diff --git a/server.php b/server.php index d2c5da4c..db60e3b8 100644 --- a/server.php +++ b/server.php @@ -2,5 +2,5 @@ require 'vendor/autoload.php'; -$handler = new \danog\MadelineProto\Server(['type' => AF_INET, 'protocol' => 0, 'address' => 'localhost', 'port' => 8002]); +$handler = new \danog\MadelineProto\Server(['type' => AF_INET, 'protocol' => 0, 'address' => 'localhost', 'port' => 8002, 'handler' => '\danog\MadelineProto\Server\Proxy', 'extra' => ['madeline' => new \danog\MadelineProto\API(['app_info' => ['api_id' => 6, 'api_hash' => 'eb06d4abfb49dc3eeb1aeb98ae0f581e']]), 'secret' => 'pony']]); $handler->start(); diff --git a/src/danog/MadelineProto/Server.php b/src/danog/MadelineProto/Server.php index a964a9ad..3afdaa04 100644 --- a/src/danog/MadelineProto/Server.php +++ b/src/danog/MadelineProto/Server.php @@ -64,7 +64,7 @@ class Server } elseif ($pid) { return $this->pids[] = $pid; } - $handler = new \danog\MadelineProto\Server\Handler($socket, null, null, null, null, null, null); + $handler = new $this->settings['handler']($socket, $this->settings['extra'], null, null, null, null, null); $handler->loop(); die; } diff --git a/src/danog/MadelineProto/Server/Proxy.php b/src/danog/MadelineProto/Server/Proxy.php new file mode 100644 index 00000000..c572a26c --- /dev/null +++ b/src/danog/MadelineProto/Server/Proxy.php @@ -0,0 +1,85 @@ +. +*/ + +namespace danog\MadelineProto\Server; + +/* + * Socket handler for server + */ +class Handler extends \danog\MadelineProto\Connection +{ + use \danog\MadelineProto\Tools; + private $madeline; + + public function __magic_construct($socket, $extra, $ip, $port, $protocol, $timeout, $ipv6) + { + \danog\MadelineProto\Magic::$pid = getmypid(); + $this->sock = $socket; + $this->sock->setBlocking(true); + $this->must_open = false; + $timeout = 2; + $this->sock->setOption(\SOL_SOCKET, \SO_RCVTIMEO, $timeout); + $this->sock->setOption(\SOL_SOCKET, \SO_SNDTIMEO, $timeout); + $this->logger = new \danog\MadelineProto\Logger(3); + $this->extra = $extra; + } + + public function __destruct() + { + echo 'Closing socket in fork '.getmypid().PHP_EOL; + unset($this->sock); + } + + public function loop() + { + $this->protocol = 'obfuscated2'; + $random = $this->sock->read(64); + + $reversed = strrev(substr($random, 8, 48)); + if (isset($this->extra['secret'])) { + $random = substr_replace($random, hash('sha256', $key.$this->extra['secret'], true), 32, 8); + } + + $this->obfuscated = ['encryption' => new \phpseclib\Crypt\AES('ctr'), 'decryption' => new \phpseclib\Crypt\AES('ctr')]; + $this->obfuscated['encryption']->enableContinuousBuffer(); + $this->obfuscated['decryption']->enableContinuousBuffer(); + $this->obfuscated['decryption']->setKey(substr($random, 8, 32)); + $this->obfuscated['decryption']->setIV(substr($random, 40, 16)); + $this->obfuscated['encryption']->setKey(substr($reversed, 0, 32)); + $this->obfuscated['encryption']->setIV(substr($reversed, 32, 16)); + $random = substr_replace($random, substr(@$this->obfuscated['encryption']->encrypt($random), 56, 8), 56, 8); + + $random[56] = $random[57] = $random[58] = $random[59] = chr(0xef); + + if (substr($random, 56, 4) !== str_repeat(chr(0xef), 4)) { + throw new \danog\MadelineProto\Exception('Wrong protocol version'); + } + $socket = $this->extra['madeline']->API->datacenter->sockets[unpack('v', substr($random, 60, 2)[1]]; + $socket->close_and_reopen(); + + while (true) { + pcntl_signal_dispatch(); + + try { + $time = time(); + $socket->send_message($this->read_message()); + } catch (\danog\MadelineProto\NothingInTheSocketException $e) { + echo $e; + if (time() - $time < 2) { + exit(); + } + continue; + } + } + } +}