From 5aacdd71068759f2b733fc21a941889c4e68184c Mon Sep 17 00:00:00 2001 From: Azat Arslanov Date: Fri, 15 Jun 2018 18:27:34 +0300 Subject: [PATCH 1/9] fix incorrect error message --- mtprotoproxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mtprotoproxy.py b/mtprotoproxy.py index 935eab6..7cede4b 100755 --- a/mtprotoproxy.py +++ b/mtprotoproxy.py @@ -322,7 +322,7 @@ class MTProtoCompactFrameStreamWriter(LayeredStreamWriterBase): LARGE_PKT_BORGER = 256 ** 3 if len(data) % 4 != 0: - print_err("BUG: MTProtoFrameStreamWriter attempted to send msg with len %d" % len(msg)) + print_err("BUG: MTProtoFrameStreamWriter attempted to send msg with len %d" % len(data)) return 0 len_div_four = len(data) // 4 From 0d0a334e8669f6c1e267153abdcc2f255db5ac2e Mon Sep 17 00:00:00 2001 From: Alexander Bersenev Date: Sun, 17 Jun 2018 03:27:13 +0500 Subject: [PATCH 2/9] fix flags --- mtprotoproxy.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mtprotoproxy.py b/mtprotoproxy.py index 935eab6..9db1ae1 100755 --- a/mtprotoproxy.py +++ b/mtprotoproxy.py @@ -377,9 +377,11 @@ class ProxyReqStreamWriter(LayeredStreamWriterBase): self.our_ip_port += int.to_bytes(my_port, 4, "little") self.out_conn_id = bytearray([random.randrange(0, 256) for i in range(8)]) + self.first_flag_byte = b"\x0a" + def write(self, msg): RPC_PROXY_REQ = b"\xee\xf1\xce\x36" - FLAGS = b"\x08\x10\x02\x40" + FLAGS = b"\x10\x02\x40" EXTRA_SIZE = b"\x18\x00\x00\x00" PROXY_TAG = b"\xae\x26\x1e\xdb" FOUR_BYTES_ALIGNER = b"\x00\x00\x00" @@ -389,11 +391,12 @@ class ProxyReqStreamWriter(LayeredStreamWriterBase): return 0 full_msg = bytearray() - full_msg += RPC_PROXY_REQ + FLAGS + self.out_conn_id + self.remote_ip_port - full_msg += self.our_ip_port + EXTRA_SIZE + PROXY_TAG + full_msg += RPC_PROXY_REQ + self.first_flag_byte + FLAGS + self.out_conn_id + full_msg += self.remote_ip_port + self.our_ip_port + EXTRA_SIZE + PROXY_TAG full_msg += bytes([len(AD_TAG)]) + AD_TAG + FOUR_BYTES_ALIGNER full_msg += msg + self.first_flag_byte = b"\x08" return self.upstream.write(full_msg) From 142c974333d3752211faeca1070338e7b860ad20 Mon Sep 17 00:00:00 2001 From: Alexander Bersenev Date: Sun, 17 Jun 2018 23:32:07 +0500 Subject: [PATCH 3/9] more work on flags --- mtprotoproxy.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mtprotoproxy.py b/mtprotoproxy.py index 23aa8e7..c52e830 100755 --- a/mtprotoproxy.py +++ b/mtprotoproxy.py @@ -377,11 +377,8 @@ class ProxyReqStreamWriter(LayeredStreamWriterBase): self.our_ip_port += int.to_bytes(my_port, 4, "little") self.out_conn_id = bytearray([random.randrange(0, 256) for i in range(8)]) - self.first_flag_byte = b"\x0a" - def write(self, msg): RPC_PROXY_REQ = b"\xee\xf1\xce\x36" - FLAGS = b"\x10\x02\x40" EXTRA_SIZE = b"\x18\x00\x00\x00" PROXY_TAG = b"\xae\x26\x1e\xdb" FOUR_BYTES_ALIGNER = b"\x00\x00\x00" @@ -390,8 +387,13 @@ class ProxyReqStreamWriter(LayeredStreamWriterBase): print_err("BUG: attempted to send msg with len %d" % len(msg)) return 0 + if msg.startswith(b"\x00" * 8): + FLAGS = b"\x0a\x10\x02\x40" + else: + FLAGS = b"\x08\x10\x02\x40" + full_msg = bytearray() - full_msg += RPC_PROXY_REQ + self.first_flag_byte + FLAGS + self.out_conn_id + full_msg += RPC_PROXY_REQ + FLAGS + self.out_conn_id full_msg += self.remote_ip_port + self.our_ip_port + EXTRA_SIZE + PROXY_TAG full_msg += bytes([len(AD_TAG)]) + AD_TAG + FOUR_BYTES_ALIGNER full_msg += msg From 0724f1403f23b07511c55a435302ce3e6bc2954c Mon Sep 17 00:00:00 2001 From: Alexander Bersenev Date: Mon, 18 Jun 2018 00:56:09 +0500 Subject: [PATCH 4/9] started to merge intermediate protocol, that may be found on the newest telegram X for Android --- mtprotoproxy.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/mtprotoproxy.py b/mtprotoproxy.py index c52e830..15f0b37 100755 --- a/mtprotoproxy.py +++ b/mtprotoproxy.py @@ -119,10 +119,11 @@ PREKEY_LEN = 32 KEY_LEN = 32 IV_LEN = 16 HANDSHAKE_LEN = 64 -MAGIC_VAL_POS = 56 +PROTO_TAG_POS = 56 DC_IDX_POS = 60 -MAGIC_VAL_TO_CHECK = b'\xef\xef\xef\xef' +PROTO_TAG_ABRIDGED = b"\xef\xef\xef\xef" +PROTO_TAG_INTERMEDIATE = b"\xee\xee\xee\xee" CBC_PADDING = 16 PADDING_FILLER = b"\x04\x00\x00\x00" @@ -420,19 +421,19 @@ async def handle_handshake(reader, writer): decrypted = decryptor.decrypt(handshake) - check_val = decrypted[MAGIC_VAL_POS:MAGIC_VAL_POS+4] - if check_val != MAGIC_VAL_TO_CHECK: + proto_tag = decrypted[PROTO_TAG_POS:PROTO_TAG_POS+4] + if proto_tag not in (PROTO_TAG_ABRIDGED, PROTO_TAG_INTERMEDIATE): continue dc_idx = int.from_bytes(decrypted[DC_IDX_POS:DC_IDX_POS+2], "little", signed=True) reader = CryptoWrappedStreamReader(reader, decryptor) writer = CryptoWrappedStreamWriter(writer, encryptor) - return reader, writer, user, dc_idx, enc_key + enc_iv + return reader, writer, proto_tag, user, dc_idx, enc_key + enc_iv return False -async def do_direct_handshake(dc_idx, dec_key_and_iv=None): +async def do_direct_handshake(proto_tag, dc_idx, dec_key_and_iv=None): RESERVED_NONCE_FIRST_CHARS = [b"\xef"] RESERVED_NONCE_BEGININGS = [b"\x48\x45\x41\x44", b"\x50\x4F\x53\x54", b"\x47\x45\x54\x20", b"\xee\xee\xee\xee"] @@ -469,7 +470,7 @@ async def do_direct_handshake(dc_idx, dec_key_and_iv=None): continue break - rnd[MAGIC_VAL_POS:MAGIC_VAL_POS+4] = MAGIC_VAL_TO_CHECK + rnd[PROTO_TAG_POS:PROTO_TAG_POS+4] = proto_tag if dec_key_and_iv: rnd[SKIP_LEN:SKIP_LEN+KEY_LEN+IV_LEN] = dec_key_and_iv[::-1] @@ -484,7 +485,7 @@ async def do_direct_handshake(dc_idx, dec_key_and_iv=None): enc_key, enc_iv = enc_key_and_iv[:KEY_LEN], enc_key_and_iv[KEY_LEN:] encryptor = create_aes_ctr(key=enc_key, iv=int.from_bytes(enc_iv, "big")) - rnd_enc = rnd[:MAGIC_VAL_POS] + encryptor.encrypt(rnd)[MAGIC_VAL_POS:] + rnd_enc = rnd[:PROTO_TAG_POS] + encryptor.encrypt(rnd)[PROTO_TAG_POS:] writer_tgt.write(rnd_enc) await writer_tgt.drain() @@ -676,15 +677,15 @@ async def handle_client(reader_clt, writer_clt): writer_clt.transport.abort() return - reader_clt, writer_clt, user, dc_idx, enc_key_and_iv = clt_data + reader_clt, writer_clt, proto_tag, user, dc_idx, enc_key_and_iv = clt_data update_stats(user, connects=1) if not USE_MIDDLE_PROXY: if FAST_MODE: - tg_data = await do_direct_handshake(dc_idx, dec_key_and_iv=enc_key_and_iv) + tg_data = await do_direct_handshake(proto_tag, dc_idx, dec_key_and_iv=enc_key_and_iv) else: - tg_data = await do_direct_handshake(dc_idx) + tg_data = await do_direct_handshake(proto_tag, dc_idx) else: cl_ip, cl_port = writer_clt.upstream.get_extra_info('peername')[:2] tg_data = await do_middleproxy_handshake(dc_idx, cl_ip, cl_port) From a6e39a66d160de5055232c35f5fd7fa6e85697be Mon Sep 17 00:00:00 2001 From: Alexander Bersenev Date: Mon, 18 Jun 2018 01:35:01 +0500 Subject: [PATCH 5/9] merge using intermediate protocol for middle proxy --- mtprotoproxy.py | 55 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/mtprotoproxy.py b/mtprotoproxy.py index 15f0b37..1bc05fd 100755 --- a/mtprotoproxy.py +++ b/mtprotoproxy.py @@ -314,16 +314,12 @@ class MTProtoCompactFrameStreamReader(LayeredStreamReaderBase): class MTProtoCompactFrameStreamWriter(LayeredStreamWriterBase): - def __init__(self, upstream, seq_no=0): - self.upstream = upstream - self.seq_no = seq_no - def write(self, data): SMALL_PKT_BORDER = 0x7f LARGE_PKT_BORGER = 256 ** 3 if len(data) % 4 != 0: - print_err("BUG: MTProtoFrameStreamWriter attempted to send msg with len %d" % len(data)) + print_err("BUG: MTProtoFrameStreamWriter attempted to send msg with len", len(data)) return 0 len_div_four = len(data) // 4 @@ -338,6 +334,24 @@ class MTProtoCompactFrameStreamWriter(LayeredStreamWriterBase): return 0 +class MTProtoIntermediateFrameStreamReader(LayeredStreamReaderBase): + async def read(self, buf_size): + msg_len_bytes = await self.upstream.readexactly(4) + msg_len = int.from_bytes(msg_len_bytes, "little") + + if msg_len > 0x80000000: + msg_len -= 0x80000000 + + data = await self.upstream.readexactly(msg_len) + + return data + + +class MTProtoIntermediateFrameStreamWriter(LayeredStreamWriterBase): + def write(self, data): + return self.upstream.write(int.to_bytes(len(data), 4, 'little') + data) + + class ProxyReqStreamReader(LayeredStreamReaderBase): async def read(self, msg): RPC_PROXY_ANS = b"\x0d\xda\x03\x44" @@ -360,7 +374,7 @@ class ProxyReqStreamReader(LayeredStreamReaderBase): class ProxyReqStreamWriter(LayeredStreamWriterBase): - def __init__(self, upstream, cl_ip, cl_port, my_ip, my_port): + def __init__(self, upstream, cl_ip, cl_port, my_ip, my_port, proto_tag): self.upstream = upstream if ":" not in cl_ip: @@ -378,6 +392,13 @@ class ProxyReqStreamWriter(LayeredStreamWriterBase): self.our_ip_port += int.to_bytes(my_port, 4, "little") self.out_conn_id = bytearray([random.randrange(0, 256) for i in range(8)]) + if proto_tag == PROTO_TAG_ABRIDGED: + self.last_flag_byte = b"\x40" + elif proto_tag == PROTO_TAG_INTERMEDIATE: + self.last_flag_byte = b"\x20" + else: + self.last_flag_byte = b"\x00" + def write(self, msg): RPC_PROXY_REQ = b"\xee\xf1\xce\x36" EXTRA_SIZE = b"\x18\x00\x00\x00" @@ -389,12 +410,12 @@ class ProxyReqStreamWriter(LayeredStreamWriterBase): return 0 if msg.startswith(b"\x00" * 8): - FLAGS = b"\x0a\x10\x02\x40" + flags = b"\x0a\x10\x02" + self.last_flag_byte else: - FLAGS = b"\x08\x10\x02\x40" + flags = b"\x08\x10\x02" + self.last_flag_byte full_msg = bytearray() - full_msg += RPC_PROXY_REQ + FLAGS + self.out_conn_id + full_msg += RPC_PROXY_REQ + flags + self.out_conn_id full_msg += self.remote_ip_port + self.our_ip_port + EXTRA_SIZE + PROXY_TAG full_msg += bytes([len(AD_TAG)]) + AD_TAG + FOUR_BYTES_ALIGNER full_msg += msg @@ -537,7 +558,7 @@ def set_bufsizes(sock, recv_buf=READ_BUF_SIZE, send_buf=WRITE_BUF_SIZE): sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, send_buf) -async def do_middleproxy_handshake(dc_idx, cl_ip, cl_port): +async def do_middleproxy_handshake(proto_tag, dc_idx, cl_ip, cl_port): START_SEQ_NO = -2 NONCE_LEN = 16 @@ -662,7 +683,7 @@ async def do_middleproxy_handshake(dc_idx, cl_ip, cl_port): if handshake_type != RPC_HANDSHAKE or handshake_peer_pid != SENDER_PID: return False - writer_tgt = ProxyReqStreamWriter(writer_tgt, cl_ip, cl_port, my_ip, my_port) + writer_tgt = ProxyReqStreamWriter(writer_tgt, cl_ip, cl_port, my_ip, my_port, proto_tag) reader_tgt = ProxyReqStreamReader(reader_tgt) return reader_tgt, writer_tgt @@ -688,7 +709,7 @@ async def handle_client(reader_clt, writer_clt): tg_data = await do_direct_handshake(proto_tag, dc_idx) else: cl_ip, cl_port = writer_clt.upstream.get_extra_info('peername')[:2] - tg_data = await do_middleproxy_handshake(dc_idx, cl_ip, cl_port) + tg_data = await do_middleproxy_handshake(proto_tag, dc_idx, cl_ip, cl_port) if not tg_data: writer_clt.transport.abort() @@ -709,8 +730,14 @@ async def handle_client(reader_clt, writer_clt): writer_clt.encryptor = FakeEncryptor() if USE_MIDDLE_PROXY: - reader_clt = MTProtoCompactFrameStreamReader(reader_clt) - writer_clt = MTProtoCompactFrameStreamWriter(writer_clt) + if proto_tag == PROTO_TAG_ABRIDGED: + reader_clt = MTProtoCompactFrameStreamReader(reader_clt) + writer_clt = MTProtoCompactFrameStreamWriter(writer_clt) + elif proto_tag == PROTO_TAG_INTERMEDIATE: + reader_clt = MTProtoIntermediateFrameStreamReader(reader_clt) + writer_clt = MTProtoIntermediateFrameStreamWriter(writer_clt) + else: + return async def connect_reader_to_writer(rd, wr, user): update_stats(user, curr_connects_x2=1) From dc9da63fbcb1839b2281a4f4aae9b4629c7fd78c Mon Sep 17 00:00:00 2001 From: Alexander Bersenev Date: Mon, 18 Jun 2018 18:33:48 +0500 Subject: [PATCH 6/9] support quickack flag --- mtprotoproxy.py | 61 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/mtprotoproxy.py b/mtprotoproxy.py index 1bc05fd..e11a510 100755 --- a/mtprotoproxy.py +++ b/mtprotoproxy.py @@ -168,7 +168,7 @@ class LayeredStreamWriterBase: def __init__(self, upstream): self.upstream = upstream - def write(self, data): + def write(self, data, extra={}): return self.upstream.write(data) def write_eof(self): @@ -230,7 +230,7 @@ class CryptoWrappedStreamWriter(LayeredStreamWriterBase): self.encryptor = encryptor self.block_size = block_size - def write(self, data): + def write(self, data, extra={}): if len(data) % self.block_size != 0: print_err("BUG: writing %d bytes not aligned to block size %d" % ( len(data), self.block_size)) @@ -280,7 +280,7 @@ class MTProtoFrameStreamWriter(LayeredStreamWriterBase): self.upstream = upstream self.seq_no = seq_no - def write(self, msg): + def write(self, msg, extra={}): len_bytes = int.to_bytes(len(msg) + 4 + 4 + 4, 4, "little") seq_bytes = int.to_bytes(self.seq_no, 4, "little", signed=True) self.seq_no += 1 @@ -299,7 +299,9 @@ class MTProtoCompactFrameStreamReader(LayeredStreamReaderBase): msg_len_bytes = await self.upstream.readexactly(1) msg_len = int.from_bytes(msg_len_bytes, "little") + extra = {"QUICKACK_FLAG": False} if msg_len >= 0x80: + extra["QUICKACK_FLAG"] = True msg_len -= 0x80 if msg_len == 0x7f: @@ -310,11 +312,11 @@ class MTProtoCompactFrameStreamReader(LayeredStreamReaderBase): data = await self.upstream.readexactly(msg_len) - return data + return data, extra class MTProtoCompactFrameStreamWriter(LayeredStreamWriterBase): - def write(self, data): + def write(self, data, extra={}): SMALL_PKT_BORDER = 0x7f LARGE_PKT_BORGER = 256 ** 3 @@ -327,8 +329,7 @@ class MTProtoCompactFrameStreamWriter(LayeredStreamWriterBase): if len_div_four < SMALL_PKT_BORDER: return self.upstream.write(bytes([len_div_four]) + data) elif len_div_four < LARGE_PKT_BORGER: - return self.upstream.write(b'\x7f' + bytes(int.to_bytes(len_div_four, 3, 'little')) + - data) + return self.upstream.write(b'\x7f' + int.to_bytes(len_div_four, 3, 'little') + data) else: print_err("Attempted to send too large pkt len =", len(data)) return 0 @@ -339,16 +340,18 @@ class MTProtoIntermediateFrameStreamReader(LayeredStreamReaderBase): msg_len_bytes = await self.upstream.readexactly(4) msg_len = int.from_bytes(msg_len_bytes, "little") + extra = {} if msg_len > 0x80000000: + extra["QUICKACK_FLAG"] = True msg_len -= 0x80000000 data = await self.upstream.readexactly(msg_len) - return data + return data, extra class MTProtoIntermediateFrameStreamWriter(LayeredStreamWriterBase): - def write(self, data): + def write(self, data, extra={}): return self.upstream.write(int.to_bytes(len(data), 4, 'little') + data) @@ -392,30 +395,41 @@ class ProxyReqStreamWriter(LayeredStreamWriterBase): self.our_ip_port += int.to_bytes(my_port, 4, "little") self.out_conn_id = bytearray([random.randrange(0, 256) for i in range(8)]) - if proto_tag == PROTO_TAG_ABRIDGED: - self.last_flag_byte = b"\x40" - elif proto_tag == PROTO_TAG_INTERMEDIATE: - self.last_flag_byte = b"\x20" - else: - self.last_flag_byte = b"\x00" + self.proto_tag = proto_tag - def write(self, msg): + def write(self, msg, extra={}): RPC_PROXY_REQ = b"\xee\xf1\xce\x36" EXTRA_SIZE = b"\x18\x00\x00\x00" PROXY_TAG = b"\xae\x26\x1e\xdb" FOUR_BYTES_ALIGNER = b"\x00\x00\x00" + FLAG_NOT_ENCRYPTED = 0x2 + FLAG_HAS_AD_TAG = 0x8 + FLAG_MAGIC = 0x1000 + FLAG_EXTMODE2 = 0x20000 + FLAG_INTERMEDIATE = 0x20000000 + FLAG_ABRIDGED = 0x40000000 + FLAG_QUICKACK = 0x80000000 + if len(msg) % 4 != 0: print_err("BUG: attempted to send msg with len %d" % len(msg)) return 0 + flags = FLAG_HAS_AD_TAG | FLAG_MAGIC | FLAG_EXTMODE2 + + if self.proto_tag == PROTO_TAG_ABRIDGED: + flags |= FLAG_ABRIDGED + elif self.proto_tag == PROTO_TAG_INTERMEDIATE: + flags |= FLAG_INTERMEDIATE + + if extra.get("QUICKACK_FLAG"): + flags |= FLAG_QUICKACK + if msg.startswith(b"\x00" * 8): - flags = b"\x0a\x10\x02" + self.last_flag_byte - else: - flags = b"\x08\x10\x02" + self.last_flag_byte + flags |= FLAG_NOT_ENCRYPTED full_msg = bytearray() - full_msg += RPC_PROXY_REQ + flags + self.out_conn_id + full_msg += RPC_PROXY_REQ + int.to_bytes(flags, 4, "little") + self.out_conn_id full_msg += self.remote_ip_port + self.our_ip_port + EXTRA_SIZE + PROXY_TAG full_msg += bytes([len(AD_TAG)]) + AD_TAG + FOUR_BYTES_ALIGNER full_msg += msg @@ -744,6 +758,11 @@ async def handle_client(reader_clt, writer_clt): try: while True: data = await rd.read(READ_BUF_SIZE) + if isinstance(data, tuple): + data, extra = data + else: + extra = {} + if not data: wr.write_eof() await wr.drain() @@ -751,7 +770,7 @@ async def handle_client(reader_clt, writer_clt): return else: update_stats(user, octets=len(data)) - wr.write(data) + wr.write(data, extra) await wr.drain() except (OSError, AttributeError, asyncio.streams.IncompleteReadError) as e: # print_err(e) From f51cdd780d169143be52e211b1e1cb707e9eb4a9 Mon Sep 17 00:00:00 2001 From: Alexander Bersenev Date: Mon, 18 Jun 2018 20:55:10 +0500 Subject: [PATCH 7/9] handle simple acks --- mtprotoproxy.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/mtprotoproxy.py b/mtprotoproxy.py index e11a510..b98d2cb 100755 --- a/mtprotoproxy.py +++ b/mtprotoproxy.py @@ -324,6 +324,9 @@ class MTProtoCompactFrameStreamWriter(LayeredStreamWriterBase): print_err("BUG: MTProtoFrameStreamWriter attempted to send msg with len", len(data)) return 0 + if extra.get("SIMPLE_ACK"): + return self.upstream.write(data[::-1]) + len_div_four = len(data) // 4 if len_div_four < SMALL_PKT_BORDER: @@ -352,28 +355,38 @@ class MTProtoIntermediateFrameStreamReader(LayeredStreamReaderBase): class MTProtoIntermediateFrameStreamWriter(LayeredStreamWriterBase): def write(self, data, extra={}): - return self.upstream.write(int.to_bytes(len(data), 4, 'little') + data) + if extra.get("SIMPLE_ACK"): + # fixme: it seems the connection on android closes here + return self.upstream.write(data) + else: + return self.upstream.write(int.to_bytes(len(data), 4, 'little') + data) class ProxyReqStreamReader(LayeredStreamReaderBase): async def read(self, msg): RPC_PROXY_ANS = b"\x0d\xda\x03\x44" RPC_CLOSE_EXT = b"\xa2\x34\xb6\x5e" + RPC_SIMPLE_ACK = b"\x9b\x40\xac\x3b" data = await self.upstream.read(1) if len(data) < 4: return b"" - ans_type, ans_flags, conn_id, conn_data = data[:4], data[4:8], data[8:16], data[16:] + ans_type = data[:4] if ans_type == RPC_CLOSE_EXT: return b"" - if ans_type != RPC_PROXY_ANS: - print_err("ans_type != RPC_PROXY_ANS", ans_type) - return b"" + if ans_type == RPC_PROXY_ANS: + ans_flags, conn_id, conn_data = data[4:8], data[8:16], data[16:] + return conn_data - return conn_data + if ans_type == RPC_SIMPLE_ACK: + conn_id, confirm = data[4:12], data[12:16] + return confirm, {"SIMPLE_ACK": True} + + print_err("unknown rpc ans type:", ans_type) + return b"" class ProxyReqStreamWriter(LayeredStreamWriterBase): From 0ec7fe9c6ba163588f33da410e78538cfc2f49a4 Mon Sep 17 00:00:00 2001 From: Alexander Bersenev Date: Tue, 19 Jun 2018 16:55:55 +0500 Subject: [PATCH 8/9] remove the note about fixme, it looks telegram fixed it from the server side --- mtprotoproxy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mtprotoproxy.py b/mtprotoproxy.py index b98d2cb..05c2a64 100755 --- a/mtprotoproxy.py +++ b/mtprotoproxy.py @@ -356,7 +356,6 @@ class MTProtoIntermediateFrameStreamReader(LayeredStreamReaderBase): class MTProtoIntermediateFrameStreamWriter(LayeredStreamWriterBase): def write(self, data, extra={}): if extra.get("SIMPLE_ACK"): - # fixme: it seems the connection on android closes here return self.upstream.write(data) else: return self.upstream.write(int.to_bytes(len(data), 4, 'little') + data) From 19b9da53f73cdb12614a987750653f568077c902 Mon Sep 17 00:00:00 2001 From: Alexander Bersenev Date: Tue, 19 Jun 2018 20:21:07 +0500 Subject: [PATCH 9/9] a possibility to specify a config path with args --- mtprotoproxy.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/mtprotoproxy.py b/mtprotoproxy.py index 05c2a64..f404666 100755 --- a/mtprotoproxy.py +++ b/mtprotoproxy.py @@ -11,6 +11,7 @@ import random import binascii import sys import re +import runpy try: @@ -59,21 +60,24 @@ except (ValueError, OSError): except ImportError: pass +if len(sys.argv) > 1: + config = runpy.run_path(sys.argv[1]) +else: + config = runpy.run_module("config") -import config -PORT = getattr(config, "PORT") -USERS = getattr(config, "USERS") +PORT = config["PORT"] +USERS = config["USERS"] # load advanced settings -PREFER_IPV6 = getattr(config, "PREFER_IPV6", socket.has_ipv6) +PREFER_IPV6 = config.get("PREFER_IPV6", socket.has_ipv6) # disables tg->client trafic reencryption, faster but less secure -FAST_MODE = getattr(config, "FAST_MODE", True) -STATS_PRINT_PERIOD = getattr(config, "STATS_PRINT_PERIOD", 600) -PROXY_INFO_UPDATE_PERIOD = getattr(config, "PROXY_INFO_UPDATE_PERIOD", 60*60*24) -READ_BUF_SIZE = getattr(config, "READ_BUF_SIZE", 16384) -WRITE_BUF_SIZE = getattr(config, "WRITE_BUF_SIZE", 65536) -CLIENT_KEEPALIVE = getattr(config, "CLIENT_KEEPALIVE", 60*30) -AD_TAG = bytes.fromhex(getattr(config, "AD_TAG", "")) +FAST_MODE = config.get("FAST_MODE", True) +STATS_PRINT_PERIOD = config.get("STATS_PRINT_PERIOD", 600) +PROXY_INFO_UPDATE_PERIOD = config.get("PROXY_INFO_UPDATE_PERIOD", 60*60*24) +READ_BUF_SIZE = config.get("READ_BUF_SIZE", 16384) +WRITE_BUF_SIZE = config.get("WRITE_BUF_SIZE", 65536) +CLIENT_KEEPALIVE = config.get("CLIENT_KEEPALIVE", 60*30) +AD_TAG = bytes.fromhex(config.get("AD_TAG", "")) TG_DATACENTER_PORT = 443