Improved logging, extended the tools class instead of calling its methods statically, improved generation and checking of message ids

This commit is contained in:
Daniil Gentili 2016-10-11 17:29:47 +02:00
parent 528faf16b0
commit a540b0a4cf
13 changed files with 88 additions and 63 deletions

10
composer.lock generated
View File

@ -237,16 +237,16 @@
}, },
{ {
"name": "phpseclib/phpseclib", "name": "phpseclib/phpseclib",
"version": "2.0.3", "version": "2.0.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpseclib/phpseclib.git", "url": "https://github.com/phpseclib/phpseclib.git",
"reference": "41f85e9c2582b3f6d1b7d20395fb40c687ad5370" "reference": "ab8028c93c03cc8d9c824efa75dc94f1db2369bf"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/41f85e9c2582b3f6d1b7d20395fb40c687ad5370", "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/ab8028c93c03cc8d9c824efa75dc94f1db2369bf",
"reference": "41f85e9c2582b3f6d1b7d20395fb40c687ad5370", "reference": "ab8028c93c03cc8d9c824efa75dc94f1db2369bf",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -325,7 +325,7 @@
"x.509", "x.509",
"x509" "x509"
], ],
"time": "2016-08-18 18:49:14" "time": "2016-10-04 00:57:04"
} }
], ],
"packages-dev": [], "packages-dev": [],

View File

@ -20,7 +20,7 @@ class API extends Tools
{ {
set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']); set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
$this->session = new MTProto($params); $this->session = new MTProto($params);
$future_salts = $this->ping(3); var_dump($future_salts = $this->ping(3));
$future_salts = $this->get_future_salts(3); $future_salts = $this->get_future_salts(3);
} }

View File

@ -15,7 +15,7 @@ namespace danog\MadelineProto;
/** /**
* Manages connection to telegram servers. * Manages connection to telegram servers.
*/ */
class Connection class Connection extends Tools
{ {
public $sock = null; public $sock = null;
public $protocol = null; public $protocol = null;
@ -41,7 +41,7 @@ class Connection
if (!(get_resource_type($this->sock) == 'file' || get_resource_type($this->sock) == 'stream')) { if (!(get_resource_type($this->sock) == 'file' || get_resource_type($this->sock) == 'stream')) {
throw new Exception("Connection: couldn't connect to socket."); throw new Exception("Connection: couldn't connect to socket.");
} }
$this->write(Tools::string2bin('\xef')); $this->write($this->string2bin('\xef'));
break; break;
case 'tcp_intermediate': case 'tcp_intermediate':
$this->sock = fsockopen('tcp://'.$ip.':'.$port); $this->sock = fsockopen('tcp://'.$ip.':'.$port);
@ -49,7 +49,7 @@ class Connection
if (!(get_resource_type($this->sock) == 'file' || get_resource_type($this->sock) == 'stream')) { if (!(get_resource_type($this->sock) == 'file' || get_resource_type($this->sock) == 'stream')) {
throw new Exception("Connection: couldn't connect to socket."); throw new Exception("Connection: couldn't connect to socket.");
} }
$this->write(Tools::string2bin('\xee\xee\xee\xee')); $this->write($this->string2bin('\xee\xee\xee\xee'));
break; break;
case 'tcp_full': case 'tcp_full':
$this->sock = fsockopen('tcp://'.$ip.':'.$port); $this->sock = fsockopen('tcp://'.$ip.':'.$port);
@ -147,7 +147,7 @@ class Connection
if ($in_seq_no != $this->in_seq_no) { if ($in_seq_no != $this->in_seq_no) {
throw new Exception('Incoming seq_no mismatch'); throw new Exception('Incoming seq_no mismatch');
} }
$payload = Tools::fopen_and_write('php://memory', 'rw+b', substr($packet, 4, $packet_length - 12)); $payload = $this->fopen_and_write('php://memory', 'rw+b', substr($packet, 4, $packet_length - 12));
break; break;
case 'tcp_intermediate': case 'tcp_intermediate':
$packet_length_data = $this->sock->read(4); $packet_length_data = $this->sock->read(4);
@ -156,7 +156,7 @@ class Connection
} }
$packet_length = $this->struct->unpack('<I', $packet_length_data)[0]; $packet_length = $this->struct->unpack('<I', $packet_length_data)[0];
$packet = $this->sock->read($packet_length); $packet = $this->sock->read($packet_length);
$payload = Tools::fopen_and_write('php://memory', 'rw+b', $packet); $payload = $this->fopen_and_write('php://memory', 'rw+b', $packet);
break; break;
case 'tcp_abridged': case 'tcp_abridged':
$packet_length_data = $this->sock->read(1); $packet_length_data = $this->sock->read(1);
@ -171,7 +171,7 @@ class Connection
$packet_length = $this->struct->unpack('<I', $packet_length_data.pack('x'))[0] << 2; $packet_length = $this->struct->unpack('<I', $packet_length_data.pack('x'))[0] << 2;
} }
$packet = $this->sock->read($packet_length); $packet = $this->sock->read($packet_length);
$payload = Tools::fopen_and_write('php://memory', 'rw+b', $packet); $payload = $this->fopen_and_write('php://memory', 'rw+b', $packet);
break; break;
} }

