Skip to content

Commit

Permalink
Working skins and online authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
shoghicp committed Jun 25, 2014
1 parent a0ebb08 commit 7001c2a
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 81 deletions.
3 changes: 2 additions & 1 deletion resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ online-mode-simpleauth: false
#kickpc: kicks the PC player
#kickold: kicks the player that was on the server
#kicknew: kicks the player that is connecting
action-on-conflict: kickpe
#none: do nothing, leave it up to PocketMine-MP and other plugins
action-on-conflict: none
93 changes: 48 additions & 45 deletions src/phpseclib/Crypt/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ function __construct($mode = CRYPT_MODE_CBC)
$const_crypt_mode = 'CRYPT_' . $this->const_namespace . '_MODE';

// Determining the availibility of mcrypt support for the cipher

if (!defined($const_crypt_mode)) {
switch (true) {
case extension_loaded('mcrypt') && in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()):
Expand Down Expand Up @@ -639,14 +640,15 @@ function encrypt($plaintext)
$this->changed = false;
}
if ($this->enchanged) {

mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
$this->enchanged = false;
}

// re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
// using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
// rewritten CFB implementation the above outputs the same thing twice.
if ($this->mode == CRYPT_MODE_CFB && $this->continuousBuffer) {
if (false && $this->continuousBuffer) {
$block_size = $this->block_size;
$iv = &$this->encryptIV;
$pos = &$this->enbuffer['pos'];
Expand Down Expand Up @@ -770,47 +772,48 @@ function encrypt($plaintext)
}
}
break;

case CRYPT_MODE_CFB:
// cfb loosely routines inspired by openssl's:
// {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
if ($this->continuousBuffer) {
$iv = &$this->encryptIV;
$pos = &$buffer['pos'];
} else {
$iv = $this->encryptIV;
$pos = 0;
}
$len = strlen($plaintext);
$i = 0;
if ($pos) {
$orig_pos = $pos;
$max = $block_size - $pos;
if ($len >= $max) {
$i = $max;
$len-= $max;
$pos = 0;
} else {
$i = $len;
$pos+= $len;
$len = 0;
}
// ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
$ciphertext = substr($iv, $orig_pos) ^ $plaintext;
$iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
}
while ($len >= $block_size) {
$iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size);
$ciphertext.= $iv;
$len-= $block_size;
$i+= $block_size;
}
if ($len) {
$iv = $this->_encryptBlock($iv);
$block = $iv ^ substr($plaintext, $i);
$iv = substr_replace($iv, $block, 0, $len);
$ciphertext.= $block;
$pos = $len;
}
// cfb loosely routines inspired by openssl's:
// {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
if ($this->continuousBuffer) {
$iv = &$this->encryptIV;
$pos = &$buffer['pos'];
} else {
$iv = $this->encryptIV;
$pos = 0;
}
$len = strlen($plaintext);
$i = 0;
if ($pos) {
$orig_pos = $pos;
$max = $block_size - $pos;
if ($len >= $max) {
$i = $max;
$len-= $max;
$pos = 0;
} else {
$i = $len;
$pos+= $len;
$len = 0;
}
// ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
$ciphertext = substr($iv, $orig_pos) ^ $plaintext;
$iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
}
while ($len >= $block_size) {
$iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size);
$ciphertext.= $iv;
$len-= $block_size;
$i+= $block_size;
}
if ($len) {
$iv = $this->_encryptBlock($iv);
$block = $iv ^ substr($plaintext, $i);
$iv = substr_replace($iv, $block, 0, $len);
$ciphertext.= $block;
$pos = $len;
}
break;
case CRYPT_MODE_OFB:
$xor = $this->encryptIV;
Expand Down Expand Up @@ -872,7 +875,7 @@ function decrypt($ciphertext)
$this->dechanged = false;
}

