Compare commits

..

6 Commits

Author SHA1 Message Date
Flowseal caa949bee0 fixes #1357 fixes #1354 2026-09-22 21:26:53 +03:00
Flowseal 3d59c813aa typo 2026-09-22 20:57:11 +03:00
Flowseal 70b982da2c Bump version 2026-09-19 22:51:47 +03:00
Flowseal 5226a409d4 clarify dialog message 2026-09-19 22:49:57 +03:00
Flowseal e519c4df4c use certifi for tls connections, fixes #1348 2026-09-19 22:48:25 +03:00
Flowseal a0605c7447 removed debug print closes #1350 2026-09-19 22:41:37 +03:00
7 changed files with 25 additions and 20 deletions
+4 -4
View File
@@ -4,8 +4,8 @@
# http://msdn.microsoft.com/en-us/library/ms646997.aspx # http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo( VSVersionInfo(
ffi=FixedFileInfo( ffi=FixedFileInfo(
filevers=(1, 10, 3, 0), filevers=(1, 10, 4, 0),
prodvers=(1, 10, 3, 0), prodvers=(1, 10, 4, 0),
mask=0x3f, mask=0x3f,
flags=0x0, flags=0x0,
OS=0x40004, OS=0x40004,
@@ -21,12 +21,12 @@ VSVersionInfo(
[ [
StringStruct(u'CompanyName', u'Flowseal'), StringStruct(u'CompanyName', u'Flowseal'),
StringStruct(u'FileDescription', u'Telegram Desktop WebSocket Bridge Proxy'), StringStruct(u'FileDescription', u'Telegram Desktop WebSocket Bridge Proxy'),
StringStruct(u'FileVersion', u'1.10.3.0'), StringStruct(u'FileVersion', u'1.10.4.0'),
StringStruct(u'InternalName', u'TgWsProxy'), StringStruct(u'InternalName', u'TgWsProxy'),
StringStruct(u'LegalCopyright', u'Copyright (c) Flowseal. MIT License.'), StringStruct(u'LegalCopyright', u'Copyright (c) Flowseal. MIT License.'),
StringStruct(u'OriginalFilename', u'TgWsProxy.exe'), StringStruct(u'OriginalFilename', u'TgWsProxy.exe'),
StringStruct(u'ProductName', u'TG WS Proxy'), StringStruct(u'ProductName', u'TG WS Proxy'),
StringStruct(u'ProductVersion', u'1.10.3.0'), StringStruct(u'ProductVersion', u'1.10.4.0'),
] ]
) )
] ]
+1 -1
View File
@@ -1,6 +1,6 @@
from .config import parse_dc_ip_list, proxy_config, coerce_domain_list from .config import parse_dc_ip_list, proxy_config, coerce_domain_list
from .utils import get_link_host, build_github_opener from .utils import get_link_host, build_github_opener
__version__ = "1.10.3" __version__ = "1.10.4"
__all__ = ["__version__", "get_link_host", "proxy_config", "parse_dc_ip_list", "build_github_opener", "coerce_domain_list"] __all__ = ["__version__", "get_link_host", "proxy_config", "parse_dc_ip_list", "build_github_opener", "coerce_domain_list"]
+5 -7
View File
@@ -1,5 +1,4 @@
import os import os
import ssl
import logging import logging
import base64 import base64
import struct import struct
@@ -8,6 +7,7 @@ import socket as _socket
from typing import List, Optional, Tuple from typing import List, Optional, Tuple
from .config import proxy_config from .config import proxy_config
from .utils import create_ssl_context
log = logging.getLogger('tg-mtproto-proxy') log = logging.getLogger('tg-mtproto-proxy')
@@ -21,9 +21,8 @@ _st_BBQ4s = struct.Struct('>BBQ4s')
_st_H = struct.Struct('>H') _st_H = struct.Struct('>H')
_st_Q = struct.Struct('>Q') _st_Q = struct.Struct('>Q')
_ssl_ctx = ssl.create_default_context() _ssl_ctx = create_ssl_context()
_ssl_ctx_fronting = ssl.create_default_context() _ssl_ctx_fronting = create_ssl_context(check_hostname=False)
_ssl_ctx_fronting.check_hostname = False
class WsHandshakeError(Exception): class WsHandshakeError(Exception):
def __init__(self, status_code: int, status_line: str, def __init__(self, status_code: int, status_line: str,
@@ -87,8 +86,7 @@ class RawWebSocket:
async def connect(host: str, domain: str, timeout: float = 10.0, async def connect(host: str, domain: str, timeout: float = 10.0,
path: str = '/apiws', *, path: str = '/apiws', *,
sni: Optional[str] = None, secure = True) -> 'RawWebSocket': sni: Optional[str] = None, secure = True) -> 'RawWebSocket':
ssl = _ssl_ctx_fronting if sni else _ssl_ctx ssl_context = _ssl_ctx_fronting if sni else _ssl_ctx
print(f"Connecting to {host} with secure={secure}, sni={sni}, path={path}")
if sni is None: if sni is None:
sni = domain sni = domain
@@ -97,7 +95,7 @@ class RawWebSocket:
( (
asyncio.open_connection( asyncio.open_connection(
host, 443, host, 443,
ssl=ssl, ssl=ssl_context,
server_hostname=sni, server_hostname=sni,
) )
if secure if secure
+9 -2
View File
@@ -140,6 +140,13 @@ class _PinnedHTTPSHandler(urllib.request.HTTPSHandler):
return super().https_open(req) return super().https_open(req)
def build_github_opener() -> urllib.request.OpenerDirector: def create_ssl_context(*, check_hostname: bool = True) -> ssl.SSLContext:
context = ssl.create_default_context(cafile=certifi.where()) context = ssl.create_default_context(cafile=certifi.where())
return urllib.request.build_opener(_PinnedHTTPSHandler(context=context)) context.load_default_certs()
context.check_hostname = check_hostname
return context
def build_github_opener() -> urllib.request.OpenerDirector:
return urllib.request.build_opener(
_PinnedHTTPSHandler(context=create_ssl_context()))
+2 -2
View File
@@ -47,10 +47,10 @@ _CFWORKER_TEST_DST = {
def _run_connectivity_test(cases: list, *, secure: bool = True) -> dict: def _run_connectivity_test(cases: list, *, secure: bool = True) -> dict:
import base64 import base64
from contextlib import nullcontext from contextlib import nullcontext
import ssl
import socket as _socket import socket as _socket
from proxy.utils import create_ssl_context
ctx = ssl.create_default_context() if secure else None ctx = create_ssl_context() if secure else None
port = 443 if secure else 80 port = 443 if secure else 80
results = {} results = {}
for dc, connect_host, sni_host, req_host, path in cases: for dc, connect_host, sni_host, req_host, path in cases:
+1 -1
View File
@@ -120,7 +120,7 @@
"dialog.restart_title": "Restart?", "dialog.restart_title": "Restart?",
"dialog.restart_body": "Settings saved.\n\nRestart the proxy now?", "dialog.restart_body": "Settings saved.\n\nRestart the proxy now?",
"dialog.already_running": "Application is already running.", "dialog.already_running": "Application is already running, check the tray",
"dialog.log_not_found": "Log file has not been created yet.", "dialog.log_not_found": "Log file has not been created yet.",
"dialog.ctk_missing": "customtkinter is not installed.", "dialog.ctk_missing": "customtkinter is not installed.",
"dialog.copy_ok": "Link copied to clipboard, send it in Telegram and click it:\n{url}", "dialog.copy_ok": "Link copied to clipboard, send it in Telegram and click it:\n{url}",
+2 -2
View File
@@ -32,7 +32,7 @@
"label.cf_custom_domain": "Свой домен", "label.cf_custom_domain": "Свой домен",
"label.cfworker_domains": "Cloudflare Worker домены (через запятую)", "label.cfworker_domains": "Cloudflare Worker домены (через запятую)",
"label.verbose": "Подробное логирование (verbose)", "label.verbose": "Подробное логирование (verbose)",
"label.no_secure": "Выключиь TLS для CF-прокси и CF-worker", "label.no_secure": "Выключить TLS для CF-прокси и CF-worker",
"label.buf_kb": "Буфер, КБ (по умолчанию 256)", "label.buf_kb": "Буфер, КБ (по умолчанию 256)",
"label.pool_size": "Пул WebSocket-сессий (по умолчанию 4)", "label.pool_size": "Пул WebSocket-сессий (по умолчанию 4)",
"label.log_max_mb": "Макс. размер лога, МБ (по умолчанию 5)", "label.log_max_mb": "Макс. размер лога, МБ (по умолчанию 5)",
@@ -120,7 +120,7 @@
"dialog.restart_title": "Перезапустить?", "dialog.restart_title": "Перезапустить?",
"dialog.restart_body": "Настройки сохранены.\n\nПерезапустить прокси сейчас?", "dialog.restart_body": "Настройки сохранены.\n\nПерезапустить прокси сейчас?",
"dialog.already_running": "Приложение уже запущено.", "dialog.already_running": "Приложение уже запущено, проверьте трей.",
"dialog.log_not_found": "Файл логов ещё не создан.", "dialog.log_not_found": "Файл логов ещё не создан.",
"dialog.ctk_missing": "customtkinter не установлен.", "dialog.ctk_missing": "customtkinter не установлен.",
"dialog.copy_ok": "Ссылка скопирована в буфер обмена, отправьте её в Telegram и нажмите по ней ЛКМ:\n{url}", "dialog.copy_ok": "Ссылка скопирована в буфер обмена, отправьте её в Telegram и нажмите по ней ЛКМ:\n{url}",