diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index b00003bb60..7a8730d01a 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -738,8 +738,7 @@ ProxyData ProxyBox::collectData() { } else if ((result.type == Type::Http || result.type == Type::Socks5) && !result.password.isEmpty() && result.user.isEmpty()) { _user->showError(); - } else if (result.type == Type::Mtproto - && result.password.size() != 32) { + } else if (result.type == Type::Mtproto && !result.valid()) { _secret->showError(); } else if (!result) { _host->showError(); @@ -850,7 +849,7 @@ void ProxyBox::setupMtprotoCredentials(const ProxyData &data) { st::connectionUserInputField, langFactory(lng_connection_proxy_secret_ph), (data.type == Type::Mtproto) ? data.password : QString()); - _secret->setMaxLength(32); + _secret->setMaxLength(ProxyData::MaxMtprotoPasswordLength()); _secret->move(0, 0); _secret->heightValue( ) | rpl::start_with_next([=, wrap = secretWrap.data()](int height) { @@ -1107,7 +1106,7 @@ void ProxiesBoxController::refreshChecker(Item &item) { item.checker->connectToServer( item.data.host, item.data.port, - MTP::ProtocolSecretFromPassword(item.data.password), + item.data.secretFromMtprotoPassword(), dcId); } else { const auto options = mtproto->dcOptions()->lookup( diff --git a/Telegram/SourceFiles/core/utils.cpp b/Telegram/SourceFiles/core/utils.cpp index e8bcf478b0..3c438d8b45 100644 --- a/Telegram/SourceFiles/core/utils.cpp +++ b/Telegram/SourceFiles/core/utils.cpp @@ -240,12 +240,16 @@ namespace { bool ProxyData::valid() const { if (type == Type::None || host.isEmpty() || !port) { return false; - } else if (type == Type::Mtproto && !ValidSecret(password)) { + } else if (type == Type::Mtproto && !ValidMtprotoPassword(password)) { return false; } return true; } +int ProxyData::MaxMtprotoPasswordLength() { + return 34; +} + bool ProxyData::supportsCalls() const { return (type == Type::Socks5); } @@ -258,6 +262,34 @@ bool ProxyData::tryCustomResolve() const { ).match(host).hasMatch(); } +bytes::vector ProxyData::secretFromMtprotoPassword() const { + Expects(type == Type::Mtproto); + Expects(password.size() % 2 == 0); + + const auto length = password.size() / 2; + const auto fromHex = [](QChar ch) -> int { + const auto code = int(ch.unicode()); + if (code >= '0' && code <= '9') { + return (code - '0'); + } else if (code >= 'A' && code <= 'F') { + return 10 + (code - 'A'); + } else if (ch >= 'a' && ch <= 'f') { + return 10 + (code - 'a'); + } + return -1; + }; + auto result = bytes::vector(length); + for (auto i = 0; i != length; ++i) { + const auto high = fromHex(password[2 * i]); + const auto low = fromHex(password[2 * i + 1]); + if (high < 0 || low < 0) { + return {}; + } + result[i] = static_cast(high * 16 + low); + } + return result; +} + ProxyData::operator bool() const { return valid(); } @@ -277,8 +309,15 @@ bool ProxyData::operator!=(const ProxyData &other) const { return !(*this == other); } -bool ProxyData::ValidSecret(const QString &secret) { - return QRegularExpression("^[a-fA-F0-9]{32}$").match(secret).hasMatch(); +bool ProxyData::ValidMtprotoPassword(const QString &secret) { + if (secret.size() == 32) { + static const auto check = QRegularExpression("^[a-fA-F0-9]{32}$"); + return check.match(secret).hasMatch(); + } else if (secret.size() == 34) { + static const auto check = QRegularExpression("^dd[a-fA-F0-9]{32}$"); + return check.match(secret).hasMatch(); + } + return false; } ProxyData ToDirectIpProxy(const ProxyData &proxy, int ipIndex) { diff --git a/Telegram/SourceFiles/core/utils.h b/Telegram/SourceFiles/core/utils.h index 1e71dd3e3e..bdc258ea9b 100644 --- a/Telegram/SourceFiles/core/utils.h +++ b/Telegram/SourceFiles/core/utils.h @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/flags.h" #include "base/algorithm.h" #include "base/assertion.h" +#include "base/bytes.h" #include #include @@ -400,11 +401,13 @@ struct ProxyData { bool valid() const; bool supportsCalls() const; bool tryCustomResolve() const; + bytes::vector secretFromMtprotoPassword() const; explicit operator bool() const; bool operator==(const ProxyData &other) const; bool operator!=(const ProxyData &other) const; - static bool ValidSecret(const QString &secret); + static bool ValidMtprotoPassword(const QString &secret); + static int MaxMtprotoPasswordLength(); }; diff --git a/Telegram/SourceFiles/mtproto/connection_abstract.cpp b/Telegram/SourceFiles/mtproto/connection_abstract.cpp index 2e1bdd75d0..8d72dfec4c 100644 --- a/Telegram/SourceFiles/mtproto/connection_abstract.cpp +++ b/Telegram/SourceFiles/mtproto/connection_abstract.cpp @@ -14,38 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace MTP { namespace internal { -namespace { - -bytes::vector ProtocolSecretFromPassword(const QString &password) { - const auto size = password.size(); - if (size % 2) { - return {}; - } - const auto length = size / 2; - const auto fromHex = [](QChar ch) -> int { - const auto code = int(ch.unicode()); - if (code >= '0' && code <= '9') { - return (code - '0'); - } else if (code >= 'A' && code <= 'F') { - return 10 + (code - 'A'); - } else if (ch >= 'a' && ch <= 'f') { - return 10 + (code - 'a'); - } - return -1; - }; - auto result = bytes::vector(length); - for (auto i = 0; i != length; ++i) { - const auto high = fromHex(password[2 * i]); - const auto low = fromHex(password[2 * i + 1]); - if (high < 0 || low < 0) { - return {}; - } - result[i] = static_cast(high * 16 + low); - } - return result; -} - -} // namespace ConnectionPointer::ConnectionPointer() = default; @@ -189,9 +157,4 @@ ConnectionPointer AbstractConnection::Create( } } // namespace internal - -bytes::vector ProtocolSecretFromPassword(const QString &password) { - return internal::ProtocolSecretFromPassword(password); -} - } // namespace MTP diff --git a/Telegram/SourceFiles/mtproto/connection_abstract.h b/Telegram/SourceFiles/mtproto/connection_abstract.h index 02c1b898b5..70fe80e30e 100644 --- a/Telegram/SourceFiles/mtproto/connection_abstract.h +++ b/Telegram/SourceFiles/mtproto/connection_abstract.h @@ -11,9 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/bytes.h" namespace MTP { - -bytes::vector ProtocolSecretFromPassword(const QString &password); - namespace internal { struct ConnectionOptions; diff --git a/Telegram/SourceFiles/mtproto/connection_tcp.cpp b/Telegram/SourceFiles/mtproto/connection_tcp.cpp index 978c08623e..156aa956fb 100644 --- a/Telegram/SourceFiles/mtproto/connection_tcp.cpp +++ b/Telegram/SourceFiles/mtproto/connection_tcp.cpp @@ -512,8 +512,7 @@ void TcpConnection::connectToServer( if (_proxy.type == ProxyData::Type::Mtproto) { _address = _proxy.host; _port = _proxy.port; - _protocol = Protocol::Create( - ProtocolSecretFromPassword(_proxy.password)); + _protocol = Protocol::Create(_proxy.secretFromMtprotoPassword()); DEBUG_LOG(("TCP Info: " "dc:%1 - Connecting to proxy '%2'"