From aaa51776079e277075d35b986a0505ff1bb2da6b Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Mon, 19 Feb 2018 12:23:34 +0000 Subject: [PATCH] Fix CDN files, improve initConnection --- bot.php | 4 +-- src/danog/MadelineProto/MTProto.php | 26 ------------------- .../MTProtoTools/AuthKeyHandler.php | 14 +++++++--- .../MTProtoTools/CallHandler.php | 23 ++++++++++++++++ .../MadelineProto/MTProtoTools/Files.php | 7 ++--- 5 files changed, 39 insertions(+), 35 deletions(-) diff --git a/bot.php b/bot.php index e684be8a..abca3f1a 100755 --- a/bot.php +++ b/bot.php @@ -37,7 +37,7 @@ while (true) { case 'updateNewMessage': case 'updateNewChannelMessage': if (isset($update['update']['message']['out']) && $update['update']['message']['out']) { -// continue; + continue; } $res = json_encode($update, JSON_PRETTY_PRINT); if ($res == '') { @@ -45,7 +45,7 @@ while (true) { } try { -// $MadelineProto->messages->sendMessage(['peer' => $update['update']['_'] === 'updateNewMessage' ? $update['update']['message']['from_id'] : $update['update']['message']['to_id'], 'message' => $res, 'reply_to_msg_id' => $update['update']['message']['id'], 'entities' => [['_' => 'messageEntityPre', 'offset' => 0, 'length' => strlen($res), 'language' => 'json']]]); + $MadelineProto->messages->sendMessage(['peer' => $update['update']['_'] === 'updateNewMessage' ? $update['update']['message']['from_id'] : $update['update']['message']['to_id'], 'message' => $res, 'reply_to_msg_id' => $update['update']['message']['id'], 'entities' => [['_' => 'messageEntityPre', 'offset' => 0, 'length' => strlen($res), 'language' => 'json']]]); } catch (\danog\MadelineProto\RPCErrorException $e) { $MadelineProto->messages->sendMessage(['peer' => '@danogentili', 'message' => $e->getCode().': '.$e->getMessage().PHP_EOL.$e->getTraceAsString()]); } diff --git a/src/danog/MadelineProto/MTProto.php b/src/danog/MadelineProto/MTProto.php index 9ce79f1f..247b6b30 100644 --- a/src/danog/MadelineProto/MTProto.php +++ b/src/danog/MadelineProto/MTProto.php @@ -664,32 +664,6 @@ class MTProto $this->init_authorization(); } - public function write_client_info($method, $arguments = [], $options = []) - { - \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['write_client_info'], $method)], Logger::NOTICE); - - return $this->method_call( - 'invokeWithLayer', - [ - 'layer' => $this->settings['tl_schema']['layer'], - 'query' => $this->serialize_method('initConnection', - [ - 'api_id' => $this->settings['app_info']['api_id'], - 'api_hash' => $this->settings['app_info']['api_hash'], - 'device_model' => strpos($options['datacenter'], 'cdn') === false ? $this->settings['app_info']['device_model'] : 'n/a', - 'system_version' => strpos($options['datacenter'], 'cdn') === false ? $this->settings['app_info']['system_version'] : 'n/a', - 'app_version' => $this->settings['app_info']['app_version'], - 'system_lang_code' => $this->settings['app_info']['lang_code'], - 'lang_code' => $this->settings['app_info']['lang_code'], - 'lang_pack' => '', - 'query' => $this->serialize_method($method, $arguments), - ] - ), - ], - $options - ); - } - public function get_config($config = [], $options = []) { if ($this->config['expires'] > time()) { diff --git a/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php b/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php index d9ba6a92..5d0911d2 100644 --- a/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php @@ -593,21 +593,27 @@ trait AuthKeyHandler $socket->auth_key = $this->create_auth_key(-1, $id); $socket->authorized = false; } - \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['gen_temp_auth_key'], $id)], \danog\MadelineProto\Logger::NOTICE); if ($this->settings['connection_settings'][$dc_config_number]['pfs']) { - $socket->temp_auth_key = $this->create_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id); if (!$cdn) { + \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['gen_temp_auth_key'], $id)], \danog\MadelineProto\Logger::NOTICE); + $socket->temp_auth_key = $this->create_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id); $this->bind_temp_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id); $config = $this->method_call('help.getConfig', [], ['datacenter' => $id]); $this->sync_authorization($id); $this->get_config($config); + } else if ($socket->temp_auth_key === null) { + \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['gen_temp_auth_key'], $id)], \danog\MadelineProto\Logger::NOTICE); + $socket->temp_auth_key = $this->create_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id); } } else { - $socket->temp_auth_key = $socket->auth_key; if (!$cdn) { + $socket->temp_auth_key = $socket->auth_key; $config = $this->method_call('help.getConfig', [], ['datacenter' => $id]); $this->sync_authorization($id); $this->get_config($config); + } else if ($socket->temp_auth_key === null) { + \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['gen_temp_auth_key'], $id)], \danog\MadelineProto\Logger::NOTICE); + $socket->temp_auth_key = $this->create_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id); } } } elseif (!$cdn) { @@ -632,7 +638,7 @@ trait AuthKeyHandler if ($this->authorized_dc !== -1 && $authorized_dc_id !== $this->authorized_dc) { continue; } - if ($authorized_socket->temp_auth_key !== null && $authorized_socket->auth_key !== null && $authorized_socket->authorized === true && $this->authorized === self::LOGGED_IN && $socket->authorized === false) { + if ($authorized_socket->temp_auth_key !== null && $authorized_socket->auth_key !== null && $authorized_socket->authorized === true && $this->authorized === self::LOGGED_IN && $socket->authorized === false && strpos($authorized_dc_id, 'cdn') === false) { try { \danog\MadelineProto\Logger::log(['Trying to copy authorization from dc '.$authorized_dc_id.' to dc '.$id]); $exported_authorization = $this->method_call('auth.exportAuthorization', ['dc_id' => preg_replace('|_.*|', '', $id)], ['datacenter' => $authorized_dc_id]); diff --git a/src/danog/MadelineProto/MTProtoTools/CallHandler.php b/src/danog/MadelineProto/MTProtoTools/CallHandler.php index 2ad72c5d..f431b378 100644 --- a/src/danog/MadelineProto/MTProtoTools/CallHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/CallHandler.php @@ -71,6 +71,27 @@ trait CallHandler } else { $serialized = $this->serialize_method($method, $args); } + if ($this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key !== null && (!isset($this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['connection_inited']) || $this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['connection_inited'] === false)) { + \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['write_client_info'], $method)], \danog\MadelineProto\Logger::NOTICE); + $serialized = $this->serialize_method( + 'invokeWithLayer', + [ + 'layer' => $this->settings['tl_schema']['layer'], + 'query' => $this->serialize_method('initConnection', + [ + 'api_id' => $this->settings['app_info']['api_id'], + 'api_hash' => $this->settings['app_info']['api_hash'], + 'device_model' => strpos($aargs['datacenter'], 'cdn') === false ? $this->settings['app_info']['device_model'] : 'n/a', + 'system_version' => strpos($aargs['datacenter'], 'cdn') === false ? $this->settings['app_info']['system_version'] : 'n/a', + 'app_version' => $this->settings['app_info']['app_version'], + 'system_lang_code' => $this->settings['app_info']['lang_code'], + 'lang_code' => $this->settings['app_info']['lang_code'], + 'lang_pack' => '', + 'query' => $serialized + ] + ), + ]); + } $content_related = $this->content_related($method); @@ -250,6 +271,8 @@ trait CallHandler throw new \danog\MadelineProto\Exception('An error occurred while calling method '.$method.' ('.$last_error.').'); } \danog\MadelineProto\Logger::log(['Got response for method '.$method.' @ try '.$count.' (response try '.$res_count.')'], \danog\MadelineProto\Logger::ULTRA_VERBOSE); + if ($this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key !== null && (!isset($this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['connection_inited']) || $this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['connection_inited'] === false)) $this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key['connection_inited'] = true; + $this->datacenter->sockets[$aargs['datacenter']]->outgoing_messages[$message_id] = []; if (isset($message_chunks) && count($message_chunks)) { $server_answer = [$server_answer]; diff --git a/src/danog/MadelineProto/MTProtoTools/Files.php b/src/danog/MadelineProto/MTProtoTools/Files.php index d71eb37b..1b85dbd3 100644 --- a/src/danog/MadelineProto/MTProtoTools/Files.php +++ b/src/danog/MadelineProto/MTProtoTools/Files.php @@ -349,7 +349,7 @@ trait Files if (isset($message_media['cdn_key'])) { $ivec = substr($message_media['cdn_iv'], 0, 12).pack('N', $offset >> 4); $res['bytes'] = $this->ctr_encrypt($res['bytes'], $message_media['cdn_key'], $ivec); - $this->check_cdn_hash($message_media['file_token'], $offset, $res['bytes'], $datacenter); + $this->check_cdn_hash($message_media['file_token'], $offset, $res['bytes'], $old_dc); } if (isset($message_media['key'])) { $res['bytes'] = $ige->decrypt($res['bytes']); @@ -393,7 +393,7 @@ trait Files $this->cdn_hashes = []; } foreach ($hashes as $hash) { - $this->cdn_hashes[$file][$hash['offset']] = ['limit' => $hash['limit'], 'hash' => $hash['hash']]; + $this->cdn_hashes[$file][$hash['offset']] = ['limit' => $hash['limit'], 'hash' => (string) $hash['hash']]; } } @@ -401,11 +401,12 @@ trait Files { while (strlen($data)) { if (!isset($this->cdn_hashes[$file][$offset])) { - $this->add_cdn_hashes($this->method_call('upload.getCdnFileHashes', ['file_token' => $file, 'offset' => $offset], ['datacenter' => &$datacenter])); + $this->add_cdn_hashes($file, $this->method_call('upload.getCdnFileHashes', ['file_token' => $file, 'offset' => $offset], ['datacenter' => $datacenter])); } if (!isset($this->cdn_hashes[$file][$offset])) { throw new \danog\MadelineProto\Exception('Could not fetch CDN hashes for offset '.$offset); } + if (hash('sha256', substr($data, 0, $this->cdn_hashes[$file][$offset]['limit']), true) !== $this->cdn_hashes[$file][$offset]['hash']) { throw new \danog\MadelineProto\SecurityException('CDN hash mismatch for offset '.$offset); }