not redirect host to chn web
add auth_simple
This commit is contained in:
parent
126afea524
commit
0ba76b666d
2 changed files with 216 additions and 3 deletions
|
@ -23,7 +23,9 @@ import hashlib
|
|||
import logging
|
||||
import binascii
|
||||
import base64
|
||||
import time
|
||||
import datetime
|
||||
import random
|
||||
import struct
|
||||
import zlib
|
||||
|
||||
|
@ -38,9 +40,13 @@ def create_verify_obfs(method):
|
|||
def create_verify_deflate(method):
|
||||
return verify_deflate(method)
|
||||
|
||||
def create_auth_obfs(method):
|
||||
return auth_simple(method)
|
||||
|
||||
obfs_map = {
|
||||
'verify_simple': (create_verify_obfs,),
|
||||
'verify_deflate': (create_verify_deflate,),
|
||||
'auth_simple': (create_auth_obfs,),
|
||||
}
|
||||
|
||||
def match_begin(str1, str2):
|
||||
|
@ -49,7 +55,7 @@ def match_begin(str1, str2):
|
|||
return True
|
||||
return False
|
||||
|
||||
class sub_encode_obfs(object):
|
||||
class obfs_verify_data(object):
|
||||
def __init__(self):
|
||||
self.sub_obfs = None
|
||||
|
||||
|
@ -60,7 +66,7 @@ class verify_base(plain.plain):
|
|||
self.sub_obfs = None
|
||||
|
||||
def init_data(self):
|
||||
return sub_encode_obfs()
|
||||
return obfs_verify_data()
|
||||
|
||||
def set_server_info(self, server_info):
|
||||
try:
|
||||
|
@ -283,3 +289,210 @@ class verify_deflate(verify_base):
|
|||
self.decrypt_packet_num += 1
|
||||
return out_buf
|
||||
|
||||
class client_queue(object):
|
||||
def __init__(self, begin_id):
|
||||
self.front = begin_id
|
||||
self.back = begin_id
|
||||
self.alloc = {}
|
||||
self.enable = True
|
||||
self.last_update = time.time()
|
||||
|
||||
def update(self):
|
||||
self.last_update = time.time()
|
||||
|
||||
def is_active(self):
|
||||
return time.time() - self.last_update < 60 * 3
|
||||
|
||||
def re_enable(self, connection_id):
|
||||
self.enable = True
|
||||
self.alloc = {}
|
||||
self.front = connection_id
|
||||
self.back = connection_id
|
||||
|
||||
def insert(self, connection_id):
|
||||
self.update()
|
||||
if not self.enable:
|
||||
return False
|
||||
if connection_id < self.front:
|
||||
return False
|
||||
if not self.is_active():
|
||||
self.re_enable(connection_id)
|
||||
if connection_id > self.front + 0x4000:
|
||||
return False
|
||||
if connection_id in self.alloc:
|
||||
return False
|
||||
if self.back <= connection_id:
|
||||
self.back = connection_id + 1
|
||||
self.alloc[connection_id] = 1
|
||||
while (self.front in self.alloc) or self.front + 0x1000 < self.back:
|
||||
if self.front in self.alloc:
|
||||
del self.alloc[self.front]
|
||||
self.front += 1
|
||||
return True
|
||||
|
||||
class obfs_auth_data(object):
|
||||
def __init__(self):
|
||||
self.sub_obfs = None
|
||||
self.client_id = {}
|
||||
|
||||
def update(self, client_id, connection_id):
|
||||
if client_id in self.client_id:
|
||||
self.client_id[client_id].update()
|
||||
|
||||
def insert(self, client_id, connection_id):
|
||||
max_client = 16
|
||||
if client_id not in self.client_id or not self.client_id[client_id].enable:
|
||||
active = 0
|
||||
for c_id in self.client_id:
|
||||
if self.client_id[c_id].is_active():
|
||||
active += 1
|
||||
if active >= max_client:
|
||||
return False
|
||||
|
||||
if len(self.client_id) < max_client:
|
||||
if client_id not in self.client_id:
|
||||
self.client_id[client_id] = client_queue(connection_id)
|
||||
else:
|
||||
self.client_id[client_id].re_enable(connection_id)
|
||||
return self.client_id[client_id].insert(connection_id)
|
||||
keys = self.client_id.keys()
|
||||
random.shuffle(keys)
|
||||
for c_id in keys:
|
||||
if not self.client_id[c_id].is_active() and self.client_id[c_id].enable:
|
||||
if len(self.client_id) >= 256:
|
||||
del self.client_id[c_id]
|
||||
else:
|
||||
self.client_id[c_id].enable = False
|
||||
if client_id not in self.client_id:
|
||||
self.client_id[client_id] = client_queue(connection_id)
|
||||
else:
|
||||
self.client_id[client_id].re_enable(connection_id)
|
||||
return self.client_id[client_id].insert(connection_id)
|
||||
return False
|
||||
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
|
||||
|
||||
def init_data(self):
|
||||
return obfs_auth_data()
|
||||
|
||||
def pack_data(self, buf):
|
||||
if len(buf) == 0:
|
||||
return b''
|
||||
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 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_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:
|
||||
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
|
||||
|
||||
if (binascii.crc32(self.recv_buf[:length]) & 0xffffffff) != 0xffffffff:
|
||||
self.raw_trans = True
|
||||
self.recv_buf = b''
|
||||
if self.decrypt_packet_num == 0:
|
||||
return None
|
||||
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]
|
||||
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
|
||||
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:
|
||||
self.raw_trans = True
|
||||
self.recv_buf = b''
|
||||
if self.decrypt_packet_num == 0:
|
||||
return b'E'
|
||||
else:
|
||||
raise Exception('server_post_decrype 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''
|
||||
if self.decrypt_packet_num == 0:
|
||||
return b'E'
|
||||
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) < 8:
|
||||
self.raw_trans = True
|
||||
self.recv_buf = b''
|
||||
return b'E'
|
||||
client_id = struct.unpack('<I', out_buf[:4])[0]
|
||||
connection_id = struct.unpack('<I', out_buf[4:8])[0]
|
||||
if self.server_info.data.insert(client_id, connection_id):
|
||||
self.has_recv_header = True
|
||||
out_buf = out_buf[8:]
|
||||
self.client_id = client_id
|
||||
self.connection_id = connection_id
|
||||
else:
|
||||
self.raw_trans = True
|
||||
self.recv_buf = b''
|
||||
return b'E'
|
||||
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
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@ class TCPRelayHandler(object):
|
|||
|
||||
def _get_redirect_host(self, client_address, ogn_data):
|
||||
# test
|
||||
host_list = [(b"www.bing.com", 80), (b"www.microsoft.com", 80), (b"www.baidu.com", 443), (b"www.qq.com", 80), (b"www.csdn.net", 80), (b"1.2.3.4", 1000)]
|
||||
host_list = [(b"www.bing.com", 80), (b"www.microsoft.com", 80), (b"cloudfront.com", 80), (b"cloudflare.com", 80), (b"1.2.3.4", 1000), (b"0.0.0.0", 0)]
|
||||
hash_code = binascii.crc32(ogn_data)
|
||||
addrs = socket.getaddrinfo(client_address[0], client_address[1], 0, socket.SOCK_STREAM, socket.SOL_TCP)
|
||||
af, socktype, proto, canonname, sa = addrs[0]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue