Add strongly typed ProxySecret class.
GitOrigin-RevId: dbde277c6cce57fd6ff51b2e310dab95e60b38c1
This commit is contained in:
parent
0c160b008b
commit
7958916080
@ -345,6 +345,7 @@ set(TDLIB_SOURCE
|
||||
td/mtproto/IStreamTransport.cpp
|
||||
td/mtproto/Ping.cpp
|
||||
td/mtproto/PingConnection.cpp
|
||||
td/mtproto/ProxySecret.cpp
|
||||
td/mtproto/RawConnection.cpp
|
||||
td/mtproto/SessionConnection.cpp
|
||||
td/mtproto/TcpTransport.cpp
|
||||
@ -476,6 +477,7 @@ set(TDLIB_SOURCE
|
||||
td/mtproto/PacketStorer.h
|
||||
td/mtproto/Ping.h
|
||||
td/mtproto/PingConnection.h
|
||||
td/mtproto/ProxySecret.h
|
||||
td/mtproto/Query.h
|
||||
td/mtproto/RawConnection.h
|
||||
td/mtproto/SessionConnection.h
|
||||
|
@ -56,6 +56,7 @@ class AuthKey {
|
||||
}
|
||||
|
||||
enum : int32 { AUTH_FLAG = 1, WAS_AUTH_FLAG = 2 };
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const {
|
||||
storer.store_binary(auth_key_id_);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "td/mtproto/IStreamTransport.h"
|
||||
#include "td/mtproto/ProxySecret.h"
|
||||
#include "td/mtproto/TransportType.h"
|
||||
|
||||
#include "td/net/HttpQuery.h"
|
||||
@ -40,7 +41,7 @@ class Transport : public IStreamTransport {
|
||||
size_t max_prepend_size() const override;
|
||||
size_t max_append_size() const override;
|
||||
TransportType get_type() const override {
|
||||
return {TransportType::Http, 0, secret_};
|
||||
return {TransportType::Http, 0, ProxySecret::from_raw(secret_)};
|
||||
}
|
||||
bool use_random_padding() const override;
|
||||
|
||||
|
@ -19,7 +19,7 @@ unique_ptr<IStreamTransport> create_transport(TransportType type) {
|
||||
case TransportType::Tcp:
|
||||
return td::make_unique<tcp::OldTransport>();
|
||||
case TransportType::Http:
|
||||
return td::make_unique<http::Transport>(type.secret);
|
||||
return td::make_unique<http::Transport>(type.secret.get_raw_secret().str());
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
46
td/mtproto/ProxySecret.cpp
Normal file
46
td/mtproto/ProxySecret.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#include "td/mtproto/ProxySecret.h"
|
||||
|
||||
#include "td/utils/base64.h"
|
||||
#include "td/utils/misc.h"
|
||||
|
||||
namespace td {
|
||||
namespace mtproto {
|
||||
|
||||
Result<ProxySecret> ProxySecret::from_link(Slice encoded_secret) {
|
||||
auto r_decoded = hex_decode(encoded_secret);
|
||||
if (r_decoded.is_error()) {
|
||||
r_decoded = base64url_decode(encoded_secret);
|
||||
}
|
||||
if (r_decoded.is_error()) {
|
||||
return Status::Error(400, "Wrong proxy secret");
|
||||
}
|
||||
return from_binary(r_decoded.ok());
|
||||
}
|
||||
|
||||
Result<ProxySecret> ProxySecret::from_binary(Slice raw_unchecked_secret) {
|
||||
if (raw_unchecked_secret.size() == 16 ||
|
||||
(raw_unchecked_secret.size() == 17 && static_cast<unsigned char>(raw_unchecked_secret[0]) == 0xdd) ||
|
||||
(raw_unchecked_secret.size() >= 17 && static_cast<unsigned char>(raw_unchecked_secret[0]) == 0xee)) {
|
||||
return from_raw(raw_unchecked_secret);
|
||||
}
|
||||
if (raw_unchecked_secret.size() < 16) {
|
||||
return Status::Error(400, "Wrong proxy secret");
|
||||
}
|
||||
return Status::Error(400, "Unsupported proxy secret");
|
||||
}
|
||||
|
||||
string ProxySecret::get_encoded_secret() const {
|
||||
if (emulate_tls()) {
|
||||
return base64url_encode(secret_);
|
||||
}
|
||||
return buffer_to_hex(secret_);
|
||||
}
|
||||
|
||||
} // namespace mtproto
|
||||
} // namespace td
|
65
td/mtproto/ProxySecret.h
Normal file
65
td/mtproto/ProxySecret.h
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
namespace mtproto {
|
||||
|
||||
class ProxySecret {
|
||||
public:
|
||||
static Result<ProxySecret> from_link(Slice encoded_secret);
|
||||
static Result<ProxySecret> from_binary(Slice raw_unchecked_secret);
|
||||
static ProxySecret from_raw(Slice raw_secret) {
|
||||
ProxySecret result;
|
||||
result.secret_ = raw_secret.str();
|
||||
return result;
|
||||
}
|
||||
|
||||
Slice get_raw_secret() const {
|
||||
return secret_;
|
||||
}
|
||||
|
||||
Slice get_proxy_secret() const {
|
||||
auto proxy_secret = Slice(secret_).truncate(17);
|
||||
if (proxy_secret.size() == 17) {
|
||||
proxy_secret.remove_prefix(1);
|
||||
}
|
||||
return proxy_secret;
|
||||
}
|
||||
|
||||
string get_encoded_secret() const;
|
||||
|
||||
bool use_random_padding() const {
|
||||
return secret_.size() >= 17;
|
||||
}
|
||||
|
||||
bool emulate_tls() const {
|
||||
return secret_.size() >= 17 && static_cast<unsigned char>(secret_[0]) == 0xee;
|
||||
}
|
||||
|
||||
string get_domain() const {
|
||||
CHECK(emulate_tls());
|
||||
return secret_.substr(17);
|
||||
}
|
||||
|
||||
private:
|
||||
friend bool operator==(const ProxySecret &lhs, const ProxySecret &rhs) {
|
||||
return lhs.secret_ == rhs.secret_;
|
||||
}
|
||||
string secret_;
|
||||
};
|
||||
|
||||
inline bool operator!=(const ProxySecret &lhs, const ProxySecret &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace mtproto
|
||||
} // namespace td
|
@ -170,22 +170,19 @@ void ObfuscatedTransport::init(ChainBufferReader *input, ChainBufferWriter *outp
|
||||
string rheader = header;
|
||||
std::reverse(rheader.begin(), rheader.end());
|
||||
UInt256 key = as<UInt256>(rheader.data() + 8);
|
||||
Slice secret_view = secret_;
|
||||
if (secret_view.size() == 17) {
|
||||
secret_view.remove_prefix(1);
|
||||
}
|
||||
Slice proxy_secret = secret_.get_proxy_secret();
|
||||
auto fix_key = [&](UInt256 &key) {
|
||||
if (secret_view.size() == 16) {
|
||||
if (!proxy_secret.empty()) {
|
||||
Sha256State state;
|
||||
sha256_init(&state);
|
||||
sha256_update(as_slice(key), &state);
|
||||
sha256_update(secret_view, &state);
|
||||
sha256_update(proxy_secret, &state);
|
||||
sha256_final(&state, as_slice(key));
|
||||
}
|
||||
};
|
||||
fix_key(key);
|
||||
aes_ctr_byte_flow_.init(key, as<UInt128>(rheader.data() + 8 + 32));
|
||||
if (emulate_tls_) {
|
||||
if (secret_.emulate_tls()) {
|
||||
tls_reader_byte_flow_.set_input(input_);
|
||||
tls_reader_byte_flow_ >> aes_ctr_byte_flow_;
|
||||
} else {
|
||||
@ -202,7 +199,7 @@ void ObfuscatedTransport::init(ChainBufferReader *input, ChainBufferWriter *outp
|
||||
}
|
||||
|
||||
Result<size_t> ObfuscatedTransport::read_next(BufferSlice *message, uint32 *quick_ack) {
|
||||
if (emulate_tls_) {
|
||||
if (secret_.emulate_tls()) {
|
||||
tls_reader_byte_flow_.wakeup();
|
||||
} else {
|
||||
aes_ctr_byte_flow_.wakeup();
|
||||
@ -213,7 +210,7 @@ Result<size_t> ObfuscatedTransport::read_next(BufferSlice *message, uint32 *quic
|
||||
void ObfuscatedTransport::write(BufferWriter &&message, bool quick_ack) {
|
||||
impl_.write_prepare_inplace(&message, quick_ack);
|
||||
output_state_.encrypt(message.as_slice(), message.as_slice());
|
||||
if (emulate_tls_) {
|
||||
if (secret_.emulate_tls()) {
|
||||
do_write_tls(std::move(message));
|
||||
} else {
|
||||
do_write_main(std::move(message));
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "td/mtproto/IStreamTransport.h"
|
||||
#include "td/mtproto/ProxySecret.h"
|
||||
#include "td/mtproto/TlsReaderByteFlow.h"
|
||||
#include "td/mtproto/TransportType.h"
|
||||
|
||||
@ -112,7 +113,7 @@ class OldTransport : public IStreamTransport {
|
||||
}
|
||||
|
||||
TransportType get_type() const override {
|
||||
return TransportType{TransportType::Tcp, 0, ""};
|
||||
return TransportType{TransportType::Tcp, 0, ProxySecret()};
|
||||
}
|
||||
|
||||
bool use_random_padding() const override {
|
||||
@ -127,10 +128,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)), impl_(secret_.size() >= 17) {
|
||||
emulate_tls_ = secret_.size() >= 17 && secret_[0] == '\xee';
|
||||
use_random_padding_ = secret_.size() >= 17;
|
||||
ObfuscatedTransport(int16 dc_id, const ProxySecret &secret)
|
||||
: dc_id_(dc_id), secret_(secret), impl_(secret_.use_random_padding()) {
|
||||
}
|
||||
|
||||
Result<size_t> read_next(BufferSlice *message, uint32 *quick_ack) override TD_WARN_UNUSED_RESULT;
|
||||
@ -153,7 +152,7 @@ class ObfuscatedTransport : public IStreamTransport {
|
||||
|
||||
size_t max_prepend_size() const override {
|
||||
size_t res = 4;
|
||||
if (emulate_tls_) {
|
||||
if (secret_.emulate_tls()) {
|
||||
res += 5;
|
||||
if (is_first_tls_packet_) {
|
||||
res += 6;
|
||||
@ -174,21 +173,19 @@ class ObfuscatedTransport : public IStreamTransport {
|
||||
return TransportType{TransportType::ObfuscatedTcp, dc_id_, secret_};
|
||||
}
|
||||
bool use_random_padding() const override {
|
||||
return use_random_padding_;
|
||||
return secret_.use_random_padding();
|
||||
}
|
||||
|
||||
private:
|
||||
int16 dc_id_;
|
||||
std::string secret_;
|
||||
bool emulate_tls_{false};
|
||||
bool use_random_padding_{false};
|
||||
bool is_first_tls_packet_{true};
|
||||
ProxySecret secret_;
|
||||
std::string header_;
|
||||
TransportImpl impl_;
|
||||
TlsReaderByteFlow tls_reader_byte_flow_;
|
||||
AesCtrByteFlow aes_ctr_byte_flow_;
|
||||
ByteFlowSink byte_flow_sink_;
|
||||
ChainBufferReader *input_;
|
||||
ChainBufferReader *input_ = nullptr;
|
||||
|
||||
static constexpr int32 MAX_TLS_PACKET_LENGTH = 2878;
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/mtproto/ProxySecret.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
|
||||
namespace td {
|
||||
@ -14,14 +16,10 @@ namespace mtproto {
|
||||
struct TransportType {
|
||||
enum Type { Tcp, ObfuscatedTcp, Http } type = Tcp;
|
||||
int16 dc_id{0};
|
||||
string secret;
|
||||
ProxySecret secret;
|
||||
|
||||
TransportType() = default;
|
||||
TransportType(Type type, int16 dc_id, string secret) : type(type), dc_id(dc_id), secret(std::move(secret)) {
|
||||
}
|
||||
|
||||
bool emulate_tls() const {
|
||||
return secret.size() >= 17 && secret[0] == '\xee';
|
||||
TransportType(Type type, int16 dc_id, ProxySecret secret) : type(type), dc_id(dc_id), secret(std::move(secret)) {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -137,7 +137,7 @@ void Proxy::store(StorerT &storer) const {
|
||||
} else if (type_ == Proxy::Type::Mtproto) {
|
||||
store(server_, storer);
|
||||
store(port_, storer);
|
||||
store(secret_, storer);
|
||||
store(secret_.get_encoded_secret(), storer);
|
||||
} else {
|
||||
CHECK(type_ == Proxy::Type::None);
|
||||
}
|
||||
@ -155,7 +155,7 @@ void Proxy::parse(ParserT &parser) {
|
||||
} else if (type_ == Proxy::Type::Mtproto) {
|
||||
parse(server_, parser);
|
||||
parse(port_, parser);
|
||||
parse(secret_, parser);
|
||||
secret_ = mtproto::ProxySecret::from_link(parser.template fetch_string<Slice>()).move_as_ok();
|
||||
} else {
|
||||
LOG_CHECK(type_ == Proxy::Type::None) << static_cast<int32>(type_);
|
||||
}
|
||||
@ -170,7 +170,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Proxy &proxy) {
|
||||
case Proxy::Type::HttpCaching:
|
||||
return string_builder << "ProxyHttpCaching " << proxy.server() << ":" << proxy.port();
|
||||
case Proxy::Type::Mtproto:
|
||||
return string_builder << "ProxyMtproto " << proxy.server() << ":" << proxy.port() << "/" << proxy.secret();
|
||||
return string_builder << "ProxyMtproto " << proxy.server() << ":" << proxy.port() << "/"
|
||||
<< proxy.secret().get_encoded_secret();
|
||||
case Proxy::Type::None:
|
||||
return string_builder << "ProxyEmpty";
|
||||
default:
|
||||
@ -239,16 +240,6 @@ void ConnectionCreator::add_proxy(int32 old_proxy_id, string server, int32 port,
|
||||
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") || begins_with(secret, "ee");
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Proxy new_proxy;
|
||||
switch (proxy_type->get_id()) {
|
||||
case td_api::proxyTypeSocks5::ID: {
|
||||
@ -267,13 +258,11 @@ void ConnectionCreator::add_proxy(int32 old_proxy_id, string server, int32 port,
|
||||
}
|
||||
case td_api::proxyTypeMtproto::ID: {
|
||||
auto type = td_api::move_object_as<td_api::proxyTypeMtproto>(proxy_type);
|
||||
if (hex_decode(type->secret_).is_error()) {
|
||||
return promise.set_error(Status::Error(400, "Wrong secret"));
|
||||
auto r_secret = mtproto::ProxySecret::from_link(type->secret_);
|
||||
if (r_secret.is_error()) {
|
||||
return promise.set_error(r_secret.move_as_error());
|
||||
}
|
||||
if (!is_secret_supported(type->secret_)) {
|
||||
return promise.set_error(Status::Error(400, "Unsupported secret"));
|
||||
}
|
||||
new_proxy = Proxy::mtproto(server, port, type->secret_);
|
||||
new_proxy = Proxy::mtproto(server, port, r_secret.move_as_ok());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -397,7 +386,7 @@ void ConnectionCreator::get_proxy_link(int32 proxy_id, Promise<string> promise)
|
||||
}
|
||||
} else {
|
||||
url += "&secret=";
|
||||
url += url_encode(proxy.secret());
|
||||
url += proxy.secret().get_encoded_secret();
|
||||
}
|
||||
promise.set_value(std::move(url));
|
||||
}
|
||||
@ -502,7 +491,7 @@ void ConnectionCreator::ping_proxy_resolved(int32 proxy_id, IPAddress ip_address
|
||||
}
|
||||
auto socket_fd = r_socket_fd.move_as_ok();
|
||||
|
||||
bool emulate_tls = extra.transport_type.emulate_tls();
|
||||
auto secret = extra.transport_type.secret;
|
||||
|
||||
auto socket_fd_promise =
|
||||
PromiseCreator::lambda([promise = std::move(promise), actor_id = actor_id(this),
|
||||
@ -514,7 +503,7 @@ void ConnectionCreator::ping_proxy_resolved(int32 proxy_id, IPAddress ip_address
|
||||
std::move(transport_type), std::move(promise));
|
||||
});
|
||||
CHECK(proxy.use_proxy());
|
||||
if (proxy.use_socks5_proxy() || proxy.use_http_tcp_proxy() || emulate_tls) {
|
||||
if (proxy.use_socks5_proxy() || proxy.use_http_tcp_proxy() || secret.emulate_tls()) {
|
||||
class Callback : public TransparentProxy::Callback {
|
||||
public:
|
||||
explicit Callback(Promise<SocketFd> promise) : promise_(std::move(promise)) {
|
||||
@ -540,11 +529,11 @@ void ConnectionCreator::ping_proxy_resolved(int32 proxy_id, IPAddress ip_address
|
||||
children_[token] = {false, create_actor<HttpProxy>("PingHttpProxy", std::move(socket_fd), extra.mtproto_ip,
|
||||
proxy.proxy().user().str(), proxy.proxy().password().str(),
|
||||
std::move(callback), create_reference(token))};
|
||||
} else if (emulate_tls) {
|
||||
} else if (secret.emulate_tls()) {
|
||||
children_[token] = {
|
||||
false, create_actor<TlsInit>("PingTlsInit", std::move(socket_fd), extra.mtproto_ip, "www.google.com",
|
||||
hex_decode(proxy.proxy().secret().substr(2)).move_as_ok(), std::move(callback),
|
||||
create_reference(token), G()->get_dns_time_difference())};
|
||||
false, create_actor<TlsInit>("PingTlsInit", std::move(socket_fd), extra.mtproto_ip, secret.get_domain(),
|
||||
secret.get_proxy_secret().str(), std::move(callback), create_reference(token),
|
||||
G()->get_dns_time_difference())};
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -694,7 +683,7 @@ td_api::object_ptr<td_api::proxy> ConnectionCreator::get_proxy_object(int32 prox
|
||||
type = make_tl_object<td_api::proxyTypeHttp>(proxy.user().str(), proxy.password().str(), true);
|
||||
break;
|
||||
case Proxy::Type::Mtproto:
|
||||
type = make_tl_object<td_api::proxyTypeMtproto>(proxy.secret().str());
|
||||
type = make_tl_object<td_api::proxyTypeMtproto>(proxy.secret().get_encoded_secret());
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -790,8 +779,11 @@ void ConnectionCreator::request_raw_connection_by_ip(IPAddress ip_address,
|
||||
if (r_socket_fd.is_error()) {
|
||||
return promise.set_error(r_socket_fd.move_as_error());
|
||||
}
|
||||
|
||||
// TODO TransportType is wrong
|
||||
auto raw_connection = make_unique<mtproto::RawConnection>(
|
||||
r_socket_fd.move_as_ok(), mtproto::TransportType{mtproto::TransportType::ObfuscatedTcp, 0, ""}, nullptr);
|
||||
r_socket_fd.move_as_ok(),
|
||||
mtproto::TransportType{mtproto::TransportType::ObfuscatedTcp, 0, mtproto::ProxySecret()}, nullptr);
|
||||
raw_connection->extra_ = network_generation_;
|
||||
promise.set_value(std::move(raw_connection));
|
||||
}
|
||||
@ -805,8 +797,7 @@ Result<mtproto::TransportType> ConnectionCreator::get_transport_type(const Proxy
|
||||
int16 raw_dc_id = narrow_cast<int16>(info.option->is_media_only() ? -int_dc_id : int_dc_id);
|
||||
|
||||
if (proxy.use_mtproto_proxy()) {
|
||||
TRY_RESULT(secret, hex_decode(proxy.proxy().secret()));
|
||||
return mtproto::TransportType{mtproto::TransportType::ObfuscatedTcp, raw_dc_id, std::move(secret)};
|
||||
return mtproto::TransportType{mtproto::TransportType::ObfuscatedTcp, raw_dc_id, proxy.proxy().secret()};
|
||||
}
|
||||
if (proxy.use_http_caching_proxy()) {
|
||||
CHECK(info.option != nullptr);
|
||||
@ -815,14 +806,15 @@ Result<mtproto::TransportType> ConnectionCreator::get_transport_type(const Proxy
|
||||
proxy_authorization =
|
||||
"|basic " + td::base64_encode(PSLICE() << proxy.proxy().user() << ':' << proxy.proxy().password());
|
||||
}
|
||||
return mtproto::TransportType{mtproto::TransportType::Http, 0,
|
||||
PSTRING() << info.option->get_ip_address().get_ip_str() << proxy_authorization};
|
||||
return mtproto::TransportType{
|
||||
mtproto::TransportType::Http, 0,
|
||||
mtproto::ProxySecret::from_raw(PSTRING() << info.option->get_ip_address().get_ip_str() << proxy_authorization)};
|
||||
}
|
||||
|
||||
if (info.use_http) {
|
||||
return mtproto::TransportType{mtproto::TransportType::Http, 0, ""};
|
||||
return mtproto::TransportType{mtproto::TransportType::Http, 0, mtproto::ProxySecret()};
|
||||
} else {
|
||||
return mtproto::TransportType{mtproto::TransportType::ObfuscatedTcp, raw_dc_id, info.option->get_secret().str()};
|
||||
return mtproto::TransportType{mtproto::TransportType::ObfuscatedTcp, raw_dc_id, info.option->get_secret()};
|
||||
}
|
||||
}
|
||||
|
||||
@ -971,7 +963,7 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
|
||||
client.checking_connections++;
|
||||
}
|
||||
|
||||
bool emulate_tls = extra.transport_type.emulate_tls();
|
||||
mtproto::ProxySecret secret = extra.transport_type.secret;
|
||||
|
||||
auto promise = PromiseCreator::lambda(
|
||||
[actor_id = actor_id(this), check_mode, transport_type = extra.transport_type, hash = client.hash,
|
||||
@ -985,7 +977,7 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
|
||||
td::make_unique<detail::StatsCallback>(client.is_media ? media_net_stats_callback_ : common_net_stats_callback_,
|
||||
actor_id(this), client.hash, extra.stat);
|
||||
|
||||
if (proxy.use_socks5_proxy() || proxy.use_http_tcp_proxy() || emulate_tls) {
|
||||
if (proxy.use_socks5_proxy() || proxy.use_http_tcp_proxy() || secret.emulate_tls()) {
|
||||
VLOG(connections) << "In client_loop: create new transparent proxy connection " << extra.debug_str;
|
||||
class Callback : public TransparentProxy::Callback {
|
||||
public:
|
||||
@ -1029,11 +1021,11 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
|
||||
children_[token] = {true, create_actor<HttpProxy>("HttpProxy", std::move(socket_fd), extra.mtproto_ip,
|
||||
proxy.proxy().user().str(), proxy.proxy().password().str(),
|
||||
std::move(callback), create_reference(token))};
|
||||
} else if (emulate_tls) {
|
||||
} else if (secret.emulate_tls()) {
|
||||
children_[token] = {
|
||||
true, create_actor<TlsInit>("TlsInit", std::move(socket_fd), extra.mtproto_ip, "www.google.com",
|
||||
hex_decode(proxy.proxy().secret().substr(2)).move_as_ok(), std::move(callback),
|
||||
create_reference(token), G()->get_dns_time_difference())};
|
||||
true, create_actor<TlsInit>("TlsInit", std::move(socket_fd), extra.mtproto_ip, secret.get_domain(),
|
||||
secret.get_proxy_secret().str(), std::move(callback), create_reference(token),
|
||||
G()->get_dns_time_difference())};
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "td/telegram/StateManager.h"
|
||||
|
||||
#include "td/mtproto/AuthData.h"
|
||||
#include "td/mtproto/ProxySecret.h"
|
||||
#include "td/mtproto/TransportType.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
@ -86,7 +87,7 @@ class Proxy {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
static Proxy mtproto(string server, int32 port, string secret) {
|
||||
static Proxy mtproto(string server, int32 port, mtproto::ProxySecret secret) {
|
||||
Proxy proxy;
|
||||
proxy.type_ = Type::Mtproto;
|
||||
proxy.server_ = std::move(server);
|
||||
@ -111,7 +112,7 @@ class Proxy {
|
||||
return password_;
|
||||
}
|
||||
|
||||
CSlice secret() const {
|
||||
const mtproto::ProxySecret &secret() const {
|
||||
return secret_;
|
||||
}
|
||||
|
||||
@ -132,7 +133,7 @@ class Proxy {
|
||||
int32 port_ = 0;
|
||||
string user_;
|
||||
string password_;
|
||||
string secret_;
|
||||
mtproto::ProxySecret secret_;
|
||||
};
|
||||
|
||||
inline bool operator==(const Proxy &lhs, const Proxy &rhs) {
|
||||
|
@ -6,9 +6,10 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/telegram/telegram_api.h"
|
||||
#include "td/mtproto/ProxySecret.h"
|
||||
|
||||
#include "td/telegram/net/DcId.h"
|
||||
#include "td/telegram/telegram_api.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/format.h"
|
||||
@ -27,7 +28,7 @@ class DcOption {
|
||||
int32 flags_ = 0;
|
||||
DcId dc_id_;
|
||||
IPAddress ip_address_;
|
||||
string secret_;
|
||||
mtproto::ProxySecret secret_;
|
||||
|
||||
struct PrintFlags {
|
||||
int32 flags;
|
||||
@ -69,10 +70,11 @@ class DcOption {
|
||||
}
|
||||
if (!option.secret_.empty()) {
|
||||
flags_ |= Flags::HasSecret;
|
||||
if (option.secret_.size() != 16u && option.secret_.size() != 17u) {
|
||||
auto r_secret = mtproto::ProxySecret::from_binary(option.secret_.as_slice());
|
||||
if (r_secret.is_error()) {
|
||||
return;
|
||||
}
|
||||
secret_ = option.secret_.as_slice().str();
|
||||
secret_ = r_secret.move_as_ok();
|
||||
}
|
||||
init_ip_address(ip, port);
|
||||
}
|
||||
@ -86,11 +88,12 @@ class DcOption {
|
||||
}
|
||||
case telegram_api::ipPortSecret::ID: {
|
||||
auto &ip_port = static_cast<const telegram_api::ipPortSecret &>(ip_port_ref);
|
||||
if (ip_port.secret_.size() != 16u && ip_port.secret_.size() != 17u) {
|
||||
auto r_secret = mtproto::ProxySecret::from_binary(ip_port.secret_.as_slice());
|
||||
if (r_secret.is_error()) {
|
||||
return;
|
||||
}
|
||||
flags_ |= Flags::HasSecret;
|
||||
secret_ = ip_port.secret_.as_slice().str();
|
||||
secret_ = r_secret.move_as_ok();
|
||||
init_ip_address(IPAddress::ipv4_to_str(static_cast<uint32>(ip_port.ipv4_)), ip_port.port_);
|
||||
break;
|
||||
}
|
||||
@ -129,7 +132,7 @@ class DcOption {
|
||||
return ip_address_.is_valid() && dc_id_.is_exact();
|
||||
}
|
||||
|
||||
Slice get_secret() const {
|
||||
const mtproto::ProxySecret &get_secret() const {
|
||||
return secret_;
|
||||
}
|
||||
|
||||
@ -141,7 +144,7 @@ class DcOption {
|
||||
storer.store_string(ip_address_.get_ip_str());
|
||||
storer.store_int(ip_address_.get_port());
|
||||
if ((flags_ & Flags::HasSecret) != 0) {
|
||||
storer.store_string(secret_);
|
||||
td::store(secret_.get_raw_secret(), storer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,7 +166,7 @@ class DcOption {
|
||||
auto port = parser.fetch_int();
|
||||
init_ip_address(ip, port);
|
||||
if ((flags_ & Flags::HasSecret) != 0) {
|
||||
secret_ = parser.template fetch_string<std::string>();
|
||||
secret_ = mtproto::ProxySecret::from_raw(parser.template fetch_string<Slice>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,7 +216,7 @@ inline StringBuilder &operator<<(StringBuilder &sb, const DcOption::PrintFlags &
|
||||
inline StringBuilder &operator<<(StringBuilder &sb, const DcOption &dc_option) {
|
||||
return sb << tag("DcOption", format::concat(dc_option.dc_id_, tag("ip", dc_option.ip_address_.get_ip_str()),
|
||||
tag("port", dc_option.ip_address_.get_port()),
|
||||
tag("secret_len", dc_option.secret_.size()),
|
||||
tag("secret_len", dc_option.get_secret().get_raw_secret().size()),
|
||||
tag("flags", DcOption::PrintFlags{dc_option.flags_})));
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "td/mtproto/HandshakeActor.h"
|
||||
#include "td/mtproto/Ping.h"
|
||||
#include "td/mtproto/PingConnection.h"
|
||||
#include "td/mtproto/ProxySecret.h"
|
||||
#include "td/mtproto/RawConnection.h"
|
||||
#include "td/mtproto/TlsInit.h"
|
||||
#include "td/mtproto/TransportType.h"
|
||||
@ -177,8 +178,9 @@ class TestPingActor : public Actor {
|
||||
|
||||
void start_up() override {
|
||||
ping_connection_ = mtproto::PingConnection::create_req_pq(
|
||||
make_unique<mtproto::RawConnection>(SocketFd::open(ip_address_).move_as_ok(),
|
||||
mtproto::TransportType{mtproto::TransportType::Tcp, 0, ""}, nullptr),
|
||||
make_unique<mtproto::RawConnection>(
|
||||
SocketFd::open(ip_address_).move_as_ok(),
|
||||
mtproto::TransportType{mtproto::TransportType::Tcp, 0, mtproto::ProxySecret()}, nullptr),
|
||||
3);
|
||||
|
||||
Scheduler::subscribe(ping_connection_->get_poll_info().extract_pollable_fd(this));
|
||||
@ -287,9 +289,9 @@ class HandshakeTestActor : public Actor {
|
||||
}
|
||||
void loop() override {
|
||||
if (!wait_for_raw_connection_ && !raw_connection_) {
|
||||
raw_connection_ =
|
||||
make_unique<mtproto::RawConnection>(SocketFd::open(get_default_ip_address()).move_as_ok(),
|
||||
mtproto::TransportType{mtproto::TransportType::Tcp, 0, ""}, nullptr);
|
||||
raw_connection_ = make_unique<mtproto::RawConnection>(
|
||||
SocketFd::open(get_default_ip_address()).move_as_ok(),
|
||||
mtproto::TransportType{mtproto::TransportType::Tcp, 0, mtproto::ProxySecret()}, nullptr);
|
||||
}
|
||||
if (!wait_for_handshake_ && !handshake_) {
|
||||
handshake_ = make_unique<mtproto::AuthKeyHandshake>(dc_id_, 0);
|
||||
@ -483,9 +485,9 @@ class FastPingTestActor : public Actor {
|
||||
|
||||
void start_up() override {
|
||||
// Run handshake to create key and salt
|
||||
auto raw_connection =
|
||||
make_unique<mtproto::RawConnection>(SocketFd::open(get_default_ip_address()).move_as_ok(),
|
||||
mtproto::TransportType{mtproto::TransportType::Tcp, 0, ""}, nullptr);
|
||||
auto raw_connection = make_unique<mtproto::RawConnection>(
|
||||
SocketFd::open(get_default_ip_address()).move_as_ok(),
|
||||
mtproto::TransportType{mtproto::TransportType::Tcp, 0, mtproto::ProxySecret()}, nullptr);
|
||||
auto handshake = make_unique<mtproto::AuthKeyHandshake>(get_default_dc_id(), 60 * 100 /*temp*/);
|
||||
create_actor<mtproto::HandshakeActor>(
|
||||
"HandshakeActor", std::move(handshake), std::move(raw_connection), make_unique<HandshakeContext>(), 10.0,
|
||||
|
Reference in New Issue
Block a user