@ -36,9 +36,6 @@ from shadowsocks import common, lru_cache
from shadowsocks . obfsplugin import plain
from shadowsocks . common import to_bytes , to_str , ord , chr
def create_auth_simple ( method ) :
return auth_simple ( method )
def create_auth_sha1 ( method ) :
return auth_sha1 ( method )
@ -46,7 +43,6 @@ def create_auth_sha1_v2(method):
return auth_sha1_v2 ( method )
obfs_map = {
' auth_simple ' : ( create_auth_simple , ) ,
' auth_sha1 ' : ( create_auth_sha1 , ) ,
' auth_sha1_compatible ' : ( create_auth_sha1 , ) ,
' auth_sha1_v2 ' : ( create_auth_sha1_v2 , ) ,
@ -137,7 +133,7 @@ class obfs_auth_data(object):
self . startup_time = int ( time . time ( ) - 30 ) & 0xFFFFFFFF
self . local_client_id = b ' '
self . connection_id = 0
self . set_max_client ( 1 6) # max active client count
self . set_max_client ( 64 ) # max active client count
def update ( self , client_id , connection_id ) :
if client_id in self . client_id :
@ -181,162 +177,6 @@ class obfs_auth_data(object):
else :
return self . client_id [ client_id ] . insert ( connection_id )
class auth_simple ( verify_base ) :
def __init__ ( self , method ) :
super ( auth_simple , self ) . __init__ ( method )
self . recv_buf = b ' '
self . unit_len = 8100
self . decrypt_packet_num = 0
self . raw_trans = False
self . has_sent_header = False
self . has_recv_header = False
self . client_id = 0
self . connection_id = 0
self . max_time_dif = 60 * 5 # time dif (second) setting
def init_data ( self ) :
return obfs_auth_data ( )
def set_server_info ( self , server_info ) :
self . server_info = server_info
try :
max_client = int ( server_info . protocol_param )
except :
max_client = 16
self . server_info . data . set_max_client ( max_client )
def pack_data ( self , buf ) :
rnd_data = os . urandom ( common . ord ( os . urandom ( 1 ) [ 0 ] ) % 16 )
data = common . chr ( len ( rnd_data ) + 1 ) + rnd_data + buf
data = struct . pack ( ' >H ' , len ( data ) + 6 ) + data
crc = ( 0xffffffff - binascii . crc32 ( data ) ) & 0xffffffff
data + = struct . pack ( ' <I ' , crc )
return data
def auth_data ( self ) :
utc_time = int ( time . time ( ) ) & 0xFFFFFFFF
if self . server_info . data . connection_id > 0xFF000000 :
self . server_info . data . local_client_id = b ' '
if not self . server_info . data . local_client_id :
self . server_info . data . local_client_id = os . urandom ( 4 )
logging . debug ( " local_client_id %s " % ( binascii . hexlify ( self . server_info . data . local_client_id ) , ) )
self . server_info . data . connection_id = struct . unpack ( ' <I ' , os . urandom ( 4 ) ) [ 0 ] & 0xFFFFFF
self . server_info . data . connection_id + = 1
return b ' ' . join ( [ struct . pack ( ' <I ' , utc_time ) ,
self . server_info . data . local_client_id ,
struct . pack ( ' <I ' , self . server_info . data . connection_id ) ] )
def client_pre_encrypt ( self , buf ) :
ret = b ' '
if not self . has_sent_header :
head_size = self . get_head_size ( buf , 30 )
datalen = min ( len ( buf ) , random . randint ( 0 , 31 ) + head_size )
ret + = self . pack_data ( self . auth_data ( ) + buf [ : datalen ] )
buf = buf [ datalen : ]
self . has_sent_header = True
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_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 > = 8192 or length < 7 :
self . raw_trans = True
self . recv_buf = b ' '
raise Exception ( ' client_post_decrypt data error ' )
if length > len ( self . recv_buf ) :
break
if ( binascii . crc32 ( self . recv_buf [ : length ] ) & 0xffffffff ) != 0xffffffff :
self . raw_trans = True
self . recv_buf = b ' '
raise Exception ( ' client_post_decrypt data uncorrect CRC32 ' )
pos = common . ord ( self . recv_buf [ 2 ] ) + 2
out_buf + = self . recv_buf [ pos : length - 4 ]
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_post_decrypt ( self , buf ) :
if self . raw_trans :
return ( buf , False )
self . recv_buf + = buf
out_buf = b ' '
while len ( self . recv_buf ) > 2 :
length = struct . unpack ( ' >H ' , self . recv_buf [ : 2 ] ) [ 0 ]
if length > = 8192 or length < 7 :
self . raw_trans = True
self . recv_buf = b ' '
if self . decrypt_packet_num == 0 :
logging . info ( ' auth_simple: over size ' )
return ( b ' E ' , False )
else :
raise Exception ( ' server_post_decrype data error ' )
if length > len ( self . recv_buf ) :
break
if ( binascii . crc32 ( self . recv_buf [ : length ] ) & 0xffffffff ) != 0xffffffff :
logging . info ( ' auth_simple: crc32 error, data %s ' % ( binascii . hexlify ( self . recv_buf [ : length ] ) , ) )
self . raw_trans = True
self . recv_buf = b ' '
if self . decrypt_packet_num == 0 :
return ( b ' E ' , False )
else :
raise Exception ( ' server_post_decrype data uncorrect CRC32 ' )
pos = common . ord ( self . recv_buf [ 2 ] ) + 2
out_buf + = self . recv_buf [ pos : length - 4 ]
if not self . has_recv_header :
if len ( out_buf ) < 12 :
self . raw_trans = True
self . recv_buf = b ' '
logging . info ( ' auth_simple: too short ' )
return ( b ' E ' , False )
utc_time = struct . unpack ( ' <I ' , out_buf [ : 4 ] ) [ 0 ]
client_id = struct . unpack ( ' <I ' , out_buf [ 4 : 8 ] ) [ 0 ]
connection_id = struct . unpack ( ' <I ' , out_buf [ 8 : 12 ] ) [ 0 ]
time_dif = common . int32 ( ( int ( time . time ( ) ) & 0xffffffff ) - utc_time )
if time_dif < - self . max_time_dif or time_dif > self . max_time_dif \
or common . int32 ( utc_time - self . server_info . data . startup_time ) < 0 :
self . raw_trans = True
self . recv_buf = b ' '
logging . info ( ' auth_simple: wrong timestamp, time_dif %d , data %s ' % ( time_dif , binascii . hexlify ( out_buf ) , ) )
return ( b ' E ' , False )
elif self . server_info . data . insert ( client_id , connection_id ) :
self . has_recv_header = True
out_buf = out_buf [ 12 : ]
self . client_id = client_id
self . connection_id = connection_id
else :
self . raw_trans = True
self . recv_buf = b ' '
logging . info ( ' auth_simple: auth fail, data %s ' % ( binascii . hexlify ( out_buf ) , ) )
return ( b ' E ' , False )
self . recv_buf = self . recv_buf [ length : ]
if out_buf :
self . server_info . data . update ( self . client_id , self . connection_id )
self . decrypt_packet_num + = 1
return ( out_buf , False )
class auth_sha1 ( verify_base ) :
def __init__ ( self , method ) :
super ( auth_sha1 , self ) . __init__ ( method )
@ -476,7 +316,7 @@ class auth_sha1(verify_base):
utc_time = struct . unpack ( ' <I ' , out_buf [ : 4 ] ) [ 0 ]
client_id = struct . unpack ( ' <I ' , out_buf [ 4 : 8 ] ) [ 0 ]
connection_id = struct . unpack ( ' <I ' , out_buf [ 8 : 12 ] ) [ 0 ]
time_dif = common . int32 ( ( int ( time . time ( ) ) & 0xffffffff ) - utc_time )
time_dif = common . int32 ( utc_time - ( int ( time . time ( ) ) & 0xffffffff ) )
if time_dif < - self . max_time_dif or time_dif > self . max_time_dif \
or common . int32 ( utc_time - self . server_info . data . startup_time ) < - self . max_time_dif / 2 :
self . raw_trans = True