Browse Source

add verify_deflate

dev
breakwa11 9 years ago
parent
commit
36dc8f9463
  1. 2
      shadowsocks/common.py
  2. 98
      shadowsocks/obfsplugin/verify_simple.py
  3. 2
      shadowsocks/tcprelay.py

2
shadowsocks/common.py

@ -160,7 +160,7 @@ def pre_parse_header(data):
'encryption method') 'encryption method')
return None return None
data = data[rand_data_size + 3:] data = data[rand_data_size + 3:]
elif datatype == 0x88: elif datatype == 0x88 or (~datatype & 0xff) == 0x88:
if len(data) <= 7 + 7: if len(data) <= 7 + 7:
return None return None
data_size = struct.unpack('>H', data[1:3])[0] data_size = struct.unpack('>H', data[1:3])[0]

98
shadowsocks/obfsplugin/verify_simple.py

@ -25,6 +25,7 @@ import binascii
import base64 import base64
import datetime import datetime
import struct import struct
import zlib
from shadowsocks.obfsplugin import plain from shadowsocks.obfsplugin import plain
from shadowsocks import common from shadowsocks import common
@ -33,8 +34,12 @@ from shadowsocks.common import to_bytes, to_str, ord
def create_verify_obfs(method): def create_verify_obfs(method):
return verify_simple(method) return verify_simple(method)
def create_verify_deflate(method):
return verify_deflate(method)
obfs = { obfs = {
'verify_simple': (create_verify_obfs,), 'verify_simple': (create_verify_obfs,),
'verify_deflate': (create_verify_deflate,),
} }
def match_begin(str1, str2): def match_begin(str1, str2):
@ -157,3 +162,96 @@ class verify_simple(plain.plain):
self.decrypt_packet_num += 1 self.decrypt_packet_num += 1
return out_buf 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

2
shadowsocks/tcprelay.py

@ -390,7 +390,7 @@ class TCPRelayHandler(object):
if self._is_local: if self._is_local:
header_result = parse_header(data) header_result = parse_header(data)
else: 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 = self._handel_protocol_error(self._client_address, ogn_data)
data = pre_parse_header(data) data = pre_parse_header(data)
if data is None: if data is None:

Loading…
Cancel
Save