Browse Source

sendback param of server_post_decrypt

details of errors
dev
BreakWa11 8 years ago
parent
commit
bd43069bcf
  1. 63
      shadowsocks/obfsplugin/auth.py
  2. 2
      shadowsocks/obfsplugin/plain.py
  3. 26
      shadowsocks/obfsplugin/verify.py
  4. 26
      shadowsocks/tcprelay.py

63
shadowsocks/obfsplugin/auth.py

@ -277,7 +277,7 @@ class auth_simple(verify_base):
def server_post_decrypt(self, buf): def server_post_decrypt(self, buf):
if self.raw_trans: if self.raw_trans:
return buf return (buf, False)
self.recv_buf += buf self.recv_buf += buf
out_buf = b'' out_buf = b''
while len(self.recv_buf) > 2: while len(self.recv_buf) > 2:
@ -287,7 +287,7 @@ class auth_simple(verify_base):
self.recv_buf = b'' self.recv_buf = b''
if self.decrypt_packet_num == 0: if self.decrypt_packet_num == 0:
logging.info('auth_simple: over size') logging.info('auth_simple: over size')
return b'E' return (b'E', False)
else: else:
raise Exception('server_post_decrype data error') raise Exception('server_post_decrype data error')
if length > len(self.recv_buf): if length > len(self.recv_buf):
@ -298,7 +298,7 @@ class auth_simple(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
if self.decrypt_packet_num == 0: if self.decrypt_packet_num == 0:
return b'E' return (b'E', False)
else: else:
raise Exception('server_post_decrype data uncorrect CRC32') raise Exception('server_post_decrype data uncorrect CRC32')
@ -309,7 +309,7 @@ class auth_simple(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
logging.info('auth_simple: too short') logging.info('auth_simple: too short')
return b'E' return (b'E', False)
utc_time = struct.unpack('<I', out_buf[:4])[0] utc_time = struct.unpack('<I', out_buf[:4])[0]
client_id = struct.unpack('<I', out_buf[4:8])[0] client_id = struct.unpack('<I', out_buf[4:8])[0]
connection_id = struct.unpack('<I', out_buf[8:12])[0] connection_id = struct.unpack('<I', out_buf[8:12])[0]
@ -319,7 +319,7 @@ class auth_simple(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
logging.info('auth_simple: wrong timestamp, time_dif %d, data %s' % (time_dif, binascii.hexlify(out_buf),)) logging.info('auth_simple: wrong timestamp, time_dif %d, data %s' % (time_dif, binascii.hexlify(out_buf),))
return b'E' return (b'E', False)
elif self.server_info.data.insert(client_id, connection_id): elif self.server_info.data.insert(client_id, connection_id):
self.has_recv_header = True self.has_recv_header = True
out_buf = out_buf[12:] out_buf = out_buf[12:]
@ -329,13 +329,13 @@ class auth_simple(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
logging.info('auth_simple: auth fail, data %s' % (binascii.hexlify(out_buf),)) logging.info('auth_simple: auth fail, data %s' % (binascii.hexlify(out_buf),))
return b'E' return (b'E', False)
self.recv_buf = self.recv_buf[length:] self.recv_buf = self.recv_buf[length:]
if out_buf: if out_buf:
self.server_info.data.update(self.client_id, self.connection_id) self.server_info.data.update(self.client_id, self.connection_id)
self.decrypt_packet_num += 1 self.decrypt_packet_num += 1
return out_buf return (out_buf, False)
class auth_sha1(verify_base): class auth_sha1(verify_base):
def __init__(self, method): def __init__(self, method):
@ -446,33 +446,33 @@ class auth_sha1(verify_base):
def server_post_decrypt(self, buf): def server_post_decrypt(self, buf):
if self.raw_trans: if self.raw_trans:
return buf return (buf, False)
self.recv_buf += buf self.recv_buf += buf
out_buf = b'' out_buf = b''
if not self.has_recv_header: if not self.has_recv_header:
if len(self.recv_buf) < 4: if len(self.recv_buf) < 4:
return b'' return (b'', False)
crc = struct.pack('<I', binascii.crc32(self.server_info.key) & 0xFFFFFFFF) crc = struct.pack('<I', binascii.crc32(self.server_info.key) & 0xFFFFFFFF)
if crc != self.recv_buf[:4]: if crc != self.recv_buf[:4]:
if self.method == 'auth_sha1': if self.method == 'auth_sha1':
return b'E' return (b'E', False)
else: else:
self.raw_trans = True self.raw_trans = True
return self.recv_buf return (self.recv_buf, False)
length = struct.unpack('>H', self.recv_buf[4:6])[0] length = struct.unpack('>H', self.recv_buf[4:6])[0]
if length > len(self.recv_buf): if length > len(self.recv_buf):
return b'' return (b'', False)
sha1data = hmac.new(self.server_info.recv_iv + self.server_info.key, self.recv_buf[:length - 10], hashlib.sha1).digest()[:10] sha1data = hmac.new(self.server_info.recv_iv + self.server_info.key, self.recv_buf[:length - 10], hashlib.sha1).digest()[:10]
if sha1data != self.recv_buf[length - 10:length]: if sha1data != self.recv_buf[length - 10:length]:
logging.error('auth_sha1 data uncorrect auth HMAC-SHA1') logging.error('auth_sha1 data uncorrect auth HMAC-SHA1')
return b'E' return (b'E', False)
pos = common.ord(self.recv_buf[6]) + 6 pos = common.ord(self.recv_buf[6]) + 6
out_buf = self.recv_buf[pos:length - 10] out_buf = self.recv_buf[pos:length - 10]
if len(out_buf) < 12: if len(out_buf) < 12:
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
logging.info('auth_sha1: too short') logging.info('auth_sha1: too short')
return b'E' return (b'E', False)
utc_time = struct.unpack('<I', out_buf[:4])[0] utc_time = struct.unpack('<I', out_buf[:4])[0]
client_id = struct.unpack('<I', out_buf[4:8])[0] client_id = struct.unpack('<I', out_buf[4:8])[0]
connection_id = struct.unpack('<I', out_buf[8:12])[0] connection_id = struct.unpack('<I', out_buf[8:12])[0]
@ -482,7 +482,7 @@ class auth_sha1(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
logging.info('auth_sha1: wrong timestamp, time_dif %d, data %s' % (time_dif, binascii.hexlify(out_buf),)) logging.info('auth_sha1: wrong timestamp, time_dif %d, data %s' % (time_dif, binascii.hexlify(out_buf),))
return b'E' return (b'E', False)
elif self.server_info.data.insert(client_id, connection_id): elif self.server_info.data.insert(client_id, connection_id):
self.has_recv_header = True self.has_recv_header = True
out_buf = out_buf[12:] out_buf = out_buf[12:]
@ -492,7 +492,7 @@ class auth_sha1(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
logging.info('auth_sha1: auth fail, data %s' % (binascii.hexlify(out_buf),)) logging.info('auth_sha1: auth fail, data %s' % (binascii.hexlify(out_buf),))
return b'E' return (b'E', False)
self.recv_buf = self.recv_buf[length:] self.recv_buf = self.recv_buf[length:]
self.has_recv_header = True self.has_recv_header = True
@ -503,7 +503,7 @@ class auth_sha1(verify_base):
self.recv_buf = b'' self.recv_buf = b''
if self.decrypt_packet_num == 0: if self.decrypt_packet_num == 0:
logging.info('auth_sha1: over size') logging.info('auth_sha1: over size')
return b'E' return (b'E', False)
else: else:
raise Exception('server_post_decrype data error') raise Exception('server_post_decrype data error')
if length > len(self.recv_buf): if length > len(self.recv_buf):
@ -514,7 +514,7 @@ class auth_sha1(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
if self.decrypt_packet_num == 0: if self.decrypt_packet_num == 0:
return b'E' return (b'E', False)
else: else:
raise Exception('server_post_decrype data uncorrect checksum') raise Exception('server_post_decrype data uncorrect checksum')
@ -525,7 +525,7 @@ class auth_sha1(verify_base):
if out_buf: if out_buf:
self.server_info.data.update(self.client_id, self.connection_id) self.server_info.data.update(self.client_id, self.connection_id)
self.decrypt_packet_num += 1 self.decrypt_packet_num += 1
return out_buf return (out_buf, False)
class obfs_auth_v2_data(object): class obfs_auth_v2_data(object):
def __init__(self): def __init__(self):
@ -686,26 +686,26 @@ class auth_sha1_v2(verify_base):
def server_post_decrypt(self, buf): def server_post_decrypt(self, buf):
if self.raw_trans: if self.raw_trans:
return buf return (buf, False)
self.recv_buf += buf self.recv_buf += buf
out_buf = b'' out_buf = b''
if not self.has_recv_header: if not self.has_recv_header:
if len(self.recv_buf) < 4: if len(self.recv_buf) < 4:
return b'' return (b'', False)
crc = struct.pack('<I', binascii.crc32(self.salt + self.server_info.key) & 0xFFFFFFFF) crc = struct.pack('<I', binascii.crc32(self.salt + self.server_info.key) & 0xFFFFFFFF)
if crc != self.recv_buf[:4]: if crc != self.recv_buf[:4]:
if self.method == 'auth_sha1_v2': if self.method == 'auth_sha1_v2':
return b'E' return (b'E', False)
else: else:
self.raw_trans = True self.raw_trans = True
return self.recv_buf return (self.recv_buf, False)
length = struct.unpack('>H', self.recv_buf[4:6])[0] length = struct.unpack('>H', self.recv_buf[4:6])[0]
if length > len(self.recv_buf): if length > len(self.recv_buf):
return b'' return (b'', False)
sha1data = hmac.new(self.server_info.recv_iv + self.server_info.key, self.recv_buf[:length - 10], hashlib.sha1).digest()[:10] sha1data = hmac.new(self.server_info.recv_iv + self.server_info.key, self.recv_buf[:length - 10], hashlib.sha1).digest()[:10]
if sha1data != self.recv_buf[length - 10:length]: if sha1data != self.recv_buf[length - 10:length]:
logging.error('auth_sha1_v2 data uncorrect auth HMAC-SHA1') logging.error('auth_sha1_v2 data uncorrect auth HMAC-SHA1')
return b'E' return (b'E', False)
pos = common.ord(self.recv_buf[6]) pos = common.ord(self.recv_buf[6])
if pos < 255: if pos < 255:
pos += 6 pos += 6
@ -716,7 +716,7 @@ class auth_sha1_v2(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
logging.info('auth_sha1_v2: too short') logging.info('auth_sha1_v2: too short')
return b'E' return (b'E', False)
client_id = struct.unpack('<Q', out_buf[:8])[0] client_id = struct.unpack('<Q', out_buf[:8])[0]
connection_id = struct.unpack('<I', out_buf[8:12])[0] connection_id = struct.unpack('<I', out_buf[8:12])[0]
if self.server_info.data.insert(client_id, connection_id): if self.server_info.data.insert(client_id, connection_id):
@ -728,10 +728,11 @@ class auth_sha1_v2(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
logging.info('auth_sha1_v2: auth fail, data %s' % (binascii.hexlify(out_buf),)) logging.info('auth_sha1_v2: auth fail, data %s' % (binascii.hexlify(out_buf),))
return b'E' return (b'E', False)
self.recv_buf = self.recv_buf[length:] self.recv_buf = self.recv_buf[length:]
self.has_recv_header = True self.has_recv_header = True
sendback = False
while len(self.recv_buf) > 2: while len(self.recv_buf) > 2:
length = struct.unpack('>H', self.recv_buf[:2])[0] length = struct.unpack('>H', self.recv_buf[:2])[0]
if length >= 8192 or length < 7: if length >= 8192 or length < 7:
@ -739,7 +740,7 @@ class auth_sha1_v2(verify_base):
self.recv_buf = b'' self.recv_buf = b''
if self.decrypt_packet_num == 0: if self.decrypt_packet_num == 0:
logging.info('auth_sha1_v2: over size') logging.info('auth_sha1_v2: over size')
return b'E' return (b'E', False)
else: else:
raise Exception('server_post_decrype data error') raise Exception('server_post_decrype data error')
if length > len(self.recv_buf): if length > len(self.recv_buf):
@ -750,7 +751,7 @@ class auth_sha1_v2(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
if self.decrypt_packet_num == 0: if self.decrypt_packet_num == 0:
return b'E' return (b'E', False)
else: else:
raise Exception('server_post_decrype data uncorrect checksum') raise Exception('server_post_decrype data uncorrect checksum')
@ -761,9 +762,11 @@ class auth_sha1_v2(verify_base):
pos = struct.unpack('>H', self.recv_buf[3:5])[0] + 2 pos = struct.unpack('>H', self.recv_buf[3:5])[0] + 2
out_buf += self.recv_buf[pos:length - 4] out_buf += self.recv_buf[pos:length - 4]
self.recv_buf = self.recv_buf[length:] self.recv_buf = self.recv_buf[length:]
if pos == length - 4:
sendback = True
if out_buf: if out_buf:
self.server_info.data.update(self.client_id, self.connection_id) self.server_info.data.update(self.client_id, self.connection_id)
self.decrypt_packet_num += 1 self.decrypt_packet_num += 1
return out_buf return (out_buf, sendback)

2
shadowsocks/obfsplugin/plain.py

@ -67,7 +67,7 @@ class plain(object):
return (buf, True, False) return (buf, True, False)
def server_post_decrypt(self, buf): def server_post_decrypt(self, buf):
return buf return (buf, False)
def client_udp_pre_encrypt(self, buf): def client_udp_pre_encrypt(self, buf):
return buf return buf

26
shadowsocks/obfsplugin/verify.py

@ -151,7 +151,7 @@ class verify_simple(verify_base):
def server_post_decrypt(self, buf): def server_post_decrypt(self, buf):
if self.raw_trans: if self.raw_trans:
return buf return (buf, False)
self.recv_buf += buf self.recv_buf += buf
out_buf = b'' out_buf = b''
while len(self.recv_buf) > 2: while len(self.recv_buf) > 2:
@ -160,7 +160,7 @@ class verify_simple(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
if self.decrypt_packet_num == 0: if self.decrypt_packet_num == 0:
return b'E' return (b'E', False)
else: else:
raise Exception('server_post_decrype data error') raise Exception('server_post_decrype data error')
if length > len(self.recv_buf): if length > len(self.recv_buf):
@ -170,7 +170,7 @@ class verify_simple(verify_base):
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
if self.decrypt_packet_num == 0: if self.decrypt_packet_num == 0:
return b'E' return (b'E', False)
else: else:
raise Exception('server_post_decrype data uncorrect CRC32') raise Exception('server_post_decrype data uncorrect CRC32')
@ -180,7 +180,7 @@ class verify_simple(verify_base):
if out_buf: if out_buf:
self.decrypt_packet_num += 1 self.decrypt_packet_num += 1
return out_buf return (out_buf, False)
class verify_deflate(verify_base): class verify_deflate(verify_base):
def __init__(self, method): def __init__(self, method):
@ -236,7 +236,7 @@ class verify_deflate(verify_base):
def server_post_decrypt(self, buf): def server_post_decrypt(self, buf):
if self.raw_trans: if self.raw_trans:
return buf return (buf, False)
self.recv_buf += buf self.recv_buf += buf
out_buf = b'' out_buf = b''
while len(self.recv_buf) > 2: while len(self.recv_buf) > 2:
@ -256,7 +256,7 @@ class verify_deflate(verify_base):
if out_buf: if out_buf:
self.decrypt_packet_num += 1 self.decrypt_packet_num += 1
return out_buf return (out_buf, False)
class verify_sha1(verify_base): class verify_sha1(verify_base):
def __init__(self, method): def __init__(self, method):
@ -303,26 +303,26 @@ class verify_sha1(verify_base):
def server_post_decrypt(self, buf): def server_post_decrypt(self, buf):
if self.raw_trans: if self.raw_trans:
return buf return (buf, False)
self.recv_buf += buf self.recv_buf += buf
out_buf = b'' out_buf = b''
if not self.has_recv_header: if not self.has_recv_header:
if len(self.recv_buf) < 2: if len(self.recv_buf) < 2:
return b'' return (b'', False)
if (ord(self.recv_buf[0]) & 0x10) != 0x10: if (ord(self.recv_buf[0]) & 0x10) != 0x10:
if self.method == 'verify_sha1': if self.method == 'verify_sha1':
logging.error('Not One-time authentication header') logging.error('Not One-time authentication header')
return b'E' return (b'E', False)
else: else:
self.raw_trans = True self.raw_trans = True
return self.recv_buf return (self.recv_buf, False)
head_size = self.get_head_size(self.recv_buf, 30) head_size = self.get_head_size(self.recv_buf, 30)
if len(self.recv_buf) < head_size + 10: if len(self.recv_buf) < head_size + 10:
return b'' return (b'', False)
sha1data = hmac.new(self.server_info.recv_iv + self.server_info.key, self.recv_buf[:head_size], hashlib.sha1).digest()[:10] sha1data = hmac.new(self.server_info.recv_iv + self.server_info.key, self.recv_buf[:head_size], hashlib.sha1).digest()[:10]
if sha1data != self.recv_buf[head_size:head_size + 10]: if sha1data != self.recv_buf[head_size:head_size + 10]:
logging.error('server_post_decrype data uncorrect auth HMAC-SHA1') logging.error('server_post_decrype data uncorrect auth HMAC-SHA1')
return b'E' return (b'E', False)
out_buf = to_bytes(chr(ord(self.recv_buf[0]) & 0xEF)) + self.recv_buf[1:head_size] out_buf = to_bytes(chr(ord(self.recv_buf[0]) & 0xEF)) + self.recv_buf[1:head_size]
self.recv_buf = self.recv_buf[head_size + 10:] self.recv_buf = self.recv_buf[head_size + 10:]
self.has_recv_header = True self.has_recv_header = True
@ -340,7 +340,7 @@ class verify_sha1(verify_base):
out_buf += data out_buf += data
self.recv_buf = self.recv_buf[length:] self.recv_buf = self.recv_buf[length:]
return out_buf return (out_buf, False)
def client_udp_pre_encrypt(self, buf): def client_udp_pre_encrypt(self, buf):
ret = self.pack_auth_data(buf) ret = self.pack_auth_data(buf)

26
shadowsocks/tcprelay.py

@ -364,7 +364,7 @@ class TCPRelayHandler(object):
return (host_post, 80) return (host_post, 80)
def _handel_protocol_error(self, client_address, ogn_data): def _handel_protocol_error(self, client_address, ogn_data):
logging.warn("Protocol ERROR, TCP ogn data %s from %s:%d" % (binascii.hexlify(ogn_data), client_address[0], client_address[1])) logging.warn("Protocol ERROR, TCP ogn data %s from %s:%d via port %d" % (binascii.hexlify(ogn_data), client_address[0], client_address[1], self._server._listen_port))
self._encrypt_correct = False self._encrypt_correct = False
#create redirect or disconnect by hash code #create redirect or disconnect by hash code
host, port = self._get_redirect_host(client_address, ogn_data) host, port = self._get_redirect_host(client_address, ogn_data)
@ -518,12 +518,17 @@ class TCPRelayHandler(object):
if not self._remote_udp: if not self._remote_udp:
if self._forbidden_iplist: if self._forbidden_iplist:
if common.to_str(sa[0]) in self._forbidden_iplist: if common.to_str(sa[0]) in self._forbidden_iplist:
if self._remote_address:
raise Exception('IP %s is in forbidden list, when connect to %s:%d via port %d' %
(common.to_str(sa[0]), self._remote_address[0], self._remote_address[1], self._server._listen_port))
raise Exception('IP %s is in forbidden list, reject' % raise Exception('IP %s is in forbidden list, reject' %
common.to_str(sa[0])) common.to_str(sa[0]))
if self._forbidden_portset: if self._forbidden_portset:
if sa[1] in self._forbidden_portset: if sa[1] in self._forbidden_portset:
raise Exception('Port %d is in forbidden list, reject' % if self._remote_address:
sa[1]) raise Exception('Port %d is in forbidden list, when connect to %s:%d via port %d' %
(sa[1], self._remote_address[0], self._remote_address[1], self._server._listen_port))
raise Exception('Port %d is in forbidden list, reject' % sa[1])
remote_sock = socket.socket(af, socktype, proto) remote_sock = socket.socket(af, socktype, proto)
self._remote_sock = remote_sock self._remote_sock = remote_sock
self._fd_to_handlers[remote_sock.fileno()] = self self._fd_to_handlers[remote_sock.fileno()] = self
@ -661,21 +666,20 @@ class TCPRelayHandler(object):
else: else:
data = obfs_decode[0] data = obfs_decode[0]
try: try:
newdata = self._protocol.server_post_decrypt(data) data, sendback = self._protocol.server_post_decrypt(data)
'''if data and not newdata: if sendback:
data = self._protocol.server_pre_encrypt(data) backdata = self._protocol.server_pre_encrypt('')
data = self._encryptor.encrypt(data) backdata = self._encryptor.encrypt(backdata)
data = self._obfs.server_encode(data) backdata = self._obfs.server_encode(backdata)
try: try:
self._write_to_sock(data, self._local_sock) self._write_to_sock(backdata, self._local_sock)
except Exception as e: except Exception as e:
shell.print_exception(e) shell.print_exception(e)
if self._config['verbose']: if self._config['verbose']:
traceback.print_exc() traceback.print_exc()
logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1]))
self.destroy() self.destroy()
return''' return
data = newdata
except Exception as e: except Exception as e:
shell.print_exception(e) shell.print_exception(e)
logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1]))

Loading…
Cancel
Save