diff --git a/td/mtproto/CryptoStorer.h b/td/mtproto/CryptoStorer.h index 08c12684..58010363 100644 --- a/td/mtproto/CryptoStorer.h +++ b/td/mtproto/CryptoStorer.h @@ -18,6 +18,7 @@ namespace td { namespace mtproto { + template class ObjectImpl { public: @@ -329,5 +330,6 @@ class CryptoImpl { uint64 message_id_; int32 seq_no_; }; + } // namespace mtproto } // namespace td diff --git a/td/mtproto/NoCryptoStorer.h b/td/mtproto/NoCryptoStorer.h index 7836d734..913c658d 100644 --- a/td/mtproto/NoCryptoStorer.h +++ b/td/mtproto/NoCryptoStorer.h @@ -11,12 +11,12 @@ namespace td { namespace mtproto { + class NoCryptoImpl { public: - NoCryptoImpl(uint64 message_id, const Storer &data, bool need_pad = true) : message_id(message_id), data(data) { + NoCryptoImpl(uint64 message_id, const Storer &data, bool need_pad = true) : message_id_(message_id), data_(data) { if (need_pad) { - auto data_size = data.size(); - auto pad_size = (data_size + 15) / 16 * 16 - data_size; + auto pad_size = -static_cast(data_.size()) & 15; pad_size += 16 * (static_cast(Random::secure_int32()) % 16); pad_.resize(pad_size); Random::secure_bytes(pad_); @@ -24,16 +24,17 @@ class NoCryptoImpl { } template void do_store(T &storer) const { - storer.store_binary(message_id); - storer.store_binary(static_cast(data.size() + pad_.size())); - storer.store_storer(data); + storer.store_binary(message_id_); + storer.store_binary(static_cast(data_.size() + pad_.size())); + storer.store_storer(data_); storer.store_slice(pad_); } private: - uint64 message_id; - const Storer &data; + uint64 message_id_; + const Storer &data_; std::string pad_; }; + } // namespace mtproto } // namespace td diff --git a/td/mtproto/TcpTransport.cpp b/td/mtproto/TcpTransport.cpp index d3ab8146..5de248cd 100644 --- a/td/mtproto/TcpTransport.cpp +++ b/td/mtproto/TcpTransport.cpp @@ -151,7 +151,7 @@ void ObfuscatedTransport::init(ChainBufferReader *input, ChainBufferWriter *outp } auto first_int = as(header.data()); if (first_int == 0x44414548 || first_int == 0x54534f50 || first_int == 0x20544547 || first_int == 0x4954504f || - first_int == 0xeeeeeeee) { + first_int == 0xdddddddd || first_int == 0xeeeeeeee) { continue; } auto second_int = as(header.data() + sizeof(uint32)); diff --git a/td/mtproto/TcpTransport.h b/td/mtproto/TcpTransport.h index 43c60105..2ffdaf8c 100644 --- a/td/mtproto/TcpTransport.h +++ b/td/mtproto/TcpTransport.h @@ -119,7 +119,8 @@ class OldTransport : public IStreamTransport { class ObfuscatedTransport : public IStreamTransport { public: - ObfuscatedTransport(int16 dc_id, std::string secret) : dc_id_(dc_id), secret_(std::move(secret)) { + ObfuscatedTransport(int16 dc_id, std::string secret) + : dc_id_(dc_id), secret_(std::move(secret)), impl_(secret_.size() >= 17) { } Result read_next(BufferSlice *message, uint32 *quick_ack) override TD_WARN_UNUSED_RESULT { aes_ctr_byte_flow_.wakeup(); @@ -162,7 +163,7 @@ class ObfuscatedTransport : public IStreamTransport { private: int16 dc_id_; std::string secret_; - TransportImpl impl_{secret_.size() >= 17}; + TransportImpl impl_; AesCtrByteFlow aes_ctr_byte_flow_; ByteFlowSink byte_flow_sink_; ChainBufferReader *input_; diff --git a/td/telegram/net/ConnectionCreator.cpp b/td/telegram/net/ConnectionCreator.cpp index 4d04ec1e..44d34fc9 100644 --- a/td/telegram/net/ConnectionCreator.cpp +++ b/td/telegram/net/ConnectionCreator.cpp @@ -279,6 +279,16 @@ void ConnectionCreator::add_proxy(string server, int32 port, bool enable, return promise.set_error(Status::Error(400, "Wrong port number")); } + auto is_secret_supported = [](Slice secret) { + if (secret.size() == 32) { + return true; + } + if (secret.size() == 34) { + return begins_with(secret, "dd"); + } + return false; + }; + Proxy new_proxy; switch (proxy_type->get_id()) { case td_api::proxyTypeSocks5::ID: { @@ -288,8 +298,11 @@ void ConnectionCreator::add_proxy(string server, int32 port, bool enable, } case td_api::proxyTypeMtproto::ID: { auto type = td_api::move_object_as(proxy_type); - if ((type->secret_.size() != 32 && type->secret_.size() != 34) || hex_decode(type->secret_).is_error()) { - return promise.set_error(Status::Error(400, "Wrong server secret")); + if (hex_decode(type->secret_).is_error()) { + return promise.set_error(Status::Error(400, "Wrong secret")); + } + if (!is_secret_supported(type->secret_)) { + return promise.set_error(Status::Error(400, "Unsupported secret")); } new_proxy = Proxy::mtproto(server, port, type->secret_); break;