0xdd transport

GitOrigin-RevId: 241c2fcea3ebaac20fc68531692cbd299a9de95a
This commit is contained in:
Arseny Smirnov 2018-06-15 21:54:22 +03:00
parent fdd898124b
commit c02d4505e4
7 changed files with 45 additions and 9 deletions

View File

@ -74,6 +74,10 @@ size_t Transport::max_prepend_size() const {
return MAX_PREPEND_SIZE; return MAX_PREPEND_SIZE;
} }
size_t Transport::max_append_size() const {
return 0;
}
} // namespace http } // namespace http
} // namespace mtproto } // namespace mtproto
} // namespace td } // namespace td

View File

@ -33,6 +33,7 @@ class Transport : public IStreamTransport {
} }
size_t max_prepend_size() const override; size_t max_prepend_size() const override;
size_t max_append_size() const override;
TransportType get_type() const override { TransportType get_type() const override {
return {TransportType::Http, 0, ""}; return {TransportType::Http, 0, ""};
} }

View File

@ -30,6 +30,7 @@ class IStreamTransport {
virtual bool can_write() const = 0; virtual bool can_write() const = 0;
virtual void init(ChainBufferReader *input, ChainBufferWriter *output) = 0; virtual void init(ChainBufferReader *input, ChainBufferWriter *output) = 0;
virtual size_t max_prepend_size() const = 0; virtual size_t max_prepend_size() const = 0;
virtual size_t max_append_size() const = 0;
virtual TransportType get_type() const = 0; virtual TransportType get_type() const = 0;
}; };

View File