View File

@ -64,6 +64,7 @@ class Logging
if (!is_string($param)) { if (!is_string($param)) {
$param = var_export($param, true); $param = var_export($param, true);
} }
$param = basename(debug_backtrace()[0]["file"], '.php').': '.$param;
switch ($mode) { switch ($mode) {
case '1': case '1':
error_log($param); error_log($param);

View File

@ -111,8 +111,6 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
$this->key = new RSA($settings['authorization']['rsa_key']); $this->key = new RSA($settings['authorization']['rsa_key']);
// Istantiate struct class // Istantiate struct class
$this->struct = new \danog\PHP\StructTools(); $this->struct = new \danog\PHP\StructTools();
// Istantiate prime class
$this->PrimeModule = new PrimeModule();
// Istantiate TL class // Istantiate TL class
$this->tl = new TL\TL($this->settings['tl_schema']['src']); $this->tl = new TL\TL($this->settings['tl_schema']['src']);
// Istantiate logging class // Istantiate logging class

View File

@ -15,7 +15,7 @@ namespace danog\MadelineProto\MTProtoTools;
/** /**
* Manages acknowledgement of messages. * Manages acknowledgement of messages.
*/ */
class AckHandler extends \danog\MadelineProto\Tools class AckHandler extends \danog\MadelineProto\PrimeModule
{ {
public function ack_outgoing_message_id($message_id) public function ack_outgoing_message_id($message_id)
{ {
@ -28,7 +28,7 @@ class AckHandler extends \danog\MadelineProto\Tools
public function ack_incoming_message_id($message_id) public function ack_incoming_message_id($message_id)
{ {
if ($this->settings['authorization']['temp_auth_key']['id'] === null || $this->settings['authorization']['temp_auth_key']['id'] == \danog\MadelineProto\Tools::string2bin('\x00\x00\x00\x00\x00\x00\x00\x00')) { if ($this->settings['authorization']['temp_auth_key']['id'] === null || $this->settings['authorization']['temp_auth_key']['id'] == $this->string2bin('\x00\x00\x00\x00\x00\x00\x00\x00')) {
return; return;
} }
// I let the server know that I received its message // I let the server know that I received its message

View File

@ -23,7 +23,7 @@ class AuthKeyHandler extends AckHandler
public function create_auth_key($expires_in = -1) public function create_auth_key($expires_in = -1)
{ {
foreach ($this->range(0, $this->settings['max_tries']['authorization']) as $retry_id_total) { foreach ($this->range(0, $this->settings['max_tries']['authorization']) as $retry_id_total) {
$this->log->log('Handshake: Requesting pq'); $this->log->log('Requesting pq');
/** /**
* *********************************************************************** * ***********************************************************************
@ -54,7 +54,7 @@ class AuthKeyHandler extends AckHandler
* Check if the client's nonce and the server's nonce are the same * Check if the client's nonce and the server's nonce are the same
*/ */
if ($ResPQ['nonce'] !== $nonce) { if ($ResPQ['nonce'] !== $nonce) {
throw new Exception('Handshake: wrong nonce'); throw new Exception('wrong nonce');
} }
/* /*
@ -71,7 +71,7 @@ class AuthKeyHandler extends AckHandler
} }
if (!isset($public_key_fingerprint)) { if (!isset($public_key_fingerprint)) {
throw new Exception("Handshake: couldn't find our key in the server_public_key_fingerprints vector."); throw new Exception("couldn't find our key in the server_public_key_fingerprints vector.");
} }
$pq_bytes = $ResPQ['pq']; $pq_bytes = $ResPQ['pq'];
@ -82,7 +82,7 @@ class AuthKeyHandler extends AckHandler
* Compute p and q * Compute p and q
*/ */
$pq = new \phpseclib\Math\BigInteger($pq_bytes, 256); $pq = new \phpseclib\Math\BigInteger($pq_bytes, 256);
list($p, $q) = $this->PrimeModule->primefactors($pq); list($p, $q) = $this->PrimeFactors($pq);
$p = new \phpseclib\Math\BigInteger($p); $p = new \phpseclib\Math\BigInteger($p);
$q = new \phpseclib\Math\BigInteger($q); $q = new \phpseclib\Math\BigInteger($q);
@ -91,10 +91,10 @@ class AuthKeyHandler extends AckHandler
} }
if (!($pq->equals($p->multiply($q)) && $p->compare($q) < 0)) { if (!($pq->equals($p->multiply($q)) && $p->compare($q) < 0)) {
throw new Exception("Handshake: couldn't compute p and q."); throw new Exception("couldn't compute p and q.");
} }
$this->log->log('Handshake: Factorization '.$pq.' = '.$p.' * '.$q); $this->log->log('Factorization '.$pq.' = '.$p.' * '.$q);
/* /*
* *********************************************************************** * ***********************************************************************
@ -138,7 +138,7 @@ class AuthKeyHandler extends AckHandler
$to_encrypt = $sha_digest.$data.$random_bytes; $to_encrypt = $sha_digest.$data.$random_bytes;
$encrypted_data = $this->key->encrypt($to_encrypt); $encrypted_data = $this->key->encrypt($to_encrypt);
$this->log->log('Handshake: Starting Diffie Hellman key exchange'); $this->log->log('Starting Diffie Hellman key exchange');
/* /*
* *********************************************************************** * ***********************************************************************
* Starting Diffie Hellman key exchange, Server authentication * Starting Diffie Hellman key exchange, Server authentication
@ -175,7 +175,7 @@ class AuthKeyHandler extends AckHandler
* Check if the client's nonce and the server's nonce are the same * Check if the client's nonce and the server's nonce are the same
*/ */
if ($nonce != $server_dh_params['nonce']) { if ($nonce != $server_dh_params['nonce']) {
throw new Exception('Handshake: wrong nonce.'); throw new Exception('wrong nonce.');
} }
/* /*
@ -183,7 +183,7 @@ class AuthKeyHandler extends AckHandler
* Check if server_nonce and new server_nonce are the same * Check if server_nonce and new server_nonce are the same
*/ */
if ($server_nonce != $server_dh_params['server_nonce']) { if ($server_nonce != $server_dh_params['server_nonce']) {
throw new Exception('Handshake: wrong server nonce.'); throw new Exception('wrong server nonce.');
} }
/* /*
@ -192,7 +192,7 @@ class AuthKeyHandler extends AckHandler
* new nonce hash return in server_DH_params_fail * new nonce hash return in server_DH_params_fail
*/ */
if (isset($server_dh_params['new_nonce_hash']) && substr(sha1($new_nonce), -32) != $server_dh_params['new_nonce_hash']) { if (isset($server_dh_params['new_nonce_hash']) && substr(sha1($new_nonce), -32) != $server_dh_params['new_nonce_hash']) {
throw new Exception('Handshake: wrong new nonce hash.'); throw new Exception('wrong new nonce hash.');
} }
/* /*
@ -232,15 +232,15 @@ class AuthKeyHandler extends AckHandler
*/ */
$server_DH_inner_data_length = $this->tl->get_length($this->fopen_and_write('php://memory', 'rw+b', $answer)); $server_DH_inner_data_length = $this->tl->get_length($this->fopen_and_write('php://memory', 'rw+b', $answer));
if (sha1(substr($answer, 0, $server_DH_inner_data_length), true) != $answer_hash) { if (sha1(substr($answer, 0, $server_DH_inner_data_length), true) != $answer_hash) {
throw new Exception('Handshake: answer_hash mismatch.'); throw new Exception('answer_hash mismatch.');
} }
if ($nonce != $server_DH_inner_data['nonce']) { if ($nonce != $server_DH_inner_data['nonce']) {
throw new Exception('Handshake: wrong nonce'); throw new Exception('wrong nonce');
} }
if ($server_nonce != $server_DH_inner_data['server_nonce']) { if ($server_nonce != $server_DH_inner_data['server_nonce']) {
throw new Exception('Handshake: wrong server nonce'); throw new Exception('wrong server nonce');
} }
$g = new \phpseclib\Math\BigInteger($server_DH_inner_data['g']); $g = new \phpseclib\Math\BigInteger($server_DH_inner_data['g']);
@ -254,13 +254,14 @@ class AuthKeyHandler extends AckHandler
$server_time = $server_DH_inner_data['server_time']; $server_time = $server_DH_inner_data['server_time'];
$this->timedelta = $server_time - time(); $this->timedelta = $server_time - time();
$this->log->log(sprintf('Handshake: Server-client time delta = %.1f s', $this->timedelta)); $this->log->log(sprintf('Server-client time delta = %.1f s', $this->timedelta));
/* /*
* *********************************************************************** * ***********************************************************************
* Define some needed numbers for BigInteger * Define some needed numbers for BigInteger
*/ */
$this->log->log('Executing dh_prime checks...');
$one = new \phpseclib\Math\BigInteger(1); $one = new \phpseclib\Math\BigInteger(1);
$two = new \phpseclib\Math\BigInteger(2); $two = new \phpseclib\Math\BigInteger(2);
$twoe2047 = new \phpseclib\Math\BigInteger('16158503035655503650357438344334975980222051334857742016065172713762327569433945446598600705761456731844358980460949009747059779575245460547544076193224141560315438683650498045875098875194826053398028819192033784138396109321309878080919047169238085235290822926018152521443787945770532904303776199561965192760957166694834171210342487393282284747428088017663161029038902829665513096354230157075129296432088558362971801859230928678799175576150822952201848806616643615613562842355410104862578550863465661734839271290328348967522998634176499319107762583194718667771801067716614802322659239302476074096777926805529798115328'); $twoe2047 = new \phpseclib\Math\BigInteger('16158503035655503650357438344334975980222051334857742016065172713762327569433945446598600705761456731844358980460949009747059779575245460547544076193224141560315438683650498045875098875194826053398028819192033784138396109321309878080919047169238085235290822926018152521443787945770532904303776199561965192760957166694834171210342487393282284747428088017663161029038902829665513096354230157075129296432088558362971801859230928678799175576150822952201848806616643615613562842355410104862578550863465661734839271290328348967522998634176499319107762583194718667771801067716614802322659239302476074096777926805529798115328');
@ -272,20 +273,20 @@ class AuthKeyHandler extends AckHandler
* 2^2047 < dh_prime < 2^2048 * 2^2047 < dh_prime < 2^2048
*/ */
if (!$dh_prime->isPrime()) { if (!$dh_prime->isPrime()) {
throw new Exception("Handshake: dh_prime isn't a safe 2048-bit prime (dh_prime isn't a prime)."); throw new Exception("dh_prime isn't a safe 2048-bit prime (dh_prime isn't a prime).");
} }
/* /*
// Almost always fails // Almost always fails
if (!$dh_prime->subtract($one)->divide($two)[0]->isPrime()) { if (!$dh_prime->subtract($one)->divide($two)[0]->isPrime()) {
throw new Exception("Handshake: dh_prime isn't a safe 2048-bit prime ((dh_prime - 1) / 2 isn't a prime)."); throw new Exception("dh_prime isn't a safe 2048-bit prime ((dh_prime - 1) / 2 isn't a prime).");
} }
*/ */
if ($dh_prime->compare($twoe2047) <= 0 // 2^2047 < dh_prime or dh_prime > 2^2047 or ! dh_prime <= 2^2047 if ($dh_prime->compare($twoe2047) <= 0 // 2^2047 < dh_prime or dh_prime > 2^2047 or ! dh_prime <= 2^2047
|| $dh_prime->compare($twoe2048) >= 0 // dh_prime < 2^2048 or ! dh_prime >= 2^2048 || $dh_prime->compare($twoe2048) >= 0 // dh_prime < 2^2048 or ! dh_prime >= 2^2048
) { ) {
throw new Exception("Handshake: g isn't a safe 2048-bit prime (2^2047 < dh_prime < 2^2048 is false)."); throw new Exception("g isn't a safe 2048-bit prime (2^2047 < dh_prime < 2^2048 is false).");
} }
/* /*
@ -296,7 +297,7 @@ class AuthKeyHandler extends AckHandler
if ($g->compare($one) <= 0 // 1 < g or g > 1 or ! g <= 1 if ($g->compare($one) <= 0 // 1 < g or g > 1 or ! g <= 1
|| $g->compare($dh_prime->subtract($one)) >= 0 // g < dh_prime - 1 or ! g >= dh_prime - 1 || $g->compare($dh_prime->subtract($one)) >= 0 // g < dh_prime - 1 or ! g >= dh_prime - 1
) { ) {
throw new Exception('Handshake: g is invalid (1 < g < dh_prime - 1 is false).'); throw new Exception('g is invalid (1 < g < dh_prime - 1 is false).');
} }
/* /*
@ -307,7 +308,7 @@ class AuthKeyHandler extends AckHandler
if ($g_a->compare($one) <= 0 // 1 < g_a or g_a > 1 or ! g_a <= 1 if ($g_a->compare($one) <= 0 // 1 < g_a or g_a > 1 or ! g_a <= 1
|| $g_a->compare($dh_prime->subtract($one)) >= 0 // g_a < dh_prime - 1 or ! g_a >= dh_prime - 1 || $g_a->compare($dh_prime->subtract($one)) >= 0 // g_a < dh_prime - 1 or ! g_a >= dh_prime - 1
) { ) {
throw new Exception('Handshake: g_a is invalid (1 < g_a < dh_prime - 1 is false).'); throw new Exception('g_a is invalid (1 < g_a < dh_prime - 1 is false).');
} }
foreach ($this->range(0, $this->settings['max_tries']['authorization']) as $retry_id) { foreach ($this->range(0, $this->settings['max_tries']['authorization']) as $retry_id) {
@ -322,7 +323,7 @@ class AuthKeyHandler extends AckHandler
if ($g_b->compare($one) <= 0 // 1 < g_b or g_b > 1 or ! g_b <= 1 if ($g_b->compare($one) <= 0 // 1 < g_b or g_b > 1 or ! g_b <= 1
|| $g_b->compare($dh_prime->subtract($one)) >= 0 // g_b < dh_prime - 1 or ! g_b >= dh_prime - 1 || $g_b->compare($dh_prime->subtract($one)) >= 0 // g_b < dh_prime - 1 or ! g_b >= dh_prime - 1
) { ) {
throw new Exception('Handshake: g_b is invalid (1 < g_b < dh_prime - 1 is false).'); throw new Exception('g_b is invalid (1 < g_b < dh_prime - 1 is false).');
} }
$g_b_str = $g_b->toBytes(); $g_b_str = $g_b->toBytes();
@ -398,7 +399,7 @@ class AuthKeyHandler extends AckHandler
* Check if the client's nonce and the server's nonce are the same * Check if the client's nonce and the server's nonce are the same
*/ */
if ($Set_client_DH_params_answer['nonce'] != $nonce) { if ($Set_client_DH_params_answer['nonce'] != $nonce) {
throw new Exception('Handshake: wrong nonce.'); throw new Exception('wrong nonce.');
} }
/* /*
@ -406,7 +407,7 @@ class AuthKeyHandler extends AckHandler
* Check if server_nonce and new server_nonce are the same * Check if server_nonce and new server_nonce are the same
*/ */
if ($Set_client_DH_params_answer['server_nonce'] != $server_nonce) { if ($Set_client_DH_params_answer['server_nonce'] != $server_nonce) {
throw new Exception('Handshake: wrong server nonce'); throw new Exception('wrong server nonce');
} }
/* /*
@ -416,10 +417,10 @@ class AuthKeyHandler extends AckHandler
switch ($Set_client_DH_params_answer['_']) { switch ($Set_client_DH_params_answer['_']) {
case 'dh_gen_ok': case 'dh_gen_ok':
if ($Set_client_DH_params_answer['new_nonce_hash1'] != $new_nonce_hash1) { if ($Set_client_DH_params_answer['new_nonce_hash1'] != $new_nonce_hash1) {
throw new Exception('Handshake: wrong new_nonce_hash1'); throw new Exception('wrong new_nonce_hash1');
} }
$this->log->log('Handshake: Diffie Hellman key exchange processed successfully'); $this->log->log('Diffie Hellman key exchange processed successfully');
$res_authorization['server_salt'] = $this->struct->unpack('<q', substr($new_nonce, 0, 8 - 0) ^ substr($server_nonce, 0, 8 - 0))[0]; $res_authorization['server_salt'] = $this->struct->unpack('<q', substr($new_nonce, 0, 8 - 0) ^ substr($server_nonce, 0, 8 - 0))[0];
$res_authorization['auth_key'] = $auth_key_str; $res_authorization['auth_key'] = $auth_key_str;
@ -429,24 +430,24 @@ class AuthKeyHandler extends AckHandler
$res_authorization['expires_in'] = $expires_in; $res_authorization['expires_in'] = $expires_in;
} }
$this->log->log('Handshake: Auth key generated'); $this->log->log('Auth key generated');
$this->timedelta = 0; $this->timedelta = 0;
return $res_authorization; return $res_authorization;
case 'dh_gen_retry': case 'dh_gen_retry':
if ($Set_client_DH_params_answer['new_nonce_hash2'] != $new_nonce_hash2) { if ($Set_client_DH_params_answer['new_nonce_hash2'] != $new_nonce_hash2) {
throw new Exception('Handshake: wrong new_nonce_hash_2'); throw new Exception('wrong new_nonce_hash_2');
} }
//repeat foreach //repeat foreach
$this->log->log('Handshake: Retrying Auth'); $this->log->log('Retrying Auth');
break; break;
case 'dh_gen_fail': case 'dh_gen_fail':
if ($Set_client_DH_params_answer['new_nonce_hash3'] != $new_nonce_hash3) { if ($Set_client_DH_params_answer['new_nonce_hash3'] != $new_nonce_hash3) {
throw new Exception('Handshake: wrong new_nonce_hash_3'); throw new Exception('wrong new_nonce_hash_3');
} }
$this->log->log('Handshake: Auth Failed'); $this->log->log('Auth Failed');
break 2; break 2;
default: default:
throw new Exception('Response Error'); throw new Exception('Response Error');

View File

@ -22,7 +22,7 @@ class CallHandler extends AuthKeyHandler
$response = null; $response = null;
$count = 0; $count = 0;
while ($response == null && $count++ < $this->settings['max_tries']['response']) { while ($response == null && $count++ < $this->settings['max_tries']['response']) {
$this->log->log('Getting response ('.$count.')...'); $this->log->log('Getting response (try number '.$count.' for '.$last_sent.')...');
$last_received = $this->recv_message(); $last_received = $this->recv_message();
$this->handle_message($last_sent, $last_received); $this->handle_message($last_sent, $last_received);
if (isset($this->outgoing_messages[$last_sent]['response']) && isset($this->incoming_messages[$this->outgoing_messages[$last_sent]['response']]['content'])) { if (isset($this->outgoing_messages[$last_sent]['response']) && isset($this->incoming_messages[$this->outgoing_messages[$last_sent]['response']]['content'])) {
@ -82,7 +82,7 @@ class CallHandler extends AuthKeyHandler
// if ($server_answer == null) { // if ($server_answer == null) {
// throw new Exception('An error occurred while calling object '.$object.'.'); // throw new Exception('An error occurred while calling object '.$object.'.');
// } // }
// $deserialized = $this->tl->deserialize(\danog\MadelineProto\Tools::fopen_and_write('php://memory', 'rw+b', $server_answer)); // $deserialized = $this->tl->deserialize($this->fopen_and_write('php://memory', 'rw+b', $server_answer));
// return $deserialized; // return $deserialized;
} }
throw new Exception('An error occurred while calling object '.$object.'.'); throw new Exception('An error occurred while calling object '.$object.'.');

View File

@ -65,7 +65,7 @@ class Crypt extends CallHandler
$ivp = substr($iv, 0, $blocksize); $ivp = substr($iv, 0, $blocksize);
$ivp2 = substr($iv, $blocksize); $ivp2 = substr($iv, $blocksize);
$ciphered = ''; $ciphered = '';
foreach (\danog\MadelineProto\Tools::range(0, strlen($message), $blocksize) as $i) { foreach ($this->range(0, strlen($message), $blocksize) as $i) {
$indata = substr($message, $i, $blocksize); $indata = substr($message, $i, $blocksize);
if ($operation == 'decrypt') { if ($operation == 'decrypt') {
$xored = $indata ^ $ivp2; $xored = $indata ^ $ivp2;

View File

@ -23,16 +23,15 @@ class MessageHandler extends Crypt
*/ */
public function send_message($message_data, $content_related) public function send_message($message_data, $content_related)
{ {
$int_message_id = (int) ((time() + $this->timedelta) * pow(2, 30)) * 4; $int_message_id = $this->generate_message_id();
$message_id = $this->struct->pack('<Q', $int_message_id); $message_id = $this->struct->pack('<Q', $int_message_id);
$this->check_message_id($int_message_id, true);
if (($this->settings['authorization']['temp_auth_key']['auth_key'] == null) || ($this->settings['authorization']['temp_auth_key']['server_salt'] == null)) { if (($this->settings['authorization']['temp_auth_key']['auth_key'] == null) || ($this->settings['authorization']['temp_auth_key']['server_salt'] == null)) {
$message = \danog\MadelineProto\Tools::string2bin('\x00\x00\x00\x00\x00\x00\x00\x00').$message_id.$this->struct->pack('<I', strlen($message_data)).$message_data; $message = $this->string2bin('\x00\x00\x00\x00\x00\x00\x00\x00').$message_id.$this->struct->pack('<I', strlen($message_data)).$message_data;
} else { } else {
$seq_no = $this->generate_seq_no($content_related); $seq_no = $this->generate_seq_no($content_related);
$encrypted_data = $this->struct->pack('<q', $this->settings['authorization']['temp_auth_key']['server_salt']).$this->settings['authorization']['session_id'].$message_id.$this->struct->pack('<II', $seq_no, strlen($message_data)).$message_data; $encrypted_data = $this->struct->pack('<q', $this->settings['authorization']['temp_auth_key']['server_salt']).$this->settings['authorization']['session_id'].$message_id.$this->struct->pack('<II', $seq_no, strlen($message_data)).$message_data;
$message_key = substr(sha1($encrypted_data, true), -16); $message_key = substr(sha1($encrypted_data, true), -16);
$padding = \phpseclib\Crypt\Random::string(\danog\MadelineProto\Tools::posmod(-strlen($encrypted_data), 16)); $padding = \phpseclib\Crypt\Random::string($this->posmod(-strlen($encrypted_data), 16));
list($aes_key, $aes_iv) = $this->aes_calculate($message_key); list($aes_key, $aes_iv) = $this->aes_calculate($message_key);
$message = $this->settings['authorization']['temp_auth_key']['id'].$message_key.$this->ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv); $message = $this->settings['authorization']['temp_auth_key']['id'].$message_key.$this->ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv);
$this->outgoing_messages[$int_message_id]['seq_no'] = $seq_no; $this->outgoing_messages[$int_message_id]['seq_no'] = $seq_no;
@ -52,7 +51,7 @@ class MessageHandler extends Crypt
throw new Exception('Server response error: '.abs($this->struct->unpack('<i', fread($payload, 4))[0])); throw new Exception('Server response error: '.abs($this->struct->unpack('<i', fread($payload, 4))[0]));
} }
$auth_key_id = fread($payload, 8); $auth_key_id = fread($payload, 8);
if ($auth_key_id == \danog\MadelineProto\Tools::string2bin('\x00\x00\x00\x00\x00\x00\x00\x00')) { if ($auth_key_id == $this->string2bin('\x00\x00\x00\x00\x00\x00\x00\x00')) {
list($message_id, $message_length) = $this->struct->unpack('<QI', fread($payload, 12)); list($message_id, $message_length) = $this->struct->unpack('<QI', fread($payload, 12));
$this->check_message_id($message_id, false); $this->check_message_id($message_id, false);
$message_data = fread($payload, $message_length); $message_data = fread($payload, $message_length);
@ -104,7 +103,7 @@ class MessageHandler extends Crypt
} else { } else {
throw new Exception('Got unknown auth_key id'); throw new Exception('Got unknown auth_key id');
} }
$deserialized = $this->tl->deserialize(\danog\MadelineProto\Tools::fopen_and_write('php://memory', 'rw+b', $message_data)); $deserialized = $this->tl->deserialize($this->fopen_and_write('php://memory', 'rw+b', $message_data));
$this->incoming_messages[$message_id]['content'] = $deserialized; $this->incoming_messages[$message_id]['content'] = $deserialized;
return $message_id; return $message_id;

View File

@ -29,6 +29,11 @@ class MsgIdHandler extends MessageHandler
if ($new_message_id % 4 != 0) { if ($new_message_id % 4 != 0) {
throw new Exception('Given message id ('.$new_message_id.') is not divisible by 4.'); throw new Exception('Given message id ('.$new_message_id.') is not divisible by 4.');
} }
$keys = array_keys($this->outgoing_messages);
asort($keys);
if ($new_message_id <= end($keys)) {
throw new Exception('Given message id ('.$new_message_id.') is lower than or equal than the current limit ('.end($keys).').', 1);
}
$this->outgoing_messages[$new_message_id] = []; $this->outgoing_messages[$new_message_id] = [];
if (count($this->outgoing_messages) > $this->settings['msg_array_limit']['outgoing']) { if (count($this->outgoing_messages) > $this->settings['msg_array_limit']['outgoing']) {
array_shift($this->outgoing_messages); array_shift($this->outgoing_messages);
@ -58,4 +63,19 @@ class MsgIdHandler extends MessageHandler
ksort($this->incoming_messages); ksort($this->incoming_messages);
} }
} }
public function generate_message_id() {
$ms_time = (time() + $this->timedelta) * 1000;
$int_message_id = (int) (
((int)($ms_time / 1000) << 32) |
($this->posmod($ms_time, 1000) << 22) |
rand(0, 524288) << 2
);
$keys = array_keys($this->outgoing_messages);
asort($keys);
if ($int_message_id <= end($keys)) {
$int_message_id += 4;
}
$this->check_message_id($int_message_id, true);
return $int_message_id;
}
} }

View File

@ -48,6 +48,7 @@ class ResponseHandler extends MsgIdHandler
break; break;
case 'pong': case 'pong':
var_dump($this->outgoing_messages);
foreach ($this->outgoing_messages as $msg_id => &$omessage) { foreach ($this->outgoing_messages as $msg_id => &$omessage) {
if (isset($omessage['content']['args']['ping_id']) && $omessage['content']['args']['ping_id'] == $response['ping_id']) { if (isset($omessage['content']['args']['ping_id']) && $omessage['content']['args']['ping_id'] == $response['ping_id']) {
$omessage['response'] = $response['msg_id']; $omessage['response'] = $response['msg_id'];

View File

@ -76,16 +76,11 @@ class PrimeModule extends Tools
return ($b == 0) ? $a : $b; return ($b == 0) ? $a : $b;
} }
public function primefactors($pq, $sort = false) public function PrimeFactors($pq, $sort = false)
{ {
// Use the native version
$pqstr = (string) $pq; $pqstr = (string) $pq;
$res = $this->find_small_multiplier_lopatin((int) $pqstr);
$res = [$res, $pqstr / $res]; $this->log->log("Trying to use the python factorization module");
if ($res[1] != 1) {
return $res;
}
// Use the python version.
if (function_exists('shell_exec')) { if (function_exists('shell_exec')) {
try { try {
$res = json_decode(shell_exec('python '.__DIR__.'/getpq.py '.$pqstr)); $res = json_decode(shell_exec('python '.__DIR__.'/getpq.py '.$pqstr));
@ -95,7 +90,8 @@ class PrimeModule extends Tools
} catch (Exception $e) { } catch (Exception $e) {
} }
} }
// Else do factorization with wolfram alpha :)))))
$this->log->log("Trying to use the wolfram alpha factorization module");
$query = 'Do prime factorization of '.$pqstr; $query = 'Do prime factorization of '.$pqstr;
$params = [ $params = [
'async' => true, 'async' => true,
@ -123,6 +119,15 @@ class PrimeModule extends Tools
if (count($res) == 2) { if (count($res) == 2) {
return $res; return $res;
} }
$this->log->log("Trying to use the native factorization module");
$res = $this->find_small_multiplier_lopatin((int) $pqstr);
$res = [$res, $pqstr / $res];
if ($res[1] != 1) {
return $res;
}
throw new Exception("Couldn't calculate pq!"); throw new Exception("Couldn't calculate pq!");
} }
} }