1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-30 07:18:57 +01:00

Finish refactoring

This commit is contained in:
Daniil Gentili 2023-09-19 21:10:46 +02:00
parent a01fa820c6
commit b0ab083367
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
4 changed files with 32 additions and 35 deletions

View File

@ -554,7 +554,7 @@ final class MTProto implements TLCallback, LoggerGetter
private ?string $tmpDbPrefix = null;
/** @internal */
protected function getDbPrefix(): string
public function getDbPrefix(): string
{
$prefix = $this->getSelf()['id'] ?? null;
if (!$prefix) {
@ -636,9 +636,8 @@ final class MTProto implements TLCallback, LoggerGetter
'TL',
// Secret chats
'secret_chats',
'secretChats',
'temp_requested_secret_chats',
'temp_rekeyed_secret_chats',
// Report URI
'reportDest',
@ -803,7 +802,7 @@ final class MTProto implements TLCallback, LoggerGetter
$db []= async($this->minDatabase->init(...));
$db []= async($this->peerDatabase->init(...));
$db []= async($this->initDb(...), $this);
foreach ($this->secret_chats as $chat) {
foreach ($this->secretChats as $chat) {
$db []= async($chat->init(...));
}
await($db);
@ -857,12 +856,9 @@ final class MTProto implements TLCallback, LoggerGetter
$this->config = ['expires' => -1];
$this->dh_config = ['version' => 0];
$this->initialize($this->settings);
foreach ($this->secret_chats as $chat => &$data) {
$data['chat_id'] = $chat;
foreach ($this->secretChats as $chat) {
try {
if (isset($this->secret_chats[$chat]) && $this->secret_chats[$chat]['InputEncryptedChat'] !== null) {
$this->notifyLayer($chat);
}
$chat->notifyLayer();
} catch (RPCErrorException $e) {
}
}

View File

@ -1035,12 +1035,11 @@ trait UpdateHandler
$this->logger->logger('Applying qts: '.$update['qts'].' over current qts '.$cur_state->qts().', chat id: '.$update['message']['chat_id'], Logger::VERBOSE);
$this->methodCallAsyncRead('messages.receivedQueue', ['max_qts' => $cur_state->qts($update['qts'])]);
}
if (!isset($this->secret_chats[$update['message']['chat_id']])) {
if (!isset($this->secretChats[$update['message']['chat_id']])) {
$this->logger->logger(\sprintf(Lang::$current_lang['secret_chat_skipping'], $update['message']['chat_id']));
return;
}
$this->secretFeeders[$update['message']['chat_id']]->feed($update);
$this->secretFeeders[$update['message']['chat_id']]->resume();
$this->secretChats[$update['message']['chat_id']]->feed($update);
return;
}
if ($update['_'] === 'updateEncryption') {
@ -1058,15 +1057,7 @@ trait UpdateHandler
break;
case 'encryptedChatDiscarded':
$this->logger->logger('Deleting secret chat '.$update['chat']['id'].' because it was revoked by the other user (it was probably accepted by another client)', Logger::NOTICE);
if (isset($this->secret_chats[$update['chat']['id']])) {
unset($this->secret_chats[$update['chat']['id']]);
}
if (isset($this->temp_requested_secret_chats[$update['chat']['id']])) {
unset($this->temp_requested_secret_chats[$update['chat']['id']]);
}
if (isset($this->temp_rekeyed_secret_chats[$update['chat']['id']])) {
unset($this->temp_rekeyed_secret_chats[$update['chat']['id']]);
}
$this->discardSecretChat($update['chat']['id']);
break;
case 'encryptedChat':
$this->logger->logger('Completing creation of secret chat '.$update['chat']['id'], Logger::NOTICE);

View File

@ -51,7 +51,7 @@ trait AuthKeyHandler
*
* @var array<int, SecretChatController>
*/
public array $secret_chats = [];
public array $secretChats = [];
/**
* Request secret chat.
*
@ -84,7 +84,7 @@ trait AuthKeyHandler
*/
public function acceptSecretChat(array $params): void
{
if ($this->secretChatStatus($params['id']) !== 0) {
if (isset($this->secretChats[$params['id']])) {
$this->logger->logger("I've already accepted secret chat ".$params['id']);
return;
}
@ -98,7 +98,7 @@ trait AuthKeyHandler
$key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8);
$key['visualization_orig'] = \substr(\sha1($key['auth_key'], true), 16);
$key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20);
$this->secret_chats[$params['id']] = new SecretChatController(
$this->secretChats[$params['id']] = $chat = new SecretChatController(
$this,
$key,
$params['id'],
@ -109,7 +109,7 @@ trait AuthKeyHandler
$g_b = $dh_config['g']->powMod($b, $dh_config['p']);
Crypt::checkG($g_b, $dh_config['p']);
$this->methodCallAsyncRead('messages.acceptEncryption', ['peer' => $params['id'], 'g_b' => $g_b->toBytes(), 'key_fingerprint' => $key['fingerprint']]);
$this->notifyLayer($params['id']);
$chat->notifyLayer();
$this->logger->logger('Secret chat '.$params['id'].' accepted successfully!', Logger::NOTICE);
}
/**
@ -119,7 +119,7 @@ trait AuthKeyHandler
*/
private function completeSecretChat(array $params)
{
if ($this->secretChatStatus($params['id']) !== 1) {
if (!isset($this->temp_requested_secret_chats[$params['id']])) {
//$this->logger->logger($this->secretChatStatus($params['id']));
$this->logger->logger('Could not find and complete secret chat '.$params['id']);
return false;
@ -137,14 +137,13 @@ trait AuthKeyHandler
}
$key['visualization_orig'] = \substr(\sha1($key['auth_key'], true), 16);
$key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20);
$this->secret_chats[$params['id']] = $chat = new SecretChatController(
$this->secretChats[$params['id']] = $chat = new SecretChatController(
$this,
$key,
$params['id'],
$params['access_hash'],
true,
$params['participant_id'],
\time(),
);
$chat->notifyLayer();
$this->logger->logger('Secret chat '.$params['id'].' completed successfully!', Logger::NOTICE);
@ -186,7 +185,7 @@ trait AuthKeyHandler
} elseif (DialogId::isSecretChat($chat)) {
$chat = DialogId::toSecretChatId($chat);
}
return $this->secret_chats[$chat];
return $this->secretChats[$chat];
}
/**
* Check whether secret chat exists.
@ -195,7 +194,7 @@ trait AuthKeyHandler
*/
public function hasSecretChat(array|int $chat): bool
{
return isset($this->secret_chats[\is_array($chat) ? $chat['chat_id'] : $chat]);
return isset($this->secretChats[\is_array($chat) ? $chat['chat_id'] : $chat]);
}
/**
* Discard secret chat.
@ -205,8 +204,8 @@ trait AuthKeyHandler
public function discardSecretChat(int $chat): void
{
$this->logger->logger('Discarding secret chat '.$chat.'...', Logger::VERBOSE);
if (isset($this->secret_chats[$chat])) {
unset($this->secret_chats[$chat]);
if (isset($this->secretChats[$chat])) {
unset($this->secretChats[$chat]);
}
if (isset($this->temp_requested_secret_chats[$chat])) {
unset($this->temp_requested_secret_chats[$chat]);

View File

@ -130,6 +130,11 @@ final class SecretChatController implements Stringable
$this->init();
}
public function feed(array $update): void
{
$this->feedLoop->feed($update);
$this->feedLoop->resume();
}
public function init(): void
{
$this->initDb($this->API);
@ -187,7 +192,7 @@ final class SecretChatController implements Stringable
$this->rekeyState = RekeyState::REQUESTED;
$this->rekeyExchangeId = Tools::randomInt();
$this->rekeyParam = $a;
$this->API->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $this->id, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionRequestKey', 'g_a' => $g_a->toBytes(), 'exchange_id' => $e]]]);
$this->API->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $this->id, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionRequestKey', 'g_a' => $g_a->toBytes(), 'exchange_id' => $this->rekeyExchangeId]]]);
$this->API->updaters[UpdateLoop::GENERIC]->resume();
} finally {
EventLoop::queue($lock->release(...));
@ -251,6 +256,7 @@ final class SecretChatController implements Stringable
$dh_config = ($this->API->getDhConfig());
$params['g_b'] = new BigInteger((string) $params['g_b'], 256);
Crypt::checkG($params['g_b'], $dh_config['p']);
assert($this->rekeyParam !== null);
$key = ['auth_key' => \str_pad($params['g_b']->powMod($this->rekeyParam, $dh_config['p'])->toBytes(), 256, \chr(0), STR_PAD_LEFT)];
$key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8);
$key['visualization_orig'] = $this->key['visualization_orig'];
@ -282,6 +288,7 @@ final class SecretChatController implements Stringable
if ($this->rekeyState !== RekeyState::ACCEPTED || $this->rekeyExchangeId !== $params['exchange_id']) {
return;
}
assert($this->rekeyKey !== null);
if ($this->rekeyKey['fingerprint'] !== $params['key_fingerprint']) {
$this->API->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $this->id, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAbortKey', 'exchange_id' => $params['exchange_id']]]]);
throw new SecurityException('Invalid key fingerprint!');
@ -488,7 +495,9 @@ final class SecretChatController implements Stringable
private function tryMTProtoV1Decrypt(string $message_key, bool $old, string $encrypted_data): string
{
[$aes_key, $aes_iv] = Crypt::oldKdf($message_key, ($old ? $this->oldKey : $this->key)['auth_key'], true);
$key = $old ? $this->oldKey : $this->key;
assert($key !== null);
[$aes_key, $aes_iv] = Crypt::oldKdf($message_key, $key['auth_key'], true);
$decrypted_data = Crypt::igeDecrypt($encrypted_data, $aes_key, $aes_iv);
$message_data_length = \unpack('V', \substr($decrypted_data, 0, 4))[1];
$message_data = \substr($decrypted_data, 4, $message_data_length);
@ -509,7 +518,9 @@ final class SecretChatController implements Stringable
private function tryMTProtoV2Decrypt(string $message_key, bool $old, string $encrypted_data): string
{
$key = ($old ? $this->oldKey : $this->key)['auth_key'];
$key = $old ? $this->oldKey : $this->key;
assert($key !== null);
$key = $key['auth_key'];
[$aes_key, $aes_iv] = Crypt::kdf($message_key, $key, !$this->public->creator);
$decrypted_data = Crypt::igeDecrypt($encrypted_data, $aes_key, $aes_iv);
if ($message_key != \substr(\hash('sha256', \substr($key, 88 + ($this->public->creator ? 8 : 0), 32).$decrypted_data, true), 8, 16)) {