@ -27,7 +27,8 @@ void RawConnection::send_crypto(const Storer &storer, int64 session_id, int64 sa
info.salt = salt; info.salt = salt;
info.session_id = session_id; info.session_id = session_id;
auto packet = BufferWriter{mtproto::Transport::write(storer, auth_key, &info), transport_->max_prepend_size(), 0}; auto packet = BufferWriter{mtproto::Transport::write(storer, auth_key, &info), transport_->max_prepend_size(),
transport_->max_append_size()};
mtproto::Transport::write(storer, auth_key, &info, packet.as_slice()); mtproto::Transport::write(storer, auth_key, &info, packet.as_slice());
bool use_quick_ack = false; bool use_quick_ack = false;
@ -47,8 +48,8 @@ uint64 RawConnection::send_no_crypto(const Storer &storer) {
mtproto::PacketInfo info; mtproto::PacketInfo info;
info.no_crypto_flag = true; info.no_crypto_flag = true;
auto packet = auto packet = BufferWriter{mtproto::Transport::write(storer, mtproto::AuthKey(), &info),
BufferWriter{mtproto::Transport::write(storer, mtproto::AuthKey(), &info), transport_->max_prepend_size(), 0}; transport_->max_prepend_size(), transport_->max_append_size()};
mtproto::Transport::write(storer, mtproto::AuthKey(), &info, packet.as_slice()); mtproto::Transport::write(storer, mtproto::AuthKey(), &info, packet.as_slice());
LOG(INFO) << "Send handshake packet: " << format::as_hex_dump<4>(packet.as_slice()); LOG(INFO) << "Send handshake packet: " << format::as_hex_dump<4>(packet.as_slice());
transport_->write(std::move(packet), false); transport_->write(std::move(packet), false);

View File

@ -58,11 +58,20 @@ void IntermediateTransport::write_prepare_inplace(BufferWriter *message, bool qu
CHECK(prepend.size() >= prepend_size); CHECK(prepend.size() >= prepend_size);
message->confirm_prepend(prepend_size); message->confirm_prepend(prepend_size);
as<uint32>(message->as_slice().begin()) = static_cast<uint32>(size); size_t append_size = 0;
if (with_padding()) {
append_size = static_cast<uint32>(Random::secure_int32()) % 16;
MutableSlice append = message->prepare_append().truncate(append_size);
CHECK(append.size() == append_size);
Random::secure_bytes(append);
message->confirm_append(append.size());
}
as<uint32>(message->as_slice().begin()) = static_cast<uint32>(size + append_size);
} }
void IntermediateTransport::init_output_stream(ChainBufferWriter *stream) { void IntermediateTransport::init_output_stream(ChainBufferWriter *stream) {
const uint32 magic = 0xeeeeeeee; const uint32 magic = with_padding() ? 0xdddddddd : 0xeeeeeeee;
stream->append(Slice(reinterpret_cast<const char *>(&magic), 4)); stream->append(Slice(reinterpret_cast<const char *>(&magic), 4));
} }
@ -153,7 +162,7 @@ void ObfuscatedTransport::init(ChainBufferReader *input, ChainBufferWriter *outp
} }
// TODO: It is actually IntermediateTransport::init_output_stream, so it will work only with // TODO: It is actually IntermediateTransport::init_output_stream, so it will work only with
// TransportImpl==IntermediateTransport // TransportImpl==IntermediateTransport
as<uint32>(header_slice.begin() + 56) = 0xeeeeeeee; as<uint32>(header_slice.begin() + 56) = impl_.with_padding() ? 0xdddddddd : 0xeeeeeeee;
if (dc_id_ != 0) { if (dc_id_ != 0) {
as<int16>(header_slice.begin() + 60) = dc_id_; as<int16>(header_slice.begin() + 60) = dc_id_;
} }
@ -161,6 +170,9 @@ void ObfuscatedTransport::init(ChainBufferReader *input, ChainBufferWriter *outp
string rheader = header; string rheader = header;
std::reverse(rheader.begin(), rheader.end()); std::reverse(rheader.begin(), rheader.end());
auto key = as<UInt256>(rheader.data() + 8); auto key = as<UInt256>(rheader.data() + 8);
if (secret_.size() == 17) {
secret_ = secret_.substr(1);
}
auto fix_key = [&](UInt256 &key) { auto fix_key = [&](UInt256 &key) {
if (secret_.size() == 16) { if (secret_.size() == 16) {
Sha256State state; Sha256State state;

View File

@ -56,12 +56,20 @@ class AbridgedTransport : public ITransport {
class IntermediateTransport : ITransport { class IntermediateTransport : ITransport {
public: public:
explicit IntermediateTransport(bool with_padding) : with_padding_(with_padding) {
}
size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) override; size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) override;
void write_prepare_inplace(BufferWriter *message, bool quick_ack) override; void write_prepare_inplace(BufferWriter *message, bool quick_ack) override;
void init_output_stream(ChainBufferWriter *stream) override; void init_output_stream(ChainBufferWriter *stream) override;
bool support_quick_ack() const override { bool support_quick_ack() const override {
return true; return true;
} }
bool with_padding() const {
return with_padding_;
}
private:
bool with_padding_;
}; };
using TransportImpl = IntermediateTransport; using TransportImpl = IntermediateTransport;
@ -94,12 +102,17 @@ class OldTransport : public IStreamTransport {
size_t max_prepend_size() const override { size_t max_prepend_size() const override {
return 4; return 4;
} }
size_t max_append_size() const override {
return 15;
}
TransportType get_type() const override { TransportType get_type() const override {
return TransportType{TransportType::Tcp, 0, ""}; return TransportType{TransportType::Tcp, 0, ""};
} }
private: private:
TransportImpl impl_; TransportImpl impl_{false};
ChainBufferReader *input_; ChainBufferReader *input_;
ChainBufferWriter *output_; ChainBufferWriter *output_;
}; };
@ -138,14 +151,18 @@ class ObfuscatedTransport : public IStreamTransport {
return 4; return 4;
} }
size_t max_append_size() const override {
return 15;
}
TransportType get_type() const override { TransportType get_type() const override {
return TransportType{TransportType::ObfuscatedTcp, dc_id_, secret_}; return TransportType{TransportType::ObfuscatedTcp, dc_id_, secret_};
} }
private: private:
TransportImpl impl_;
int16 dc_id_; int16 dc_id_;
std::string secret_; std::string secret_;
TransportImpl impl_{secret_.size() >= 17};
AesCtrByteFlow aes_ctr_byte_flow_; AesCtrByteFlow aes_ctr_byte_flow_;
ByteFlowSink byte_flow_sink_; ByteFlowSink byte_flow_sink_;
ChainBufferReader *input_; ChainBufferReader *input_;

View File

@ -288,7 +288,7 @@ void ConnectionCreator::add_proxy(string server, int32 port, bool enable,
} }
case td_api::proxyTypeMtproto::ID: { case td_api::proxyTypeMtproto::ID: {
auto type = td_api::move_object_as<td_api::proxyTypeMtproto>(proxy_type); auto type = td_api::move_object_as<td_api::proxyTypeMtproto>(proxy_type);
if (type->secret_.size() != 32 || hex_decode(type->secret_).is_error()) { 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")); return promise.set_error(Status::Error(400, "Wrong server secret"));
} }
new_proxy = Proxy::mtproto(server, port, type->secret_); new_proxy = Proxy::mtproto(server, port, type->secret_);