if ($this->mode == CRYPT_MODE_CFB && $this->continuousBuffer) {
if (false && $this->continuousBuffer) {
$iv = &$this->decryptIV;
$pos = &$this->debuffer['pos'];
$len = strlen($ciphertext);
Expand Down Expand Up @@ -1274,7 +1277,7 @@ function _setupMcrypt()
CRYPT_MODE_CTR => 'ctr',
CRYPT_MODE_ECB => MCRYPT_MODE_ECB,
CRYPT_MODE_CBC => MCRYPT_MODE_CBC,
CRYPT_MODE_CFB => 'ncfb',
CRYPT_MODE_CFB => 'cfb',
CRYPT_MODE_OFB => MCRYPT_MODE_NOFB,
CRYPT_MODE_STREAM => MCRYPT_MODE_STREAM,
);
Expand All @@ -1285,13 +1288,13 @@ function _setupMcrypt()
// we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer()
// to workaround mcrypt's broken ncfb implementation in buffered mode
// see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
if ($this->mode == CRYPT_MODE_CFB) {
if (false) {
$this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
}

} // else should mcrypt_generic_deinit be called?
if ($this->mode == CRYPT_MODE_CFB) {
if (false) {
mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/shoghicp/BigBrother/BigBrother.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ class_exists("phpseclib\\Crypt\\AES", true);

//TODO: work on online mode
$this->onlineMode = (bool) $this->getConfig()->get("online-mode");
if($this->onlineMode and !function_exists("mcrypt_generic_init")){
$this->onlineMode = false;
$this->getLogger()->notice("no mcrypt detected, online-mode has been disabled");
}

if(Info::CURRENT_PROTOCOL === 16){
$this->translator = new Translator_16();
Expand All @@ -76,11 +80,10 @@ class_exists("phpseclib\\Crypt\\AES", true);

$this->rsa = new RSA();



$this->getServer()->getPluginManager()->registerEvents($this, $this);

if($this->onlineMode){
$this->getLogger()->info("Server is being started in the background");
$task = new GeneratePrivateKey($this->getServer()->getLogger(), $this->getServer()->getLoader());
$this->getServer()->getScheduler()->scheduleAsyncTask($task);
}else{
Expand Down
71 changes: 61 additions & 10 deletions src/shoghicp/BigBrother/DesktopPlayer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,35 @@
use pocketmine\level\Position;
use pocketmine\network\protocol\Info;
use pocketmine\network\protocol\LoginPacket;
use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\network\protocol\SetTimePacket;
use pocketmine\network\SourceInterface;
use pocketmine\Player;
use pocketmine\scheduler\CallbackTask;
use pocketmine\Server;
use pocketmine\tile\Spawnable;
use pocketmine\utils\TextFormat;
use pocketmine\utils\Utils;
use shoghicp\BigBrother\network\protocol\ChunkDataPacket;
use shoghicp\BigBrother\network\protocol\EncryptionRequestPacket;
use shoghicp\BigBrother\network\protocol\EncryptionResponsePacket;
use shoghicp\BigBrother\network\protocol\EntityTeleportPacket;
use shoghicp\BigBrother\network\protocol\KeepAlivePacket;
use shoghicp\BigBrother\network\protocol\LoginDisconnectPacket;
use shoghicp\BigBrother\network\protocol\LoginStartPacket;
use shoghicp\BigBrother\network\protocol\LoginSuccessPacket;
use shoghicp\BigBrother\network\protocol\PlayDisconnectPacket;
use shoghicp\BigBrother\network\protocol\SpawnPlayerPacket;
use shoghicp\BigBrother\network\ProtocolInterface;
use shoghicp\BigBrother\tasks\AuthenticateOnline;
use shoghicp\BigBrother\utils\Binary;

class DesktopPlayer extends Player{

private $bigBrother_status = 0; //0 = log in, 1 = playing
private $bigBrother_uuid;
private $bigBrother_formatedUUID;
protected $bigBrother_uuid;
protected $bigBrother_formatedUUID;
protected $bigBrother_properties = [];
private $bigBrother_checkToken;
private $bigBrother_secret;
private $bigBrother_username;
Expand Down Expand Up @@ -172,7 +177,54 @@ public function sendNextChunk(){
}
}

public function bigBrother_authenticate($username, $uuid, $onlineMode){
public function spawnTo(Player $player){
if($player instanceof DesktopPlayer){
if($this !== $player and $this->spawned === true and $player->getLevel() === $this->getLevel() and $player->canSee($this)){
$this->hasSpawned[$player->getID()] = $player;
$pk = new SpawnPlayerPacket();
if($player->getRemoveFormat()){
$pk->name = TextFormat::clean($this->nameTag);
}else{
$pk->name = $this->nameTag;
}
$pk->eid = $this->getID();
$pk->uuid = $this->bigBrother_formatedUUID;
$pk->x = $this->x;
$pk->z = $this->y;
$pk->y = $this->z;
$pk->yaw = $this->yaw;
$pk->pitch = $this->pitch;
$pk->item = $this->inventory->getItemInHand()->getID();
$pk->metadata = $this->getData();
$pk->data = $this->bigBrother_properties;
$player->interface->putRawPacket($player, $pk);

$pk = new EntityTeleportPacket();
$pk->eid = $this->getID();
$pk->x = $this->x;
$pk->z = $this->y;
$pk->y = $this->z;
$pk->yaw = $this->yaw;
$pk->pitch = $this->pitch;
$player->interface->putRawPacket($player, $pk);

$pk = new SetEntityMotionPacket();
$pk->eid = $this->getID();
$pk->speedX = $this->motionX;
$pk->speedY = $this->motionY;
$pk->speedZ = $this->motionZ;
$player->dataPacket($pk);

$this->inventory->sendHeldItem($player);

$this->inventory->sendArmorContents($player);
}
}else{
parent::spawnTo($player);
}
}

public function bigBrother_authenticate($username, $uuid, $onlineModeData = null){
if($this->bigBrother_status === 0){
$this->bigBrother_uuid = $uuid;
$this->bigBrother_formatedUUID = Binary::UUIDtoString($this->bigBrother_uuid);
Expand All @@ -182,6 +234,9 @@ public function bigBrother_authenticate($username, $uuid, $onlineMode){
$pk->name = $this->username;
$this->interface->putRawPacket($this, $pk);
$this->bigBrother_status = 1;
if($onlineModeData !== null and is_array($onlineModeData)){
$this->bigBrother_properties = $onlineModeData;
}

$this->tasks[] = $this->server->getScheduler()->scheduleDelayedRepeatingTask(new CallbackTask([$this, "bigBrother_sendKeepAlive"]), 180, 2);
$this->server->getScheduler()->scheduleDelayedTask(new CallbackTask([$this, "bigBrother_authenticationCallback"], [$username]), 1);
Expand Down Expand Up @@ -220,7 +275,7 @@ public function bigBrother_handleAuthentication(BigBrother $plugin, $username, $
$pk->verifyToken = $this->bigBrother_checkToken = Utils::getRandomBytes(4, false, true, $pk->publicKey);
$this->interface->putRawPacket($this, $pk);
}else{
$this->bigBrother_authenticate($username, "00000000000040008000000000000000", false);
$this->bigBrother_authenticate($username, "00000000000040008000000000000000", null);
}
}

Expand Down Expand Up @@ -276,15 +331,11 @@ public function bigBrother_handleAuthentication(BigBrother $plugin, $username, $
public function close($message = "", $reason = "generic reason"){
if($this->bigBrother_status === 0){
$pk = new LoginDisconnectPacket();
$pk->reason = json_encode([
"text" => $reason === "" ? "You have been disconnected." : $reason
]);
$pk->reason = TextFormat::toJSON($reason === "" ? "You have been disconnected." : $reason);
$this->interface->putRawPacket($this, $pk);
}else{
$pk = new PlayDisconnectPacket();
$pk->reason = json_encode([
"text" => $reason === "" ? "You have been disconnected." : $reason
]);
$pk->reason = TextFormat::toJSON($reason === "" ? "You have been disconnected." : $reason);;
$this->interface->putRawPacket($this, $pk);
}
parent::close($message, $reason);
Expand Down
1 change: 0 additions & 1 deletion src/shoghicp/BigBrother/network/ServerThread.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ public function __construct(\ThreadedLogger $logger, \SplAutoloader $loader, $po
$this->loadPaths = array_reverse($loadPaths);
$this->shutdown = false;

$sockets = [];
if(($sockets = stream_socket_pair((strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? STREAM_PF_INET : STREAM_PF_UNIX), STREAM_SOCK_STREAM, STREAM_IPPROTO_IP)) === false){
throw new \Exception("Could not create IPC streams. Reason: ".socket_strerror(socket_last_error()));
}
Expand Down
7 changes: 3 additions & 4 deletions src/shoghicp/BigBrother/network/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
namespace shoghicp\BigBrother\network;

use phpseclib\Crypt\AES;
use pocketmine\utils\TextFormat;
use shoghicp\BigBrother\network\protocol\LoginDisconnectPacket;
use shoghicp\BigBrother\network\protocol\PingPacket;
use shoghicp\BigBrother\utils\Binary;
Expand All @@ -44,8 +45,6 @@ public function __construct(ServerManager $manager, $identifier, $socket){
$this->address = substr($addr, 0, $final);

$this->aes = new AES(CRYPT_AES_MODE_CFB);
$this->aes->setKeyLength(128);
$this->aes->disablePadding();
}

public function write($data){
Expand Down Expand Up @@ -158,11 +157,11 @@ public function process(){
$this->status = -1;
if($protocol < Info::PROTOCOL){
$packet = new LoginDisconnectPacket();
$packet->reason = "{\"text\":\"§lOutdated client!§r\\n\\nPlease use ".Info::VERSION."\"}";
$packet->reson = TextFormat::toJSON(TextFormat::BOLD . "Outdated client!".TextFormat::RESET."\n\nPlease use ".Info::VERSION);
$this->writePacket($packet);
}elseif($protocol > Info::PROTOCOL){
$packet = new LoginDisconnectPacket();
$packet->reason = "{\"text\":\"§lOutdated server!§r\\n\\nI'm using ".Info::VERSION."\"}";
$packet->reson = TextFormat::toJSON(TextFormat::BOLD . "Outdated server!".TextFormat::RESET."\n\nI'm using ".Info::VERSION);
$this->writePacket($packet);
}else{
$this->manager->openSession($this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ public function encode(){
}

public function decode(){
$this->x = $this->getDouble();
$this->y = $this->getDouble();
$this->headY = $this->getDouble();
$this->z = $this->getDouble();
$this->yaw = $this->getFloat();
$this->pitch = $this->getFloat();
$this->onGround = $this->getByte() > 0;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ public function encode(){
$this->putInt(intval($this->x * 32));
$this->putInt(intval($this->y * 32));
$this->putInt(intval($this->z * 32));
$this->putByte((int) ($this->yaw * (256 / 360)));
$this->putByte((int) ($this->pitch * (256 / 360)));
$this->putByte(($this->yaw / 360) << 8);
$this->putByte(($this->pitch / 360) << 8);
$this->putShort($this->item);
$this->put(Binary::writeMetadata($this->metadata));
}
Expand Down
Loading

0 comments on commit 7001c2a

Please sign in to comment.