From 36dc8f9463827f59cc99ed55b9b16cc8054d8272 Mon Sep 17 00:00:00 2001 From: breakwa11 Date: Fri, 9 Oct 2015 13:07:52 +0800 Subject: [PATCH] add verify_deflate --- shadowsocks/common.py | 2 +- shadowsocks/obfsplugin/verify_simple.py | 98 +++++++++++++++++++++++++ shadowsocks/tcprelay.py | 2 +- 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/shadowsocks/common.py b/shadowsocks/common.py index cc88d5d..2b11b9f 100644 --- a/shadowsocks/common.py +++ b/shadowsocks/common.py @@ -160,7 +160,7 @@ def pre_parse_header(data): 'encryption method') return None data = data[rand_data_size + 3:] - elif datatype == 0x88: + elif datatype == 0x88 or (~datatype & 0xff) == 0x88: if len(data) <= 7 + 7: return None data_size = struct.unpack('>H', data[1:3])[0] diff --git a/shadowsocks/obfsplugin/verify_simple.py b/shadowsocks/obfsplugin/verify_simple.py index f89e743..25bb55c 100644 --- a/shadowsocks/obfsplugin/verify_simple.py +++ b/shadowsocks/obfsplugin/verify_simple.py @@ -25,6 +25,7 @@ import binascii import base64 import datetime import struct +import zlib from shadowsocks.obfsplugin import plain from shadowsocks import common @@ -33,8 +34,12 @@ from shadowsocks.common import to_bytes, to_str, ord def create_verify_obfs(method): return verify_simple(method) +def create_verify_deflate(method): + return verify_deflate(method) + obfs = { 'verify_simple': (create_verify_obfs,), + 'verify_deflate': (create_verify_deflate,), } def match_begin(str1, str2): @@ -157,3 +162,96 @@ class verify_simple(plain.plain): self.decrypt_packet_num += 1 return out_buf +class verify_deflate(plain.plain): + def __init__(self, method): + self.method = method + self.recv_buf = b'' + self.unit_len = 32700 + self.decrypt_packet_num = 0 + self.raw_trans = False + + def pack_data(self, buf): + if len(buf) == 0: + return b'' + data = zlib.compress(buf) + data = struct.pack('>H', len(data)) + data[2:] + return data + + def client_pre_encrypt(self, buf): + ret = b'' + while len(buf) > self.unit_len: + ret += self.pack_data(buf[:self.unit_len]) + buf = buf[self.unit_len:] + ret += self.pack_data(buf) + return ret + + def client_encode(self, buf): + return buf + + def client_decode(self, buf): + # (buffer_to_recv, is_need_to_encode_and_send_back) + return (buf, False) + + def client_post_decrypt(self, buf): + if self.raw_trans: + return buf + self.recv_buf += buf + out_buf = b'' + while len(self.recv_buf) > 2: + length = struct.unpack('>H', self.recv_buf[:2])[0] + if length >= 32768: + self.raw_trans = True + self.recv_buf = b'' + if self.decrypt_packet_num == 0: + return None + else: + raise Exception('server_post_decrype data error') + if length > len(self.recv_buf): + break + + out_buf += zlib.decompress(b'x\x9c' + self.recv_buf[2:length]) + self.recv_buf = self.recv_buf[length:] + + if out_buf: + self.decrypt_packet_num += 1 + return out_buf + + def server_pre_encrypt(self, buf): + ret = b'' + while len(buf) > self.unit_len: + ret += self.pack_data(buf[:self.unit_len]) + buf = buf[self.unit_len:] + ret += self.pack_data(buf) + return ret + + def server_encode(self, buf): + return buf + + def server_decode(self, buf): + # (buffer_to_recv, is_need_decrypt, is_need_to_encode_and_send_back) + return (buf, True, False) + + def server_post_decrypt(self, buf): + if self.raw_trans: + return buf + self.recv_buf += buf + out_buf = b'' + while len(self.recv_buf) > 2: + length = struct.unpack('>H', self.recv_buf[:2])[0] + if length >= 32768: + self.raw_trans = True + self.recv_buf = b'' + if self.decrypt_packet_num == 0: + return None + else: + raise Exception('server_post_decrype data error') + if length > len(self.recv_buf): + break + + out_buf += zlib.decompress(b'x\x9c' + self.recv_buf[2:length]) + self.recv_buf = self.recv_buf[length:] + + if out_buf: + self.decrypt_packet_num += 1 + return out_buf + diff --git a/shadowsocks/tcprelay.py b/shadowsocks/tcprelay.py index 99ac9b3..2e42d59 100644 --- a/shadowsocks/tcprelay.py +++ b/shadowsocks/tcprelay.py @@ -390,7 +390,7 @@ class TCPRelayHandler(object): if self._is_local: header_result = parse_header(data) else: - if data is None or FORCE_NEW_PROTOCOL and common.ord(data[0]) != 0x88: + if data is None or FORCE_NEW_PROTOCOL and common.ord(data[0]) != 0x88 and (~common.ord(data[0]) & 0xff) != 0x88: data = self._handel_protocol_error(self._client_address, ogn_data) data = pre_parse_header(data) if data is None: