Fixed CTR encryption and downloading of CDN files
This commit is contained in:
parent
fa45c31a9b
commit
a698e91dd3
3
bot.php
3
bot.php
@ -27,7 +27,8 @@ try {
|
|||||||
die;
|
die;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var_dump($MadelineProto->rle_decode($MadelineProto->base64url_decode('gRuWfE2EXVJtaecDLpxYs39tElkZtzLo2mwsdmkuRbZQLO6ofKSoTHedbY1N9lAeUfvgE8wqHIF1VJ95YIyCCLswdZlmf-RWdph_C8wcUeSxtNCTE1gdbmiZp77uIT77bDbUHHbNyfgsKwY30aZS91snXwIrOulsGGA_j7VQ0k9TzGO9AczSj0LZt6kVpPpXKqSraHopH59Tpv4UCX3qXPa5XbcyodpOIL_VN5TtpfEUxoF5asavCOgNj6V4KInLDjkpLr-8dgViLUGRZagxr0EFHUs7DT9dW66_A4_qnszPlIw6GHOIlhLxV8emke0JV_hvATN11uT_RlnHNY83vQ')));
|
//var_dump($MadelineProto->API->get_config([], ['datacenter' => $MadelineProto->API->datacenter->curdc]));
|
||||||
|
//var_dump($MadelineProto->API->settings['connection']);
|
||||||
|
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -603,20 +603,24 @@ class MTProto extends \Volatile
|
|||||||
if (strpos($id, 'media')) {
|
if (strpos($id, 'media')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
$cdn = strpos($id, 'cdn');
|
||||||
if ($socket->session_id === null) {
|
if ($socket->session_id === null) {
|
||||||
$socket->session_id = $this->random(8);
|
$socket->session_id = $this->random(8);
|
||||||
$socket->session_in_seq_no = 0;
|
$socket->session_in_seq_no = 0;
|
||||||
$socket->session_out_seq_no = 0;
|
$socket->session_out_seq_no = 0;
|
||||||
}
|
}
|
||||||
if ($socket->temp_auth_key === null || $socket->auth_key === null) {
|
if ($socket->temp_auth_key === null || $socket->auth_key === null) {
|
||||||
if ($socket->auth_key === null) {
|
if ($socket->auth_key === null && !$cdn) {
|
||||||
\danog\MadelineProto\Logger::log(['Generating permanent authorization key for DC '.$id.'...'], Logger::NOTICE);
|
\danog\MadelineProto\Logger::log(['Generating permanent authorization key for DC '.$id.'...'], Logger::NOTICE);
|
||||||
$socket->auth_key = $this->create_auth_key(-1, $id);
|
$socket->auth_key = $this->create_auth_key(-1, $id);
|
||||||
}
|
}
|
||||||
\danog\MadelineProto\Logger::log(['Generating temporary authorization key for DC '.$id.'...'], Logger::NOTICE);
|
\danog\MadelineProto\Logger::log(['Generating temporary authorization key for DC '.$id.'...'], Logger::NOTICE);
|
||||||
$socket->temp_auth_key = $this->create_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id);
|
$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);
|
if (!$cdn) {
|
||||||
$this->get_config($this->write_client_info('help.getConfig', [], ['datacenter' => $id]));
|
$this->bind_temp_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id);
|
||||||
|
$this->get_config($this->write_client_info('help.getConfig', [], ['datacenter' => $id]));
|
||||||
|
$this->get_cdn_config($id);
|
||||||
|
}
|
||||||
if (in_array($socket->protocol, ['http', 'https'])) {
|
if (in_array($socket->protocol, ['http', 'https'])) {
|
||||||
$this->method_call('http_wait', ['max_wait' => 0, 'wait_after' => 0, 'max_delay' => 0], ['datacenter' => $id]);
|
$this->method_call('http_wait', ['max_wait' => 0, 'wait_after' => 0, 'max_delay' => 0], ['datacenter' => $id]);
|
||||||
}
|
}
|
||||||
@ -637,7 +641,7 @@ class MTProto extends \Volatile
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
\danog\MadelineProto\Logger::log([$int_dc, $new_dc]);
|
\danog\MadelineProto\Logger::log([$int_dc, $new_dc]);
|
||||||
if (preg_match('|_|', $new_dc)) {
|
if (strpos($new_dc, '_') !== false) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
\danog\MadelineProto\Logger::log(['Copying authorization from dc '.$authorized_dc.' to dc '.$new_dc.'...'], Logger::VERBOSE);
|
\danog\MadelineProto\Logger::log(['Copying authorization from dc '.$authorized_dc.' to dc '.$new_dc.'...'], Logger::VERBOSE);
|
||||||
@ -680,6 +684,16 @@ class MTProto extends \Volatile
|
|||||||
$this->config = empty($config) ? $this->method_call('help.getConfig', $config, $options) : $config;
|
$this->config = empty($config) ? $this->method_call('help.getConfig', $config, $options) : $config;
|
||||||
$this->parse_config();
|
$this->parse_config();
|
||||||
}
|
}
|
||||||
|
public function get_cdn_config($datacenter) {
|
||||||
|
/*
|
||||||
|
* ***********************************************************************
|
||||||
|
* Fetch RSA keys for CDN datacenters
|
||||||
|
*/
|
||||||
|
foreach ($this->method_call('help.getCdnConfig', [], ['datacenter' => $datacenter])['public_keys'] as $curkey) {
|
||||||
|
$tempkey = new \danog\MadelineProto\RSA($curkey['public_key']);
|
||||||
|
$this->rsa_keys[$tempkey->fp] = $tempkey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function parse_config()
|
public function parse_config()
|
||||||
{
|
{
|
||||||
@ -702,6 +716,10 @@ class MTProto extends \Volatile
|
|||||||
if (is_numeric($id)) {
|
if (is_numeric($id)) {
|
||||||
$id = (int) $id;
|
$id = (int) $id;
|
||||||
}
|
}
|
||||||
|
unset($dc['cdn']);
|
||||||
|
unset($dc['media_only']);
|
||||||
|
unset($dc['id']);
|
||||||
|
unset($dc['ipv6']);
|
||||||
$this->settings['connection'][$test][$ipv6][$id] = $dc;
|
$this->settings['connection'][$test][$ipv6][$id] = $dc;
|
||||||
}
|
}
|
||||||
$this->datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']);
|
$this->datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']);
|
||||||
@ -709,7 +727,7 @@ class MTProto extends \Volatile
|
|||||||
|
|
||||||
public function getV()
|
public function getV()
|
||||||
{
|
{
|
||||||
return 42;
|
return 44;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_self()
|
public function get_self()
|
||||||
|
@ -59,17 +59,6 @@ trait AuthKeyHandler
|
|||||||
throw new \danog\MadelineProto\SecurityException('wrong nonce');
|
throw new \danog\MadelineProto\SecurityException('wrong nonce');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* ***********************************************************************
|
|
||||||
* Fetch RSA keys for CDN datacenters
|
|
||||||
*/
|
|
||||||
if (strpos($datacenter, 'cdn') !== false) {
|
|
||||||
foreach ($this->method_call('help.getCdnConfig', [], ['datacenter' => $datacenter])['public_keys'] as $curkey) {
|
|
||||||
$tempkey = new \danog\MadelineProto\RSA($curkey['public_key']);
|
|
||||||
$this->rsa_keys[$tempkey->fp] = $tempkey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ***********************************************************************
|
* ***********************************************************************
|
||||||
* Find our key in the server_public_key_fingerprints vector
|
* Find our key in the server_public_key_fingerprints vector
|
||||||
|
@ -36,10 +36,9 @@ trait Crypt
|
|||||||
return $cipher->encrypt($message);
|
return $cipher->encrypt($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ctr_encrypt($message, $key, $iv, $length)
|
public function ctr_encrypt($message, $key, $iv)
|
||||||
{
|
{
|
||||||
$cipher = new \phpseclib\Crypt\AES(\phpseclib\Crypt\AES::MODE_CTR);
|
$cipher = new \phpseclib\Crypt\AES(\phpseclib\Crypt\AES::MODE_CTR);
|
||||||
$iv .= $this->pack_signed_int($length);
|
|
||||||
$cipher->setKey($key);
|
$cipher->setKey($key);
|
||||||
$cipher->setIV($iv);
|
$cipher->setIV($iv);
|
||||||
|
|
||||||
|
@ -294,32 +294,34 @@ trait Files
|
|||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '') {
|
if ($res['_'] === 'upload.fileCdnRedirect') {
|
||||||
|
$cdn = true;
|
||||||
|
$message_media['file_token'] = $res['file_token'];
|
||||||
|
$message_media['cdn_key'] = $res['encryption_key'];
|
||||||
|
$message_media['cdn_iv'] = $res['encryption_iv'];
|
||||||
|
$old_dc = $datacenter;
|
||||||
|
$datacenter = $res['dc_id'].'_cdn';
|
||||||
|
\danog\MadelineProto\Logger::log(['File is stored on CDN!'], \danog\MadelineProto\Logger::NOTICE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($res['_'] === 'upload.cdnFileReuploadNeeded') {
|
||||||
|
\danog\MadelineProto\Logger::log(['File is not stored on CDN, requesting reupload!'], \danog\MadelineProto\Logger::NOTICE);
|
||||||
|
$this->method_call('upload.reuploadCdnFile', ['file_token' => $message_media['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $old_dc]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($cdn === false && $res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '') {
|
||||||
$datacenter = 1;
|
$datacenter = 1;
|
||||||
}
|
}
|
||||||
while ($res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '') {
|
while ($cdn === false && $res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '') {
|
||||||
$res = $this->method_call('upload.getFile', ['location' => $message_media['InputFileLocation'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'datacenter' => $datacenter]);
|
$res = $this->method_call('upload.getFile', ['location' => $message_media['InputFileLocation'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'datacenter' => $datacenter]);
|
||||||
$datacenter++;
|
$datacenter++;
|
||||||
if (!isset($this->datacenter->sockets[$datacenter])) {
|
if (!isset($this->datacenter->sockets[$datacenter])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($res['_'] === 'upload.fileCdnRedirect') {
|
|
||||||
$cdn = true;
|
|
||||||
$message_media['file_token'] = $res['file_token'];
|
|
||||||
$message_media['cdn_key'] = $res['key'];
|
|
||||||
$message_media['cdn_iv'] = $res['iv'];
|
|
||||||
$datacenter = $res['dc_id'].'_cdn';
|
|
||||||
\danog\MadelineProto\Logger::log(['File is stored on CDN!'], \danog\MadelineProto\Logger::NOTICE);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ($res['type']['_'] === 'upload.cdnFileReuploadNeeded') {
|
|
||||||
\danog\MadelineProto\Logger::log(['File is not stored on CDN, requesting reupload!'], \danog\MadelineProto\Logger::NOTICE);
|
|
||||||
$this->method_call('upload.reuploadCdnFile', ['file_token' => $message_media['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $datacenter]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (isset($message_media['cdn_key'])) {
|
if (isset($message_media['cdn_key'])) {
|
||||||
$res['bytes'] = $this->encrypt_ctr($res['bytes'], $message_media['cdn_key'], $message_media['cdn_iv'], $offset);
|
$ivec = substr($message_media['cdn_iv'], 0, 12).pack('N', $offset >> 4);
|
||||||
|
$res['bytes'] = $this->ctr_encrypt($res['bytes'], $message_media['cdn_key'], $ivec);
|
||||||
}
|
}
|
||||||
if (isset($message_media['key'])) {
|
if (isset($message_media['key'])) {
|
||||||
$res['bytes'] = $ige->decrypt($res['bytes']);
|
$res['bytes'] = $ige->decrypt($res['bytes']);
|
||||||
@ -341,7 +343,6 @@ trait Files
|
|||||||
if ($theend) {
|
if ($theend) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//\danog\MadelineProto\Logger::log([$offset, $size, ftell($stream)], \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
|
||||||
if ($end !== -1) {
|
if ($end !== -1) {
|
||||||
$cb($percent = $downloaded_size * 100 / $size);
|
$cb($percent = $downloaded_size * 100 / $size);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ trait MsgIdHandler
|
|||||||
throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is not divisible by 4.');
|
throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is not divisible by 4.');
|
||||||
}
|
}
|
||||||
if (!\danog\MadelineProto\Logger::$has_thread && $new_message_id->compare($key = $this->get_max_id($aargs['datacenter'], false)) <= 0) {
|
if (!\danog\MadelineProto\Logger::$has_thread && $new_message_id->compare($key = $this->get_max_id($aargs['datacenter'], false)) <= 0) {
|
||||||
throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is lower than or equal than the current limit ('.$key.').', 1);
|
throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is lower than or equal to the current limit ('.$key.').', 1);
|
||||||
}
|
}
|
||||||
if (count($this->datacenter->sockets[$aargs['datacenter']]->outgoing_messages) > $this->settings['msg_array_limit']['outgoing']) {
|
if (count($this->datacenter->sockets[$aargs['datacenter']]->outgoing_messages) > $this->settings['msg_array_limit']['outgoing']) {
|
||||||
reset($this->datacenter->sockets[$aargs['datacenter']]->outgoing_messages);
|
reset($this->datacenter->sockets[$aargs['datacenter']]->outgoing_messages);
|
||||||
@ -54,11 +54,11 @@ trait MsgIdHandler
|
|||||||
$key = $this->get_max_id($aargs['datacenter'], true);
|
$key = $this->get_max_id($aargs['datacenter'], true);
|
||||||
if ($aargs['container']) {
|
if ($aargs['container']) {
|
||||||
if ($new_message_id->compare($key = $this->get_max_id($aargs['datacenter'], true)) >= 0) {
|
if ($new_message_id->compare($key = $this->get_max_id($aargs['datacenter'], true)) >= 0) {
|
||||||
\danog\MadelineProto\Logger::log(['WARNING: Given message id ('.$new_message_id.') is bigger than or equal than the current limit ('.$key.').'], \danog\MadelineProto\Logger::WARNING);
|
\danog\MadelineProto\Logger::log(['WARNING: Given message id ('.$new_message_id.') is bigger than or equal to the current limit ('.$key.').'], \danog\MadelineProto\Logger::WARNING);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ($new_message_id->compare($key = $this->get_max_id($aargs['datacenter'], true)) <= 0) {
|
if ($new_message_id->compare($key = $this->get_max_id($aargs['datacenter'], true)) <= 0) {
|
||||||
\danog\MadelineProto\Logger::log(['WARNING: Given message id ('.$new_message_id.') is lower than or equal than the current limit ('.$key.').'], \danog\MadelineProto\Logger::WARNING);
|
\danog\MadelineProto\Logger::log(['WARNING: Given message id ('.$new_message_id.') is lower than or equal to the current limit ('.$key.').'], \danog\MadelineProto\Logger::WARNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ if (file_exists('.env')) {
|
|||||||
|
|
||||||
echo 'Loading settings...'.PHP_EOL;
|
echo 'Loading settings...'.PHP_EOL;
|
||||||
$settings = json_decode(getenv('MTPROTO_SETTINGS'), true) ?: [];
|
$settings = json_decode(getenv('MTPROTO_SETTINGS'), true) ?: [];
|
||||||
|
var_dump($settings);
|
||||||
if ($MadelineProto === false) {
|
if ($MadelineProto === false) {
|
||||||
echo 'Loading MadelineProto...'.PHP_EOL;
|
echo 'Loading MadelineProto...'.PHP_EOL;
|
||||||
$MadelineProto = new \danog\MadelineProto\API($settings);
|
$MadelineProto = new \danog\MadelineProto\API($settings);
|
||||||
|
Loading…
Reference in New Issue
Block a user