ZaStoGram_desktop/Telegram/SourceFiles/tests/test_proxy_wss_default.py
loop-uh 820a4f8006
All checks were successful
Desktop source guards / guards (push) Successful in 6s
Tunnel WSS through a Cloudflare Worker when a DC relay is down
2026-09-24 14:02:27 +03:00

312 lines
15 KiB
Python

from pathlib import Path
from session_private_sources import read_session_private_sources
SOURCE_DIR = Path(__file__).resolve().parents[1]
PROXY_DATA_H = SOURCE_DIR / "mtproto" / "proxy" / "data.h"
RUNTIME_PROXY_DATA_H = SOURCE_DIR / "mtproto" / "runtime" / "proxy_data.h"
PROXY_DATA_CPP = SOURCE_DIR / "mtproto" / "proxy" / "data.cpp"
WSS_SOCKET_H = SOURCE_DIR / "mtproto" / "proxy" / "wss" / "socket.h"
WSS_SOCKET_CPP = SOURCE_DIR / "mtproto" / "proxy" / "wss" / "socket.cpp"
CORE_SETTINGS_CPP = SOURCE_DIR / "core" / "core_settings.cpp"
CONNECTION_BOX_CPP = SOURCE_DIR / "boxes" / "connection_box.cpp"
CORE_SETTINGS_PROXY_CPP = SOURCE_DIR / "core" / "core_settings_proxy.cpp"
APPLICATION_CPP = SOURCE_DIR / "core" / "application.cpp"
PROXY_CHECK_H = SOURCE_DIR / "mtproto" / "proxy" / "check.h"
PROXY_CHECK_CPP = SOURCE_DIR / "mtproto" / "proxy" / "check.cpp"
TRANSPORT_POLICY_H = SOURCE_DIR / "mtproto" / "proxy" / "transport_policy.h"
TRANSPORT_POLICY_CPP = SOURCE_DIR / "mtproto" / "proxy" / "transport_policy.cpp"
SESSION_CPP = SOURCE_DIR / "mtproto" / "session" / "session.cpp"
SESSION_PRIVATE_CPP = SOURCE_DIR / "mtproto" / "session" / "private" / "session_private.cpp"
CONNECTION_TCP_CPP = SOURCE_DIR / "mtproto" / "transport" / "connection_tcp.cpp"
CMAKE_LISTS = SOURCE_DIR.parent / "CMakeLists.txt"
def test_wss_transport_is_the_stealth_default():
header = RUNTIME_PROXY_DATA_H.read_text(encoding="utf-8")
assert "ProxyTransport transport = ProxyTransport::Wss;" in header
def test_wss_transport_lives_in_proxy_module():
header = WSS_SOCKET_H.read_text(encoding="utf-8")
source = WSS_SOCKET_CPP.read_text(encoding="utf-8")
assert "struct WssRoute" in header
assert "class WssSocket final" in header
assert '#include "mtproto/proxy/wss/socket.h"' in source
def test_wss_keeps_tls_peer_verification_enabled():
header = WSS_SOCKET_H.read_text(encoding="utf-8")
source = WSS_SOCKET_CPP.read_text(encoding="utf-8")
assert "VerifyNone" not in source
assert "QSslSocket::VerifyPeer" in source
assert "_socket.setPeerVerifyName(_route.domain);" in source
assert "connectToRelayHost(" in source
assert "void connectToRelayHost();" in header
def test_persisted_transport_falls_back_to_wss():
source = CORE_SETTINGS_CPP.read_text(encoding="utf-8")
assert 'read(\n\t\t"mtproxy/transport",' in source
assert "int(MTP::ProxyTransport::Wss)))" in source
def test_route_via_wss_toggle_uses_transport_setting():
source = CONNECTION_BOX_CPP.read_text(encoding="utf-8")
assert 'u"Route via WSS (web, DC2/DC4 only)"_q' in source
assert "(saved.transport == MTP::ProxyTransport::Wss)" in source
assert "? MTP::ProxyTransport::Wss" in source
assert ": MTP::ProxyTransport::Tcp" in source
def test_default_local_proxy_port_matches_documented_telegram_proxy():
source = CORE_SETTINGS_PROXY_CPP.read_text(encoding="utf-8")
assert '#include "base/random.h"' not in source
assert "kDefaultProxyPort = 1353" in source
assert "GenerateDefaultProxyPort()" not in source
assert "def.port = kDefaultProxyPort;" in source
def test_wss_transport_policy_is_the_single_effective_entrypoint():
header = TRANSPORT_POLICY_H.read_text(encoding="utf-8")
source = TRANSPORT_POLICY_CPP.read_text(encoding="utf-8")
cmake = CMAKE_LISTS.read_text(encoding="utf-8")
assert '#include "mtproto/proxy/data.h"' in header
assert "[[nodiscard]] bool ProxyWssAllowed(" in header
assert "void NoteProxyWssRemoteClosed(" in header
assert "[[nodiscard]] ProxyTransport EffectiveProxyTransport(" in header
assert "[[nodiscard]] ProxyStealthOptions EffectiveProxyStealthOptions(" in header
assert "proxy.type == ProxyData::Type::None" in source
assert "proxy.type != ProxyData::Type::Socks5" in source
assert "proxy.type == ProxyData::Type::Mtproto" in source
assert "proxy.type != ProxyData::Type::Mtproto" not in source
assert "settings != ProxyData::Settings::Enabled" in source
assert "result.transport = EffectiveProxyTransport(" in source
assert "CompatStrictProxyStealthOptions(" in source
assert "mtproto/proxy/transport_policy.cpp" in cmake
assert "mtproto/proxy/transport_policy.h" in cmake
def test_wss_policy_allows_only_direct_or_nonlocal_socks_until_forbidden():
source = TRANSPORT_POLICY_CPP.read_text(encoding="utf-8")
allowed_body = function_body(source, "bool ProxyWssAllowed(")
assert "settings != ProxyData::Settings::Enabled" in allowed_body
assert "proxy.type == ProxyData::Type::None" in allowed_body
assert "proxy.type != ProxyData::Type::Socks5" in allowed_body
assert "IsLocalProxyEndpoint(proxy)" in allowed_body
assert "runtime->proxyServices().capabilities().wssAllowed(proxy)" in (
allowed_body)
assert "ProxyWssForbidden(proxy)" not in allowed_body
assert "ProxyData::Type::Http" not in allowed_body
def test_compat_strict_disables_stealth_for_mtproxy_and_local_tunnels():
header = RUNTIME_PROXY_DATA_H.read_text(encoding="utf-8")
proxy_header = PROXY_DATA_H.read_text(encoding="utf-8")
data = PROXY_DATA_CPP.read_text(encoding="utf-8")
source = TRANSPORT_POLICY_CPP.read_text(encoding="utf-8")
strict_body = function_body(
data,
"ProxyStealthOptions CompatStrictProxyStealthOptions(")
level_body = function_body(
data,
"ProxyStealthOptions ApplyProxyStealthLevel(")
effective_body = function_body(
source,
"ProxyStealthOptions EffectiveProxyStealthOptions(")
assert "enum class ProxyStealthLevel" in header
assert "CompatStrict" in header
assert "CompatModern" in header
assert "DpiAdaptiveHandshake" in header
assert "DpiAdaptiveData" in header
assert "Experimental" in header
assert "ProxyStealthLevel level" in header
assert "bool syntheticPsk = false;" in header
assert "ApplyProxyStealthLevel(" in proxy_header
assert "CompatStrictProxyStealthOptions(" in proxy_header
assert "result.transport = ProxyTransport::Tcp;" in strict_body
assert (
"result.clientHelloFragmentation = "
"ProxyClientHelloFragmentation::Off;" in strict_body)
assert "result.recordSizing = ProxyRecordSizing::Off;" in strict_body
assert "result.timing = ProxyTiming::Off;" in strict_body
assert "result.startupCover = ProxyStartupCover::Off;" in strict_body
assert "result.syntheticPsk = false;" in strict_body
assert "result.connectionPattern = ProxyConnectionPattern::Off;" in strict_body
assert "result.tlsProfile = ProxyTlsProfile::Auto;" in strict_body
assert "case ProxyStealthLevel::CompatStrict:" in level_body
assert "case ProxyStealthLevel::CompatModern:" in level_body
assert "case ProxyStealthLevel::DpiAdaptiveHandshake:" in level_body
assert "case ProxyStealthLevel::DpiAdaptiveData:" in level_body
assert "case ProxyStealthLevel::Experimental:" in level_body
assert "result.clientHelloFragmentation = ProxyClientHelloFragmentation::Off;" in level_body
assert "result.syntheticPsk = false;" in level_body
assert "result.recordSizing = ProxyRecordSizing::Conservative;" in level_body
assert "result.timing = ProxyTiming::Gentle;" in level_body
assert "result.startupCover = ProxyStartupCover::Soft;" in level_body
assert "proxy.type == ProxyData::Type::Mtproto" in effective_body
assert "result.transport = ProxyTransport::Tcp;" in effective_body
mtproxy_branch = effective_body.split(
"proxy.type == ProxyData::Type::Mtproto) {", 1)[1].split(
"if (settings == ProxyData::Settings::Enabled", 1)[0]
assert "result.level == ProxyStealthLevel::Experimental" not in mtproxy_branch
assert "ApplyProxyStealthLevel(" not in mtproxy_branch
assert "capability.syntheticPskAllowed" not in mtproxy_branch
assert "capability.fragmentationAllowed" not in mtproxy_branch
assert "IsLocalProxyEndpoint(proxy)" in effective_body
assert "!ProxyWssAllowed(runtime, proxy, settings)" in effective_body
assert "return CompatStrictProxyStealthOptions(std::move(result));" in effective_body
def test_persisted_transport_is_raw_and_not_mtproxy_clamped():
source = CORE_SETTINGS_CPP.read_text(encoding="utf-8")
assert "mtprotoProxyEnabled" not in source
assert "result.transport = MTP::ProxyTransport::Tcp;" not in source
assert "copy.transport = MTP::ProxyTransport::Tcp;" not in source
assert '"mtproxy/stealthLevel"' in source
assert '"mtproxy/syntheticPsk"' in source
assert 'write("mtproxy/transport", int(value.transport));' in source
assert 'write("mtproxy/stealthLevel", int(value.level));' in source
assert 'write("mtproxy/syntheticPsk", value.syntheticPsk ? 1 : 0);' in source
def test_enabling_mtproxy_does_not_rewrite_saved_transport():
source = APPLICATION_CPP.read_text(encoding="utf-8")
assert "DisableWssForMtprotoProxy" not in source
assert "setProxyStealthOptions(stealth)" not in source
def test_route_via_wss_checkbox_refreshes_after_proxy_change():
source = CONNECTION_BOX_CPP.read_text(encoding="utf-8")
assert "QPointer<Ui::Checkbox> _routeViaWss;" in source
assert "void refreshRouteViaWss();" in source
assert "void ProxiesBox::refreshRouteViaWss()" in source
assert "_routeViaWss->setChecked(" in source
assert "Ui::Checkbox::NotifyAboutChange::DontNotify" in source
assert "refreshRouteViaWss();" in source
def test_wss_dc_coverage_policy_is_centralized_and_soft():
header = TRANSPORT_POLICY_H.read_text(encoding="utf-8")
source = TRANSPORT_POLICY_CPP.read_text(encoding="utf-8")
assert "enum class WssDcCoverage" in header
assert "Unavailable" in header
assert "Official" in header
assert "Custom" in header
assert "[[nodiscard]] WssDcCoverage WssDcCoverageForDc(" in header
assert "[[nodiscard]] bool WssNeedsProxyRecommendation(" in header
assert '#include "mtproto/proxy/wss/socket.h"' in source
assert "WssCustomRoute(stealth)" in source
assert "WssOfficialRoute(protocolDcId)" in source
route_source = WSS_SOCKET_CPP.read_text(encoding="utf-8")
route_body = function_body(
route_source, "std::optional<WssRoute> OfficialRoute(")
assert "route.domain = (raw < 0)" in route_body
assert "protocolForFiles" not in route_body
assert "proxy.type == ProxyData::Type::None" in source
assert "stealth.transport == ProxyTransport::Wss" in source
assert "WssDcCoverage::Unavailable" in source
def test_wss_direct_fallback_requests_proxy_without_blocking():
session = read_session_private_sources()
assert '#include "mtproto/proxy/transport_policy.h"' in session
assert "WssNeedsProxyRecommendation(" in session
assert "MTP::ConnectionNotice::WssDirectFallback" in session
assert "setConnectionNotice(MTP::ConnectionNotice::None)" in session
assert "_sessionState.options->stealth.transport != ProxyTransport::Wss" in session
assert "kWaitForProxyTimeout" in session
def test_wss_remembers_working_relay_host_across_sockets():
header = WSS_SOCKET_H.read_text(encoding="utf-8")
source = WSS_SOCKET_CPP.read_text(encoding="utf-8")
connect_body = function_body(
source,
"void WssSocket::connectToHost(")
timed_out_body = function_body(source, "void WssSocket::timedOut()")
error_body = function_body(source, "void WssSocket::handleError(")
upgrade_body = function_body(source, "bool WssSocket::tryFinishUpgrade()")
# A blocked primary relay IP must not be re-tried first by every new
# socket: the working host is remembered process-wide with a TTL, the
# in-socket retry flips between hosts in both directions, and the
# session-level connect watchdog (which kills the socket before
# errorOccurred fires) records the stalled host too.
assert "bool _hostFlipped = false;" in header
assert "kRelayFallbackPreferenceTtl" in source
assert "Q_UNUSED(port);" in connect_body
# The official relay ignores the DC address; only the Worker tunnel
# needs it, to know which datacenter to open over TCP.
assert '_route.path = u"/apiws?dst="_q + address;' in connect_body
assert "if (_route.tunnel) {" in connect_body
assert "_usedFallback = PreferRelayFallback(_route);" in connect_body
assert "NoteRelayAttemptFailed(_route, _usedFallback);" in timed_out_body
assert "NoteRelayAttemptFailed(_route, _usedFallback);" in error_body
assert "_usedFallback = !_usedFallback;" in error_body
assert "NoteRelayUpgraded(_route, _usedFallback);" in upgrade_body
def test_wss_remote_closed_forbids_wss_for_that_proxy():
source = CONNECTION_TCP_CPP.read_text(encoding="utf-8")
error_body = function_body(source, "void TcpConnection::socketError(")
assert '#include "mtproto/proxy/transport_policy.h"' in source
# The local must not shadow AbstractConnection::error(qint32) which is
# called at the end of socketError().
assert "const auto proxyError = SocketProxyConnectionError(errorCode);" in error_body
assert "const auto error = " not in error_body
assert "const auto transport = _socket->transportName();" in error_body
assert "transport == u\"WSS\"_q" in error_body
assert "proxyError == ProxyConnectionError::RemoteClosed" in error_body
assert "NoteProxyWssRemoteClosed(_runtime, _proxy);" in error_body
assert "error(errorCode);" in error_body
assert ".transport = (transport == u\"WSS\"_q) ? transport : tag()," in error_body
def function_body(text: str, signature: str) -> str:
start = text.index(signature)
brace = text.index(" {\n", start) + 1
depth = 0
for index in range(brace, len(text)):
char = text[index]
if char == "{":
depth += 1
elif char == "}":
depth -= 1
if depth == 0:
return text[brace + 1:index]
raise AssertionError(f"body not found for {signature}")
if __name__ == "__main__":
test_wss_transport_is_the_stealth_default()
test_wss_transport_lives_in_proxy_module()
test_wss_keeps_tls_peer_verification_enabled()
test_persisted_transport_falls_back_to_wss()
test_route_via_wss_toggle_uses_transport_setting()
test_default_local_proxy_port_matches_documented_telegram_proxy()
test_wss_transport_policy_is_the_single_effective_entrypoint()
test_wss_policy_allows_only_direct_or_nonlocal_socks_until_forbidden()
test_compat_strict_disables_stealth_for_mtproxy_and_local_tunnels()
test_persisted_transport_is_raw_and_not_mtproxy_clamped()
test_enabling_mtproxy_does_not_rewrite_saved_transport()
test_route_via_wss_checkbox_refreshes_after_proxy_change()
test_wss_dc_coverage_policy_is_centralized_and_soft()
test_wss_direct_fallback_requests_proxy_without_blocking()
test_wss_remembers_working_relay_host_across_sockets()
test_wss_remote_closed_forbids_wss_for_that_proxy()