diff --git a/shadowsocks/common.py b/shadowsocks/common.py index 7f306ea..377f06a 100644 --- a/shadowsocks/common.py +++ b/shadowsocks/common.py @@ -204,7 +204,7 @@ def parse_header(data): elif addrtype == ADDRTYPE_HOST: if len(data) > 2: addrlen = ord(data[1]) - if len(data) >= 2 + addrlen: + if len(data) >= 4 + addrlen: dest_addr = data[2:2 + addrlen] dest_port = struct.unpack('>H', data[2 + addrlen:4 + addrlen])[0] diff --git a/shadowsocks/encrypt.py b/shadowsocks/encrypt.py index d3b2752..2494395 100644 --- a/shadowsocks/encrypt.py +++ b/shadowsocks/encrypt.py @@ -78,6 +78,7 @@ class Encryptor(object): self.iv_sent = False self.cipher_iv = b'' self.iv_buf = b'' + self.cipher_key = b'' self.decipher = None method = method.lower() self._method_info = self.get_method_info(method) @@ -109,6 +110,7 @@ class Encryptor(object): if op == 1: # this iv is for cipher not decipher self.cipher_iv = iv[:m[1]] + self.cipher_key = key return m[2](method, key, iv, op) def encrypt(self, buf): diff --git a/shadowsocks/local.py b/shadowsocks/local.py index 096283c..3b6523f 100755 --- a/shadowsocks/local.py +++ b/shadowsocks/local.py @@ -47,6 +47,8 @@ def main(): asyncdns.IPV6_CONNECTION_SUPPORT = False daemon.daemon_exec(config) + logging.info("local start with protocol[%s] password [%s] method [%s] obfs [%s] obfs_param [%s]" % + (config['protocol'], config['password'], config['method'], config['obfs'], config['obfs_param'])) try: logging.info("starting local at %s:%d" % diff --git a/shadowsocks/obfsplugin/http_simple.py b/shadowsocks/obfsplugin/http_simple.py index 9dce440..7c0cf99 100644 --- a/shadowsocks/obfsplugin/http_simple.py +++ b/shadowsocks/obfsplugin/http_simple.py @@ -90,7 +90,7 @@ class http_simple(plain.plain): def client_encode(self, buf): if self.has_sent_header: return buf - head_size = self.get_head_size(buf, 30) + head_size = len(self.server_info.iv) + self.server_info.head_len if len(buf) - head_size > 64: headlen = head_size + random.randint(0, 64) else: diff --git a/shadowsocks/tcprelay.py b/shadowsocks/tcprelay.py index 355b211..82ffb09 100644 --- a/shadowsocks/tcprelay.py +++ b/shadowsocks/tcprelay.py @@ -118,16 +118,22 @@ class TCPRelayHandler(object): server_info = obfs.server_info(server.obfs_data) server_info.host = config['server'] server_info.port = server._listen_port - server_info.tcp_mss = 1440 server_info.param = config['obfs_param'] + server_info.iv = self._encryptor.cipher_iv + server_info.key = self._encryptor.cipher_key + server_info.head_len = 30 + server_info.tcp_mss = 1440 self._obfs.set_server_info(server_info) self._protocol = obfs.obfs(config['protocol']) server_info = obfs.server_info(server.protocol_data) server_info.host = config['server'] server_info.port = server._listen_port - server_info.tcp_mss = 1440 server_info.param = '' + server_info.iv = self._encryptor.cipher_iv + server_info.key = self._encryptor.cipher_key + server_info.head_len = 30 + server_info.tcp_mss = 1440 self._protocol.set_server_info(server_info) self._redir_list = config.get('redirect', ["0.0.0.0:0"]) @@ -386,6 +392,18 @@ class TCPRelayHandler(object): traceback.print_exc() self.destroy() + def _get_head_size(self, buf, def_value): + if len(buf) < 2: + return def_value + head_type = ord(buf[0]) & 0xF + if head_type == 1: + return 7 + if head_type == 4: + return 19 + if head_type == 3: + return 4 + ord(buf[1]) + return def_value + def _handle_stage_addr(self, ogn_data, data): try: if self._is_local: @@ -439,6 +457,9 @@ class TCPRelayHandler(object): self._write_to_sock((b'\x05\x00\x00\x01' b'\x00\x00\x00\x00\x10\x10'), self._local_sock) + head_len = self._get_head_size(data, 30) + self._obfs.obfs.server_info.head_len = head_len + self._protocol.obfs.server_info.head_len = head_len if CLIENT_NEW_PROTOCOL: rnd_len = random.randint(1, 32) total_len = 7 + rnd_len + len(data)