Exemplo n.º 1
0
 def pack_auth_data(self, auth_data, buf):
     if len(buf) == 0:
         return b''
     if len(buf) > 400:
         rnd_len = struct.unpack('<H', os.urandom(2))[0] % 512
     else:
         rnd_len = struct.unpack('<H', os.urandom(2))[0] % 1024
     data = auth_data
     data_len = 7 + 4 + 16 + 4 + len(buf) + rnd_len + 4
     data = data + struct.pack('<H', data_len) + struct.pack('<H', rnd_len)
     mac_key = self.server_info.iv + self.server_info.key
     uid = os.urandom(4)
     if b':' in to_bytes(self.server_info.protocol_param):
         try:
             items = to_bytes(self.server_info.protocol_param).split(b':')
             self.user_key = self.hashfunc(items[1]).digest()
             uid = struct.pack('<I', int(items[0]))
         except:
             pass
     if self.user_key is None:
         self.user_key = self.server_info.key
     encryptor = encrypt.Encryptor(
         to_bytes(base64.b64encode(self.user_key)) + self.salt,
         'aes-128-cbc', b'\x00' * 16)
     data = uid + encryptor.encrypt(data)[16:]
     data += hmac.new(mac_key, data, self.hashfunc).digest()[:4]
     check_head = os.urandom(1)
     check_head += hmac.new(mac_key, check_head, self.hashfunc).digest()[:6]
     data = check_head + data + os.urandom(rnd_len) + buf
     data += hmac.new(self.user_key, data, self.hashfunc).digest()[:4]
     return data
Exemplo n.º 2
0
 def client_udp_pre_encrypt(self, buf):
     if self.user_key is None:
         if b':' in to_bytes(self.server_info.protocol_param):
             try:
                 items = to_bytes(
                     self.server_info.protocol_param).split(':')
                 self.user_key = self.hashfunc(items[1]).digest()
                 self.user_id = struct.pack('<I', int(items[0]))
             except:
                 pass
         if self.user_key is None:
             self.user_id = os.urandom(4)
             self.user_key = self.server_info.key
     authdata = os.urandom(3)
     mac_key = self.server_info.key
     md5data = hmac.new(mac_key, authdata, self.hashfunc).digest()
     uid = struct.unpack('<I', self.user_id)[0] ^ struct.unpack(
         '<I', md5data[:4])[0]
     uid = struct.pack('<I', uid)
     rand_len = self.udp_rnd_data_len(md5data, self.random_client)
     encryptor = encrypt.Encryptor(
         to_bytes(base64.b64encode(self.user_key)) +
         to_bytes(base64.b64encode(md5data)), 'rc4')
     out_buf = encryptor.encrypt(buf)
     buf = out_buf + os.urandom(rand_len) + authdata + uid
     return buf + hmac.new(self.user_key, buf, self.hashfunc).digest()[:1]
Exemplo n.º 3
0
def decrypt_data(data):
    if g.config.encrypt_data:
        if isinstance(data, memoryview):
            data = data.tobytes()
        return encrypt.Encryptor(g.config.encrypt_password, g.config.encrypt_method).decrypt(data)
    else:
        return data
Exemplo n.º 4
0
 def handle(self):
     try:
         self.encryptor = encrypt.Encryptor(self.server.key,
                                            self.server.method)
         sock = self.connection
         iv_len = self.encryptor.iv_len()
         if iv_len:
             self.decrypt(sock.recv(iv_len))
         addrtype = ord(self.decrypt(sock.recv(1)))
         if addrtype == 1:
             addr = socket.inet_ntoa(self.decrypt(self.rfile.read(4)))
         elif addrtype == 3:
             addr = self.decrypt(
                 self.rfile.read(ord(self.decrypt(sock.recv(1)))))
         elif addrtype == 4:
             addr = socket.inet_ntop(socket.AF_INET6,
                                     self.decrypt(self.rfile.read(16)))
         else:
             # not supported
             logging.warn('addr_type not supported, maybe wrong password')
             return
         port = struct.unpack('>H', self.decrypt(self.rfile.read(2)))
         try:
             logging.info('connecting %s:%d' % (addr, port[0]))
             remote = socket.create_connection((addr, port[0]))
         except socket.error, e:
             # Connection refused
             logging.warn(e)
             return
         self.handle_tcp(sock, remote)
Exemplo n.º 5
0
 def __init__(self, server, fd_to_handlers, loop, local_sock, config,
              dns_resolver, is_local):
     self._server = server
     self._fd_to_handlers = fd_to_handlers
     self._loop = loop
     self._local_sock = local_sock
     self._remote_sock = None
     self._config = config
     self._dns_resolver = dns_resolver
     self._is_local = is_local
     self._stage = STAGE_INIT
     self._encryptor = encrypt.Encryptor(config['password'],
                                         config['method'])
     self._fastopen_connected = False
     self._data_to_write_to_local = []
     self._data_to_write_to_remote = []
     self._upstream_status = WAIT_STATUS_READING
     self._downstream_status = WAIT_STATUS_INIT
     self._client_address = local_sock.getpeername()[:2]
     self._remote_address = None
     if is_local:
         self._chosen_server = self._get_a_server()
     fd_to_handlers[local_sock.fileno()] = self
     local_sock.setblocking(False)
     local_sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
     loop.add(local_sock, eventloop.POLL_IN | eventloop.POLL_ERR)
     self.last_activity = 0
     self._update_activity()
Exemplo n.º 6
0
    def handle(self):
        try:
            self.encryptor = encrypt.Encryptor(KEY, METHOD)
            sock = self.connection
            sock.recv(262)
            sock.send("\x05\x00")
            data = self.rfile.read(4) or '\x00' * 4
            mode = ord(data[1])
            if mode != 1:
                logging.warn('mode != 1')
                return
            addrtype = ord(data[3])
            addr_to_send = data[3]
            print addrtype
            if addrtype == 1:
                addr_ip = self.rfile.read(4)
                addr = socket.inet_ntoa(addr_ip)
                addr_to_send += addr_ip
            elif addrtype == 3:
                addr_len = self.rfile.read(1)
                addr = self.rfile.read(ord(addr_len))
                addr_to_send += addr_len + addr
            elif addrtype == 4:
                addr_ip = self.rfile.read(16)
                addr = socket.inet_ntop(socket.AF_INET6, addr_ip)
                addr_to_send += addr_ip
            else:
                logging.warn('addr_type not support')
                # not support
                return
            addr_port = self.rfile.read(2)
            addr_to_send += addr_port
            port = struct.unpack('>H', addr_port)
            try:
                reply = "\x05\x00\x00\x01"
                reply += socket.inet_aton('0.0.0.0') + struct.pack(">H", 2222)
                self.wfile.write(reply)
                # reply immediately
                if '-6' in sys.argv[1:]:
                    remote = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
                    remote.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY,
                                      1)
                    remote.connect((SERVER, REMOTE_PORT, 0, 0))
                else:
                    remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    remote.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY,
                                      1)
                    remote.connect((SERVER, REMOTE_PORT))

                self.send_encrypt(remote, addr_to_send)
                logging.info('connecting %s:%d' % (addr, port[0]))
            except socket.error, e:
                logging.warn(e)
                return
            self.handle_tcp(sock, remote)
Exemplo n.º 7
0
 def _connect(self):
     self.connected = 0
     self.getKey()
     if self._sock is None:
         from connection import create_connection
         host, port = self.hxsServer.hostname, self.hxsServer.port
         self._sock = create_connection((host, port),
                                        self.timeout,
                                        parentproxy=self.parentproxy,
                                        tunnel=True)
         self.pskcipher = encrypt.Encryptor(self.PSK, self.method)
Exemplo n.º 8
0
    def pack_auth_data(self, auth_data, buf):
        data = auth_data
        data_len = 12 + 4 + 16 + 4
        data = data + (struct.pack('<H', self.server_info.overhead) +
                       struct.pack('<H', 0))
        mac_key = self.server_info.iv + self.server_info.key

        check_head = os.urandom(4)
        self.last_client_hash = hmac.new(mac_key, check_head,
                                         self.hashfunc).digest()
        check_head += self.last_client_hash[:8]

        if b':' in to_bytes(self.server_info.protocol_param):
            try:
                items = to_bytes(self.server_info.protocol_param).split(b':')
                self.user_key = items[1]
                uid = struct.pack('<I', int(items[0]))
            except:
                uid = os.urandom(4)
        else:
            uid = os.urandom(4)
        if self.user_key is None:
            self.user_key = self.server_info.key

        encryptor = encrypt.Encryptor(
            to_bytes(base64.b64encode(self.user_key)) + self.salt,
            'aes-128-cbc', b'\x00' * 16)

        uid = struct.unpack('<I', uid)[0] ^ struct.unpack(
            '<I', self.last_client_hash[8:12])[0]
        uid = struct.pack('<I', uid)
        data = uid + encryptor.encrypt(data)[16:]
        self.last_server_hash = hmac.new(self.user_key, data,
                                         self.hashfunc).digest()
        data = check_head + data + self.last_server_hash[:4]
        self.encryptor = encrypt.Encryptor(
            to_bytes(base64.b64encode(self.user_key)) +
            to_bytes(base64.b64encode(self.last_client_hash)), 'rc4')
        return data + self.pack_client_data(buf)
Exemplo n.º 9
0
 def client_udp_post_decrypt(self, buf):
     if len(buf) <= 8:
         return (b'', None)
     if hmac.new(self.user_key, buf[:-1],
                 self.hashfunc).digest()[:1] != buf[-1:]:
         return (b'', None)
     mac_key = self.server_info.key
     md5data = hmac.new(mac_key, buf[-8:-1], self.hashfunc).digest()
     rand_len = self.udp_rnd_data_len(md5data, self.random_server)
     encryptor = encrypt.Encryptor(
         to_bytes(base64.b64encode(self.user_key)) +
         to_bytes(base64.b64encode(md5data)), 'rc4')
     return encryptor.decrypt(buf[:-8 - rand_len])
Exemplo n.º 10
0
    def connect(self, address):
        self._address = address
        self.getKey()
        if self._sock is None:
            from connection import create_connection
            host, port = self.hxsServer.hostname, self.hxsServer.port
            self._sock = create_connection((host, port),
                                           self.timeout,
                                           parentproxy=self.parentproxy,
                                           tunnel=True)
            self.pskcipher = encrypt.Encryptor(self.PSK, self.method)
            self._rfile = self._sock.makefile('rb')
            self._header_sent = False
            self._header_received = False
        logger.debug('hxsocks send connect request')
        padding_len = random.randint(64, 255)
        pt = b''.join([
            struct.pack('>I', int(time.time())),
            chr(len(self._address[0])).encode('latin1'),
            self._address[0].encode(),
            struct.pack('>H', self._address[1]), b'\x00' * padding_len
        ])
        ct, mac = self.cipher.encrypt(pt)
        self._sock_sendall(
            self.pskcipher.encrypt(b''.join([
                chr(11).encode(), keys[self.serverid][0],
                struct.pack('>H', len(ct))
            ])) + ct + mac)

        resp_len = 2 if self.pskcipher.decipher else self.pskcipher.iv_len + 2
        data = self._rfile_read(resp_len)
        if not data:
            raise IOError(0, 'hxsocks Error: connection closed.')
        resp_len = self.pskcipher.decrypt(data)
        resp_len = struct.unpack('>H', resp_len)[0]

        resp = self.pskcipher.decrypt(self._rfile_read(resp_len))

        d = byte2int(resp) if resp else None
        if d == 0:
            logger.debug('hxsocks connected')
            self.readable = 1
            self.writeable = 1
            return
        elif d == 2:
            raise IOError(0, 'hxsocks Error: remote connect timed out. code 2')
        else:
            if self.serverid in keys:
                del keys[self.serverid]
            raise IOError(0, 'hxsocks Error: invalid shared key. code %d' % d)
Exemplo n.º 11
0
 def __init__(self):
     self.server = config['server']
     self.server_port = config['server_port']
     self.timeout = config['timeout']
     self.data_to_send = []
     self.state = STATE_INITIAL
     self.buf = ""
     self.supportedAuthMechs = [AUTHMECH_ANON, AUTHMECH_USERPASS]
     self.supportedAddrs = [ADDR_IPV4, ADDR_DOMAINNAME]
     self.enabledCommands = [CMD_CONNECT, CMD_UDPASSOC]
     self.peersock = None
     self.addressType = 0
     self.requestType = 0
     self.encryptor = encrypt.Encryptor(config['password'],
                                        config['method'])
Exemplo n.º 12
0
 def handle(self):
     KEY = self.server.config.get("password")
     METHOD = self.server.config.get("method")
     REMOTE_PORT = self.server.config.get("server_port")
     SERVER = self.server.config.get("server")
     try:
         self.encryptor = encrypt.Encryptor(KEY, METHOD)
         sock = self.connection
         sock.recv(262)
         sock.send("\x05\x00")
         data = self.rfile.read(4) or '\x00' * 4
         mode = ord(data[1])
         if mode != 1:
             logging.warn('mode != 1')
             return
         addrtype = ord(data[3])
         addr_to_send = data[3]
         if addrtype == 1:
             addr_ip = self.rfile.read(4)
             addr = socket.inet_ntoa(addr_ip)
             addr_to_send += addr_ip
         elif addrtype == 3:
             addr_len = self.rfile.read(1)
             addr = self.rfile.read(ord(addr_len))
             addr_to_send += addr_len + addr
         elif addrtype == 4:
             addr_ip = self.rfile.read(16)
             addr = socket.inet_ntop(socket.AF_INET6, addr_ip)
             addr_to_send += addr_ip
         else:
             logging.warn('addr_type not support')
             # not support
             return
         addr_port = self.rfile.read(2)
         addr_to_send += addr_port
         port = struct.unpack('>H', addr_port)
         try:
             reply = "\x05\x00\x00\x01"
             reply += socket.inet_aton('0.0.0.0') + struct.pack(">H", 2222)
             self.wfile.write(reply)
             # reply immediately
             remote = socket.create_connection((SERVER, REMOTE_PORT))
             self.send_encrypt(remote, addr_to_send)
             logging.debug('connecting %s:%d' % (addr, port[0]))
         except socket.error, e:
             logging.warn(e)
             return
         self.handle_tcp(sock, remote)
Exemplo n.º 13
0
    def __init__(self, server, fd_to_handlers, loop, local_sock, config,
                 dns_resolver, is_local):
        self._server = server
        self._fd_to_handlers = fd_to_handlers
        self._loop = loop
        self._local_sock = local_sock
        self._remote_sock = None
        self._config = config
        self._dns_resolver = dns_resolver

        # TCP Relay works as either sslocal or ssserver
        # if is_local, this is sslocal
        self._is_local = is_local
        self._stage = STAGE_INIT
        self._encryptor = encrypt.Encryptor(config['password'],
                                            config['method'])
        if 'one_time_auth' in config and config['one_time_auth']:
            self._ota_enable = True
        else:
            self._ota_enable = False
        self._ota_buff_head = b''
        self._ota_buff_data = b''
        self._ota_len = 0
        self._ota_chunk_idx = 0
        self._fastopen_connected = False
        self._data_to_write_to_local = []
        self._data_to_write_to_remote = []
        # upstream 数据从client->sserver->web,为WRITING输出到remote_sock,为READING读取local_sock
        self._upstream_status = WAIT_STATUS_READING
        # downstream 数据从web->ssserver->client,为WRITTING输出到local_sock,为READING读取remote_sock
        self._downstream_status = WAIT_STATUS_INIT
        self._client_address = local_sock.getpeername()[:2]
        self._remote_address = None
        if 'forbidden_ip' in config:
            self._forbidden_iplist = config['forbidden_ip']
        else:
            self._forbidden_iplist = None
        if is_local:
            self._chosen_server = self._get_a_server()
        fd_to_handlers[local_sock.fileno()] = self  # 注册socket
        local_sock.setblocking(False)
        local_sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
        # 添加到事件循环loop
        loop.add(local_sock, eventloop.POLL_IN | eventloop.POLL_ERR,
                 self._server)
        self.last_activity = 0  # 上一次活动的时间
        # 下面的函数就是更新这个变量
        self._update_activity()
Exemplo n.º 14
0
 def connect(self, address):
     self.__address = address
     sshost, ssport, ssmethod, sspassword = (self.ssServer.hostname,
                                             self.ssServer.port,
                                             self.ssServer.username.lower(),
                                             self.ssServer.password)
     from connection import create_connection
     if ssmethod.endswith('-auth'):
         self.__ota = True
         ssmethod = ssmethod[:-5]
     self._sock = create_connection((sshost, ssport),
                                    self.timeout,
                                    parentproxy=self.parentproxy,
                                    tunnel=True)
     self._rfile = self._sock.makefile('rb')
     self.crypto = encrypt.Encryptor(sspassword, ssmethod)
Exemplo n.º 15
0
 def server_udp_pre_encrypt(self, buf, uid):
     if uid in self.server_info.users:
         user_key = self.server_info.users[uid]
     else:
         uid = None
         if not self.server_info.users:
             user_key = self.server_info.key
         else:
             user_key = self.server_info.recv_iv
     authdata = os.urandom(7)
     mac_key = self.server_info.key
     md5data = hmac.new(mac_key, authdata, self.hashfunc).digest()
     rand_len = self.udp_rnd_data_len(md5data, self.random_server)
     encryptor = encrypt.Encryptor(
         to_bytes(base64.b64encode(user_key)) +
         to_bytes(base64.b64encode(md5data)), 'rc4')
     out_buf = encryptor.encrypt(buf)
     buf = out_buf + os.urandom(rand_len) + authdata
     return buf + hmac.new(user_key, buf, self.hashfunc).digest()[:1]
Exemplo n.º 16
0
 def handle(self):
     try:
         self.encryptor = encrypt.Encryptor(self.server.key,
                                            self.server.method)
         sock = self.connection
         sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
         iv_len = self.encryptor.iv_len()
         data = sock.recv(iv_len)
         if iv_len > 0 and not data:
             sock.close()
             return
         if iv_len:
             self.decrypt(data)
         data = sock.recv(1)
         if not data:
             sock.close()
             return
         addrtype = ord(self.decrypt(data))
         if addrtype == 1:
             addr = socket.inet_ntoa(self.decrypt(self.rfile.read(4)))
         elif addrtype == 3:
             addr = self.decrypt(
                 self.rfile.read(ord(self.decrypt(sock.recv(1)))))
         elif addrtype == 4:
             addr = socket.inet_ntop(socket.AF_INET6,
                                     self.decrypt(self.rfile.read(16)))
         else:
             # not supported
             logging.warn('addr_type not supported, maybe wrong password')
             return
         port = struct.unpack('>H', self.decrypt(self.rfile.read(2)))
         try:
             logging.info('connecting %s:%d' % (addr, port[0]))
             remote = socket.create_connection((addr, port[0]),
                                               timeout=config_timeout)
             remote.settimeout(config_timeout)
             remote.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
         except socket.error, e:
             # Connection refused
             logging.warn(e)
             return
         self.handle_tcp(sock, remote)
Exemplo n.º 17
0
 def server_udp_post_decrypt(self, buf):
     mac_key = self.server_info.key
     md5data = hmac.new(mac_key, buf[-8:-5], self.hashfunc).digest()
     uid = struct.unpack('<I', buf[-5:-1])[0] ^ struct.unpack(
         '<I', md5data[:4])[0]
     uid = struct.pack('<I', uid)
     if uid in self.server_info.users:
         user_key = self.server_info.users[uid]
     else:
         uid = None
         if not self.server_info.users:
             user_key = self.server_info.key
         else:
             user_key = self.server_info.recv_iv
     if hmac.new(user_key, buf[:-1],
                 self.hashfunc).digest()[:1] != buf[-1:]:
         return (b'', None)
     rand_len = self.udp_rnd_data_len(md5data, self.random_client)
     encryptor = encrypt.Encryptor(
         to_bytes(base64.b64encode(user_key)) +
         to_bytes(base64.b64encode(md5data)), 'rc4')
     out_buf = encryptor.decrypt(buf[:-8 - rand_len])
     return (out_buf, uid)
Exemplo n.º 18
0
    def connect(self, address):
        self.__address = address
        sshost, ssport, ssmethod, sspassword = (self.ssServer.hostname,
                                                self.ssServer.port,
                                                self.ssServer.username.lower(),
                                                self.ssServer.password)
        from connection import create_connection

        self._sock = create_connection((sshost, ssport),
                                       self.timeout,
                                       parentproxy=self.parentproxy,
                                       tunnel=True)
        self._rfile = self._sock.makefile('rb')
        self.aead = encrypt.is_aead(ssmethod)
        self.crypto = encrypt.Encryptor(sspassword, ssmethod)

        self._connected = False

        # start forward thread here
        self._thread = Thread(target=self.forward_tcp,
                              args=(self._socketpair_b, self._sock,
                                    self.crypto, 60))
        self._thread.start()
Exemplo n.º 19
0
 def getKey(self):
     with newkey_lock[self.serverid]:
         if self.serverid not in keys:
             for _ in range(2):
                 logger.debug('hxsocks getKey')
                 host, port, usn, psw = (self.hxsServer.hostname,
                                         self.hxsServer.port,
                                         self.hxsServer.username,
                                         self.hxsServer.password)
                 if self._sock is None:
                     logger.debug('hxsocks connect')
                     from connection import create_connection
                     self._sock = create_connection(
                         (host, port),
                         self.timeout,
                         parentproxy=self.parentproxy,
                         tunnel=True)
                     self.pskcipher = encrypt.Encryptor(
                         self.PSK, self.method)
                 acipher = ECC(self.pskcipher.key_len)
                 pubk = acipher.get_pub_key()
                 logger.debug('hxsocks send key exchange request')
                 ts = struct.pack('>I', int(time.time()))
                 data = chr(10) + ts + chr(len(pubk)) + pubk + hmac.new(
                     psw.encode(), ts + pubk + usn.encode(),
                     hashlib.sha256).digest()
                 self._sock.sendall(self.pskcipher.encrypt(data))
                 fp = self._sock.makefile('rb', 0)
                 resp_len = 1 if self.pskcipher.decipher else self.pskcipher.iv_len + 1
                 resp = ord(self.pskcipher.decrypt(fp.read(resp_len)))
                 if resp == 0:
                     logger.debug('hxsocks read key exchange respond')
                     pklen = ord(self.pskcipher.decrypt(fp.read(1)))
                     server_key = self.pskcipher.decrypt(fp.read(pklen))
                     auth = self.pskcipher.decrypt(fp.read(32))
                     pklen = ord(self.pskcipher.decrypt(fp.read(1)))
                     server_cert = self.pskcipher.decrypt(fp.read(pklen))
                     rlen = ord(self.pskcipher.decrypt(fp.read(1)))
                     r = self.pskcipher.decrypt(fp.read(rlen))
                     s = self.pskcipher.decrypt(fp.read(rlen))
                     # TODO: ask user if a certificate should be accepted or not.
                     if host not in known_hosts:
                         logger.info(
                             'hxs: server %s new cert %s saved.' %
                             (host,
                              hashlib.sha256(server_cert).hexdigest()[:8]))
                         with open('./.hxs_known_hosts/' + host + '.cert',
                                   'wb') as f:
                             f.write(server_cert)
                             known_hosts[host] = server_cert
                     elif known_hosts[host] != server_cert:
                         logger.error(
                             'hxs: server %s certificate mismatch! PLEASE CHECK!'
                         )
                         raise OSError(0, 'hxs: bad certificate')
                     if auth == hmac.new(psw.encode(),
                                         pubk + server_key + usn.encode(),
                                         hashlib.sha256).digest():
                         if ECC.verify_with_pub_key(server_cert, auth, r,
                                                    s):
                             shared_secret = acipher.get_dh_key(server_key)
                             keys[self.serverid] = (
                                 hashlib.md5(pubk).digest(), shared_secret)
                             logger.debug('hxs key exchange success')
                             return
                         else:
                             logger.error(
                                 'hxs getKey Error: server auth failed, bad signature'
                             )
                     else:
                         logger.error(
                             'hxs getKey Error: server auth failed, bad username or password'
                         )
                 else:
                     fp.read(ord(self.pskcipher.decrypt(fp.read(1))))
                     logger.error(
                         'hxs getKey Error. bad password or timestamp.')
             else:
                 raise IOError(0, 'hxs getKey Error')
Exemplo n.º 20
0
    def handle(self):
        self.remote = None
        try:
            self.encryptor = encrypt.Encryptor(self.server.key, self.server.method, servermode=True)
            sock = self.connection
            # sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
            iv_len = self.encryptor.iv_len()
            if iv_len:
                try:
                    self.decrypt(self.rfile.read(iv_len))
                except ValueError:
                    logging.warn('server %s:%d iv reused, possible replay attrack. closing...' % self.server.server_address)
                    return
            data = sock.recv(1)
            if not data:
                return
            addrtype = ord(self.decrypt(data))
            if addrtype == 1:
                addr = socket.inet_ntoa(self.decrypt(self.rfile.read(4)))
            elif addrtype == 3:
                addr = self.decrypt(self.rfile.read(ord(self.decrypt(self.rfile.read(1)))))
            elif addrtype == 4:
                addr = socket.inet_ntop(socket.AF_INET6, self.decrypt(self.rfile.read(16)))
            else:  # not supported
                logging.warn('server %s:%d addr_type not supported, maybe wrong password' % self.server.server_address)
                return
            port = struct.unpack('>H', self.decrypt(self.rfile.read(2)))[0]
            if self.server.aports and port not in self.server.aports:
                logging.info('server %s:%d port %d not allowed' % (self.server.server_address[0], self.server.server_address[1], port))
                return
            if self._request_is_loopback((addr, port)):
                logging.info('server %s:%d localhost access denied' % self.server.server_address)
                return

            try:
                logging.info('server %s:%d request %s:%d from %s:%d' % (self.server.server_address[0], self.server.server_address[1],
                             addr, port, self.client_address[0], self.client_address[1]))
                data = self.decrypt(sock.recv(self.bufsize))

                if self.server.reverse:
                    if data.startswith((b'GET', b'POST', b'HEAD', b'PUT', b'DELETE', b'TRACE', b'OPTIONS', b'PATCH', b'CONNECT')) and b'HTTP/1' in data and b'\r\n' in data:
                        data = data.decode('latin1')
                        data = data.replace('\r\n', '\r\nss-realip: %s:%s\r\nss-client: %s\r\n' % (self.client_address[0], self.client_address[1], self.server.key), 1)
                        self.remote = create_connection(self.server.reverse, timeout=10)
                    else:
                        a = 'CONNECT %s:%d HTTP/1.0\r\nss-realip: %s:%s\r\nss-client: %s\r\n\r\n' % (addr, port, self.client_address[0], self.client_address[1], self.server.key)
                        self.remote = create_connection(self.server.reverse, timeout=10)
                        self.remote.sendall(a.encode('latin1'))
                        remoterfile = self.remote.makefile('rb', 0)
                        d = remoterfile.readline()
                        while d not in (b'\r\n', b'\n', b'\r'):
                            if not d:
                                raise IOError(0, 'remote closed')
                            d = remoterfile.readline()
                if not self.remote:
                    self.remote = create_connection((addr, port), timeout=10)
                self.remote.sendall(data)
                # self.remote.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
            except (IOError, OSError) as e:  # Connection refused
                logging.warn('server %s:%d %r on connecting %s:%d' % (self.server.server_address[0], self.server.server_address[1], e, addr, port))
                return
            self.handle_tcp(sock, self.remote)
        except socket.error as e:
            logging.warn('server %s:%d %r' % (self.server.server_address[0], self.server.server_address[1], e))
Exemplo n.º 21
0
    def server_post_decrypt(self, buf):
        if self.raw_trans:
            return (buf, False)
        self.recv_buf += buf
        out_buf = b''
        sendback = False

        if not self.has_recv_header:
            if len(self.recv_buf) >= 12 or len(self.recv_buf) in [7, 8]:
                recv_len = min(len(self.recv_buf), 12)
                mac_key = self.server_info.recv_iv + self.server_info.key
                md5data = hmac.new(mac_key, self.recv_buf[:4],
                                   self.hashfunc).digest()
                if md5data[:recv_len - 4] != self.recv_buf[4:recv_len]:
                    return self.not_match_return(self.recv_buf)

            if len(self.recv_buf) < 12 + 24:
                return (b'', False)

            self.last_client_hash = md5data

            self.user_key = self.server_info.key
            md5data = hmac.new(self.user_key, self.recv_buf[12:12 + 20],
                               self.hashfunc).digest()
            if md5data[:4] != self.recv_buf[32:36]:
                logging.error(
                    '%s data uncorrect auth HMAC-MD5 from %s:%d, data %s' %
                    (self.no_compatible_method, self.server_info.client,
                     self.server_info.client_port,
                     binascii.hexlify(self.recv_buf)))
                if len(self.recv_buf) < 36:
                    return (b'', False)
                return self.not_match_return(self.recv_buf)

            self.last_server_hash = md5data
            encryptor = encrypt.Encryptor(
                to_bytes(base64.b64encode(self.user_key)) + self.salt,
                'aes-128-cbc')
            head = encryptor.decrypt(
                b'\x00' * 16 + self.recv_buf[16:32] +
                b'\x00')  # need an extra byte or recv empty
            self.client_over_head = struct.unpack('<H', head[12:14])[0]

            utc_time = struct.unpack('<I', head[:4])[0]
            client_id = struct.unpack('<I', head[4:8])[0]
            connection_id = struct.unpack('<I', head[8:12])[0]
            time_dif = common.int32(utc_time - (int(time.time()) & 0xffffffff))
            if time_dif < -self.max_time_dif or time_dif > self.max_time_dif:
                logging.info('%s: wrong timestamp, time_dif %d, data %s' %
                             (self.no_compatible_method, time_dif,
                              binascii.hexlify(head)))
                return self.not_match_return(self.recv_buf)
            elif self.server_info.data.insert(self.user_id, client_id,
                                              connection_id):
                self.has_recv_header = True
                self.client_id = client_id
                self.connection_id = connection_id
            else:
                logging.info(
                    '%s: auth fail, data %s' %
                    (self.no_compatible_method, binascii.hexlify(out_buf)))
                return self.not_match_return(self.recv_buf)

            self.encryptor = encrypt.Encryptor(
                to_bytes(base64.b64encode(self.user_key)) +
                to_bytes(base64.b64encode(self.last_client_hash)), 'rc4')
            self.recv_buf = self.recv_buf[36:]
            self.has_recv_header = True
            sendback = True

        while len(self.recv_buf) > 4:
            mac_key = self.user_key + struct.pack('<I', self.recv_id)
            data_len = struct.unpack('<H',
                                     self.recv_buf[:2])[0] ^ struct.unpack(
                                         '<H', self.last_client_hash[14:16])[0]
            rand_len = self.rnd_data_len(data_len, self.last_client_hash,
                                         self.random_client)
            length = data_len + rand_len
            if length >= 4096:
                self.raw_trans = True
                self.recv_buf = b''
                if self.recv_id == 0:
                    logging.info(self.no_compatible_method + ': over size')
                    return (b'E' * 2048, False)
                else:
                    raise Exception('server_post_decrype data error')

            if length + 4 > len(self.recv_buf):
                break

            client_hash = hmac.new(mac_key, self.recv_buf[:length + 2],
                                   self.hashfunc).digest()
            if client_hash[:2] != self.recv_buf[length + 2:length + 4]:
                logging.info('%s: checksum error, data %s' %
                             (self.no_compatible_method,
                              binascii.hexlify(self.recv_buf[:length])))
                self.raw_trans = True
                self.recv_buf = b''
                if self.recv_id == 0:
                    return (b'E' * 2048, False)
                else:
                    raise Exception(
                        'server_post_decrype data uncorrect checksum')

            self.recv_id = (self.recv_id + 1) & 0xFFFFFFFF
            pos = 2
            if data_len > 0 and rand_len > 0:
                pos = 2 + self.rnd_start_pos(rand_len, self.random_client)
            out_buf += self.encryptor.decrypt(self.recv_buf[pos:data_len +
                                                            pos])
            self.last_client_hash = client_hash
            self.recv_buf = self.recv_buf[length + 4:]
            if data_len == 0:
                sendback = True

        if out_buf:
            self.server_info.data.update(self.user_id, self.client_id,
                                         self.connection_id)
        return (out_buf, sendback)
Exemplo n.º 22
0
    def server_post_decrypt(self, buf):
        if self.raw_trans:
            return (buf, False)
        self.recv_buf += buf
        out_buf = b''
        sendback = False

        if not self.has_recv_header:
            if len(self.recv_buf) >= 7 or len(self.recv_buf) in [2, 3]:
                recv_len = min(len(self.recv_buf), 7)
                mac_key = self.server_info.recv_iv + self.server_info.key
                sha1data = hmac.new(mac_key, self.recv_buf[:1],
                                    self.hashfunc).digest()[:recv_len - 1]
                if sha1data != self.recv_buf[1:recv_len]:
                    return self.not_match_return(self.recv_buf)

            if len(self.recv_buf) < 31:
                return (b'', False)
            sha1data = hmac.new(mac_key, self.recv_buf[7:27],
                                self.hashfunc).digest()[:4]
            if sha1data != self.recv_buf[27:31]:
                logging.error(
                    '%s data uncorrect auth HMAC-SHA1 from %s:%d, data %s' %
                    (self.no_compatible_method, self.server_info.client,
                     self.server_info.client_port,
                     binascii.hexlify(self.recv_buf)))
                if len(self.recv_buf) < 31 + self.extra_wait_size:
                    return (b'', False)
                return self.not_match_return(self.recv_buf)

            self.user_key = self.server_info.key
            encryptor = encrypt.Encryptor(
                to_bytes(base64.b64encode(self.user_key)) + self.salt,
                'aes-128-cbc')
            head = encryptor.decrypt(
                b'\x00' * 16 + self.recv_buf[11:27] +
                b'\x00')  # need an extra byte or recv empty
            length = struct.unpack('<H', head[12:14])[0]
            if len(self.recv_buf) < length:
                return (b'', False)

            utc_time = struct.unpack('<I', head[:4])[0]
            client_id = struct.unpack('<I', head[4:8])[0]
            connection_id = struct.unpack('<I', head[8:12])[0]
            rnd_len = struct.unpack('<H', head[14:16])[0]
            if hmac.new(self.user_key, self.recv_buf[:length - 4],
                        self.hashfunc).digest()[:4] != self.recv_buf[length -
                                                                     4:length]:
                logging.info('%s: checksum error, data %s' %
                             (self.no_compatible_method,
                              binascii.hexlify(self.recv_buf[:length])))
                return self.not_match_return(self.recv_buf)
            time_dif = common.int32(utc_time - (int(time.time()) & 0xffffffff))
            if time_dif < -self.max_time_dif or time_dif > self.max_time_dif:
                logging.info('%s: wrong timestamp, time_dif %d, data %s' %
                             (self.no_compatible_method, time_dif,
                              binascii.hexlify(head)))
                return self.not_match_return(self.recv_buf)
            elif self.server_info.data.insert(self.user_id, client_id,
                                              connection_id):
                self.has_recv_header = True
                out_buf = self.recv_buf[31 + rnd_len:length - 4]
                self.client_id = client_id
                self.connection_id = connection_id
            else:
                logging.info(
                    '%s: auth fail, data %s' %
                    (self.no_compatible_method, binascii.hexlify(out_buf)))
                return self.not_match_return(self.recv_buf)
            self.recv_buf = self.recv_buf[length:]
            self.has_recv_header = True
            sendback = True

        while len(self.recv_buf) > 4:
            mac_key = self.user_key + struct.pack('<I', self.recv_id)
            mac = hmac.new(mac_key, self.recv_buf[:2],
                           self.hashfunc).digest()[:2]
            if mac != self.recv_buf[2:4]:
                self.raw_trans = True
                logging.info(self.no_compatible_method + ': wrong crc')
                if self.recv_id == 0:
                    logging.info(self.no_compatible_method + ': wrong crc')
                    return (b'E' * 2048, False)
                else:
                    raise Exception('server_post_decrype data error')
            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.recv_id == 0:
                    logging.info(self.no_compatible_method + ': over size')
                    return (b'E' * 2048, False)
                else:
                    raise Exception('server_post_decrype data error')
            if length > len(self.recv_buf):
                break

            if hmac.new(mac_key, self.recv_buf[:length - 4],
                        self.hashfunc).digest()[:4] != self.recv_buf[length -
                                                                     4:length]:
                logging.info('%s: checksum error, data %s' %
                             (self.no_compatible_method,
                              binascii.hexlify(self.recv_buf[:length])))
                self.raw_trans = True
                self.recv_buf = b''
                if self.recv_id == 0:
                    return (b'E' * 2048, False)
                else:
                    raise Exception(
                        'server_post_decrype data uncorrect checksum')

            self.recv_id = (self.recv_id + 1) & 0xFFFFFFFF
            pos = common.ord(self.recv_buf[4])
            if pos < 255:
                pos += 4
            else:
                pos = struct.unpack('<H', self.recv_buf[5:7])[0] + 4
            out_buf += self.recv_buf[pos:length - 4]
            self.recv_buf = self.recv_buf[length:]
            if pos == length - 4:
                sendback = True

        if out_buf:
            self.server_info.data.update(self.user_id, self.client_id,
                                         self.connection_id)
        return (out_buf, sendback)
Exemplo n.º 23
0
def decrypt_data(data):
    if g.config.encrypt_data:
        return encrypt.Encryptor(g.config.encrypt_password, g.config.encrypt_method).decrypt(data)
    else:
        return data
Exemplo n.º 24
0
 def handle(self):
     try:
         encryptor = encrypt.Encryptor(config_password, config_method)
         sock = self.connection
         sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
         data = sock.recv(262)
         if not data:
             sock.close()
             return
         if len(data) < 3:
             return
         method = ord(data[2])
         if method == 2:
             logging.warn(
                 'client tries to use username/password auth, prete'
                 'nding the password is OK')
             sock.send('\x05\x02')
             try:
                 ver_ulen = sock.recv(2)
                 ulen = ord(ver_ulen[1])
                 if ulen:
                     username = sock.recv(ulen)
                     assert (ulen == len(username))
                 plen = ord(sock.recv(1))
                 if plen:
                     _password = sock.recv(plen)
                     assert (plen == len(_password))
                 sock.send('\x01\x00')
             except Exception as e:
                 logging.error(e)
                 return
         elif method == 0:
             sock.send("\x05\x00")
         else:
             logging.error('unsupported method %d' % method)
             return
         data = self.rfile.read(4) or '\x00' * 4
         mode = ord(data[1])
         if mode == 1:
             pass
         elif mode == 3:
             # UDP
             logging.debug('UDP assc request')
             if sock.family == socket.AF_INET6:
                 header = '\x05\x00\x00\x04'
             else:
                 header = '\x05\x00\x00\x01'
             addr, port = sock.getsockname()
             addr_to_send = socket.inet_pton(sock.family, addr)
             port_to_send = struct.pack('>H', port)
             sock.send(header + addr_to_send + port_to_send)
             while True:
                 data = sock.recv(4096)
                 if not data:
                     break
             return
         else:
             logging.warn('unknown mode %d' % mode)
             return
         addrtype = ord(data[3])
         addr_to_send = data[3]
         if addrtype == 1:
             addr_ip = self.rfile.read(4)
             addr = socket.inet_ntoa(addr_ip)
             addr_to_send += addr_ip
         elif addrtype == 3:
             addr_len = self.rfile.read(1)
             addr = self.rfile.read(ord(addr_len))
             addr_to_send += addr_len + addr
         elif addrtype == 4:
             addr_ip = self.rfile.read(16)
             addr = socket.inet_ntop(socket.AF_INET6, addr_ip)
             addr_to_send += addr_ip
         else:
             logging.warn('addr_type not supported')
             # not supported
             return
         addr_port = self.rfile.read(2)
         addr_to_send += addr_port
         port = struct.unpack('>H', addr_port)
         try:
             reply = "\x05\x00\x00\x01"
             reply += socket.inet_aton('0.0.0.0') + struct.pack(">H", 2222)
             self.wfile.write(reply)
             # reply immediately
             a_server, a_port = Socks5Server.get_server()
             addrs = socket.getaddrinfo(a_server, a_port)
             if addrs:
                 af, socktype, proto, canonname, sa = addrs[0]
                 if config_fast_open:
                     remote = socket.socket(af, socktype, proto)
                     remote.setsockopt(socket.IPPROTO_TCP,
                                       socket.TCP_NODELAY, 1)
                     Socks5Server.handle_tcp(sock, remote, encryptor,
                                             addr_to_send, a_server, a_port)
                 else:
                     logging.info('connecting %s:%d' % (addr, port[0]))
                     remote = socket.create_connection(
                         (a_server, a_port), timeout=config_timeout)
                     remote.settimeout(config_timeout)
                     remote.setsockopt(socket.IPPROTO_TCP,
                                       socket.TCP_NODELAY, 1)
                     Socks5Server.handle_tcp(sock, remote, encryptor,
                                             addr_to_send)
         except (OSError, IOError) as e:
             logging.warn(e)
             return
     except (OSError, IOError) as e:
         raise e
         logging.warn(e)
Exemplo n.º 25
0
    def connect(self, address):
        self._address = address
        for _ in range(2):
            self.getKey()
            if self._sock is None:
                from connection import create_connection
                host, port = self.hxsServer.hostname, self.hxsServer.port
                self._sock = create_connection((host, port),
                                               self.timeout,
                                               parentproxy=self.parentproxy,
                                               tunnel=True)

                self.pskcipher = encrypt.Encryptor(self.PSK, self.method)

                self._rfile = self._sock.makefile('rb')
                self._header_sent = False
                self._header_received = False

            logger.debug('hxsocks send connect request')
            padding_len = random.randint(64, 255)
            pt = b''.join([
                struct.pack('>I', int(time.time())),
                chr(len(self._address[0])).encode('latin1'),
                self._address[0].encode(),
                struct.pack('>H', self._address[1]), b'\x00' * padding_len
            ])
            ct = self.cipher.encrypt(pt)

            if self.pskcipher._encryptor:
                ct = self.pskcipher.encrypt(b''.join([
                    chr(11).encode(), keys[self.serverid][0],
                    struct.pack('>H', len(ct)), ct
                ]))
                self._sock.sendall(struct.pack('>H', len(ct)) + ct)
            else:
                self._sock.sendall(
                    self.pskcipher.encrypt(b''.join([
                        chr(11).encode(), keys[self.serverid][0],
                        struct.pack('>H', len(ct)), ct
                    ])))

            self._sock.settimeout(8)
            resp_len = self._rfile.read(2)
            if not resp_len:
                self._sock.close()
                self._sock = None
                continue
            self._sock.settimeout(self.timeout)
            resp_len, = struct.unpack('>H', resp_len)

            ct = self._rfile.read(resp_len)

            try:
                resp = self.cipher.decrypt(ct)
            except InvalidTag:
                if self.serverid in keys:
                    del keys[self.serverid]
                continue
            except BufEmptyError:
                self._sock.close()
                self._sock = None
                continue

            d = byte2int(resp) if resp else None
            if d == 0:
                logger.debug('hxsocks connected')
                self.readable = 1
                self.writeable = 1
                self.pre_close = 0
                # start forwarding
                self._thread = Thread(target=self.forward_tcp,
                                      args=(self._socketpair_b, self._sock,
                                            self.cipher, 60))
                self._thread.start()
                return
            else:
                raise IOError(
                    0, 'hxsocks Error: remote connect failed. code %d' % d)
        raise IOError(0, 'hxsocks Error: remote connect failed.')
Exemplo n.º 26
0
 def connect(self, address):
     self.__address = address
     sshost, ssport, ssmethod, sspassword = (self.ssServer.hostname, self.ssServer.port, self.ssServer.username.lower(), self.ssServer.password)
     from connection import create_connection
     self._sock = create_connection((sshost, ssport), self.timeout, parentproxy=self.parentproxy, tunnel=True)
     self.crypto = encrypt.Encryptor(sspassword, ssmethod)
Exemplo n.º 27
0
    def getKey(self):
        with newkey_lock[self.serverid]:
            if self.serverid not in keys:
                for _ in range(2):
                    logger.debug('hxsocks getKey')
                    host, port, usn, psw = (self.hxsServer.hostname,
                                            self.hxsServer.port,
                                            self.hxsServer.username,
                                            self.hxsServer.password)
                    if self._sock is None:
                        logger.debug('hxsocks connect')
                        from connection import create_connection
                        self._sock = create_connection(
                            (host, port),
                            self.timeout,
                            parentproxy=self.parentproxy,
                            tunnel=True)
                        self.pskcipher = encrypt.Encryptor(
                            self.PSK, self.method)
                        self._rfile = self._sock.makefile('rb')
                        self._header_sent = False
                        self._header_received = False
                    acipher = ECC(self.pskcipher.key_len)
                    pubk = acipher.get_pub_key()
                    logger.debug('hxsocks send key exchange request')
                    ts = struct.pack('>I', int(time.time()))
                    padding_len = random.randint(64, 255)
                    data = b''.join([
                        ts,
                        chr(len(pubk)).encode('latin1'), pubk,
                        hmac.new(psw.encode(), ts + pubk + usn.encode(),
                                 hashlib.sha256).digest(),
                        b'\x00' * padding_len
                    ])
                    data = chr(10).encode() + struct.pack('>H',
                                                          len(data)) + data
                    self._sock_sendall(self.pskcipher.encrypt(data))
                    resp_len = 2 if self.pskcipher.decipher else self.pskcipher.iv_len + 2
                    resp_len = self.pskcipher.decrypt(
                        self._rfile_read(resp_len))
                    resp_len = struct.unpack('>H', resp_len)[0]
                    data = self.pskcipher.decrypt(self._rfile_read(resp_len))

                    data = io.BytesIO(data)

                    resp_code = byte2int(data.read(1))
                    if resp_code == 0:
                        logger.debug('hxsocks read key exchange respond')
                        pklen = byte2int(data.read(1))
                        scertlen = byte2int(data.read(1))
                        siglen = byte2int(data.read(1))

                        server_key = data.read(pklen)
                        auth = data.read(32)
                        server_cert = data.read(scertlen)
                        signature = data.read(siglen)

                        # TODO: ask user if a certificate should be accepted or not.
                        if host not in known_hosts:
                            logger.info(
                                'hxs: server %s new cert %s saved.' %
                                (host,
                                 hashlib.sha256(server_cert).hexdigest()[:8]))
                            with open('./.hxs_known_hosts/' + host + '.cert',
                                      'wb') as f:
                                f.write(server_cert)
                                known_hosts[host] = server_cert
                        elif known_hosts[host] != server_cert:
                            logger.error(
                                'hxs: server %s certificate mismatch! PLEASE CHECK!'
                                % host)
                            raise OSError(0, 'hxs: bad certificate')
                        if auth == hmac.new(psw.encode(),
                                            pubk + server_key + usn.encode(),
                                            hashlib.sha256).digest():
                            if ECC.verify_with_pub_key(server_cert, auth,
                                                       signature,
                                                       self.hash_algo):
                                shared_secret = acipher.get_dh_key(server_key)
                                keys[self.serverid] = (
                                    hashlib.md5(pubk).digest(), shared_secret)
                                self.cipher = encrypt.AEncryptor(
                                    keys[self.serverid][1], self.method, SALT,
                                    CTX, 0, MAC_LEN)
                                logger.debug('hxs key exchange success')
                                return
                            else:
                                logger.error(
                                    'hxs getKey Error: server auth failed, bad signature'
                                )
                        else:
                            logger.error(
                                'hxs getKey Error: server auth failed, bad username or password'
                            )
                    else:
                        logger.error(
                            'hxs getKey Error. bad password or timestamp.')
                else:
                    raise IOError(0, 'hxs getKey Error')
            else:
                self.cipher = encrypt.AEncryptor(keys[self.serverid][1],
                                                 self.method, SALT, CTX, 0,
                                                 MAC_LEN)
Exemplo n.º 28
0
    def __init__(self, ntsk):
        self.ntsk = ntsk
        self.CharQuery = data.character_query.CharacterQuery()
        self.scoreReact = score_react.ScoreReact()
        self.messageEncryptor = encrypt.Encryptor()
        self.kanjiQuiz = kanji_quiz.KanjiQuiz()
        self.googleSearcher = google_search.googleimagesdownload()
        self.searchArgs = {
            "keywords": "neko",
            "safe_search": False,
            "metadata": False,
            "limit": 5,
            "no_directory": True,
            "output_directory": "birdy",
            "keywords_from_file": None,
            "size": None,
            "format": None,
            "time": None,
            "time_range": None,
            'suffix_keywords': None,
            'prefix_keywords': None,
            'url': None,
            'similar_images': None,
            'specific_site': None,
            'single_image': None,
            'proxy': None,
            'image_directory': None,
            'thumbnail': None,
            'language': None,
            'exact_size': None,
            'color': None,
            'color_type': None,
            'usage_rights': None,
            'type': None,
            'aspect_ratio': None,
            'offset': None
        }

        danbooru_config = json.load(
            open('data/config.json', 'r', encoding="utf-8_sig"))
        self.danbooruRequest = data.danbooru_request.DanbooruRequest(
            danbooru_config['danbooru_user'], danbooru_config['danbooru_key'])
        self.danbooruQuery = data.danbooru_query.DanbooruQuery(
            servers=list(map(lambda s: s.id, self.ntsk.servers)))
        self.timerHolder = timer.TimerHolder(
            servers=list(map(lambda s: s.id, self.ntsk.servers)))
        self.atejiMatcher = ateji_to_word.AtejiMatcher()
        #self.timerHolder = timer_holder.TimerHolder() # holds timers for each server, each with info on the user who created it, etc...
        #self.scheduler = sched.scheduler() # scheduler(time.time, time.sleep) implied ((wow, asyncio.sleep() seems good for now))

        self.f_dict = dict()

        self.f_dict[pfx + 'info'] = self.display_info
        self.f_dict[pfx + 'commands'] = self.get_commands

        self.f_dict[pfx + 'count'] = self.db_count
        self.f_dict[pfx + 'stats'] = self.display_top_words
        self.f_dict[pfx + 'logs'] = self.get_logs

        self.f_dict[pfx + 'bin'] = self.encode_bin
        self.f_dict[pfx + 'unbin'] = self.decode_bin
        self.f_dict[pfx + 'qr'] = self.create_qr
        self.f_dict[pfx + 'enc'] = self.get_encryption
        self.f_dict[pfx + 'dec'] = self.get_decryption

        self.f_dict[pfx + 'trans'] = self.translate

        self.f_dict[pfx + 'danbo'] = self.post_danbooru
        self.f_dict[pfx + 'google'] = self.google_images
        self.f_dict[pfx + 'vgoogle'] = self.google_videos

        self.f_dict[pfx + 'setquote'] = self.set_quote
        self.f_dict[pfx + 'quote'] = self.get_quote

        self.f_dict[pfx + 'points'] = self.show_points

        self.f_dict[pfx + 'automata'] = self.automata
        self.f_dict[pfx + 'trivia'] = self.ask_trivia
        self.f_dict[pfx + 'kanji'] = self.ask_kanji_quiz

        self.f_dict[pfx + 'kmatch'] = self.match_ateji

        self.f_dict[pfx + 'futuresay'] = self.future_say

        self.f_dict[pfx + 'matrix'] = self.matrix

        self.f_dict[pfx + 'lmgtfy'] = self.lmgtfy

        self.f_dict[pfx + 'score'] = self.display_score

        self.f_dict[pfx + '😂'] = self.ok_hand
        self.f_dict[pfx + 'yuri'] = self.yuri

        self.f_dict[pfx + '!db'] = self.do_nothing
        self.f_dict[pfx + '!inspire'] = self.do_nothing
        self.f_dict[pfx + '!info'] = self.do_nothing

        self.f_dict[pfx + 'initdata'] = self.init_data
        self.f_dict[pfx + 'leaveserver'] = self.leave_server
Exemplo n.º 29
0
    def handle(self):
        try:
            self.connection.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY,
                                       1)
            pskcipher = encrypt.Encryptor(self.server.PSK, self.server.method)
            self.connection.settimeout(self.timeout)
            data = self.rfile.read(pskcipher.iv_len)
            pskcipher.decrypt(data)
            while True:
                try:
                    data = self.rfile.read(1)
                    self.connection.settimeout(self.timeout)
                    cmd = ord(pskcipher.decrypt(data))
                except Exception as e:
                    logging.error(
                        'cmd Exception: server %s %r from %s:%s' %
                        (self.server.server_address[1], e,
                         self.client_address[0], self.client_address[1]))
                    break
                if cmd == 10:  # client key exchange
                    rint = random.randint(64, 255)
                    req_len = pskcipher.decrypt(self.rfile.read(2))
                    req_len = struct.unpack('>H', req_len)[0]
                    data = pskcipher.decrypt(self.rfile.read(req_len))
                    data = io.BytesIO(data)
                    ts = data.read(4)
                    if abs(struct.unpack('>I', ts)[0] - time.time()) > 120:
                        # possible replay attack
                        logging.error('bad timestamp. client_ip: %s' %
                                      self.client_address[0])
                        break
                    pklen = ord(data.read(1))
                    client_pkey = data.read(pklen)
                    client_auth = data.read(32)

                    def _send(data):
                        data = struct.pack('>H', len(data)) + data
                        self.wfile.write(pskcipher.encrypt(data))

                    client = None
                    for user, passwd in USER_PASS.items():
                        h = hmac.new(passwd.encode(),
                                     ts + client_pkey + user.encode(),
                                     hashlib.sha256).digest()
                        if compare_digest(h, client_auth):
                            client = user
                            break
                    else:
                        logging.error('user not found. client_ip: %s' %
                                      self.client_address[0])
                        break
                    pkey, passwd = KeyManager.create_key(
                        client, client_pkey, pskcipher.key_len)
                    if pkey:
                        logging.info('new key exchange. client: %s, ip: %s' %
                                     (client, self.client_address[0]))
                        h = hmac.new(passwd.encode(),
                                     client_pkey + pkey + client.encode(),
                                     hashlib.sha256).digest()
                        scert = SERVER_CERT.get_pub_key()
                        signature = SERVER_CERT.sign(h, self.server.hash_algo)
                        data = chr(0) + chr(len(pkey)) + chr(len(scert)) + chr(
                            len(signature)
                        ) + pkey + h + scert + signature + os.urandom(rint)
                        _send(data)
                        continue
                    else:
                        logging.error(
                            'Private_key already registered. client: %s, ip: %s'
                            % (client, self.client_address[0]))
                        # KeyManager.del_key(hashlib.md5(client_pkey).digest())
                        break
                elif cmd == 11:  # a connect request
                    client_pkey = pskcipher.decrypt(self.rfile.read(16))
                    rint = random.randint(64, 2048)

                    def _send(code, cipher):
                        if code == 1:
                            data = os.urandom(rint)
                            data = pskcipher.encrypt(struct.pack('>H',
                                                                 rint)) + data
                            self.wfile.write(data)
                        else:
                            ct = cipher.encrypt(
                                chr(code) + os.urandom(rint - 1))
                            data = pskcipher.encrypt(struct.pack(
                                '>H', len(ct))) + ct
                            self.wfile.write(data)

                    if KeyManager.check_key(client_pkey):
                        logging.error(
                            'client key not exist or expired. client ip: %s' %
                            self.client_address[0])
                        ctlen = struct.unpack(
                            '>H', pskcipher.decrypt(self.rfile.read(2)))[0]
                        self.rfile.read(ctlen)
                        _send(1, None)
                        continue

                    user = KeyManager.get_user_by_pubkey(client_pkey)
                    cipher = encrypt.AEncryptor(
                        KeyManager.get_skey_by_pubkey(client_pkey),
                        self.server.method, CTX)
                    ctlen = struct.unpack(
                        '>H', pskcipher.decrypt(self.rfile.read(2)))[0]
                    ct = self.rfile.read(ctlen)
                    data = cipher.decrypt(ct)
                    buf = io.BytesIO(data)
                    ts = buf.read(4)
                    if abs(struct.unpack('>I', ts)[0] - time.time()) > 120:
                        logging.error(
                            'bad timestamp, possible replay attrack. client ip: %s'
                            % self.client_address[0])
                        # KeyManager.del_key(client_pkey)
                        # _send(1, None)
                        break
                    host_len = ord(buf.read(1))
                    addr = buf.read(host_len)
                    port = struct.unpack('>H', buf.read(2))[0]
                    if self._request_is_loopback(
                        (addr, port)) and port not in self.server.forward:
                        logging.info(
                            'server %d access localhost:%d denied. from %s:%d, %s'
                            % (self.server.server_address[1], port,
                               self.client_address[0], self.client_address[1],
                               user))
                        _send(2, cipher)
                        continue
                    try:
                        logging.info('server %d request %s:%d from %s:%d, %s' %
                                     (self.server.server_address[1], addr,
                                      port, self.client_address[0],
                                      self.client_address[1], user))
                        remote = create_connection((addr, port),
                                                   timeout=10,
                                                   proxy=self.server.proxy)
                        remote.setsockopt(socket.IPPROTO_TCP,
                                          socket.TCP_NODELAY, 1)
                        _send(0, cipher)
                        # self.remote.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
                    except (IOError, OSError) as e:  # Connection refused
                        logging.warning(
                            'server %s:%d %r on connecting %s:%d' %
                            (self.server.server_address[0],
                             self.server.server_address[1], e, addr, port))
                        _send(2, cipher)
                        continue
                    if self.forward_tcp(self.connection,
                                        remote,
                                        cipher,
                                        pskcipher,
                                        timeout=60):
                        break
                    self.connection.settimeout(60)
                    logging.debug(
                        'hxsocks connect reusable, except next connection')
                elif cmd in (1, 3, 4, 17, 19, 20):
                    # A shadowsocks request
                    if not self.server.ss:
                        logging.warning(
                            'shadowsocks not enabled for this server. port: %d'
                            % self.server.server_address[1])
                        break
                    ota = cmd & 16
                    if cmd & 15 == 1:
                        _addr = pskcipher.decrypt(self.rfile.read(4))
                        addr = socket.inet_ntoa(_addr)
                    elif cmd & 15 == 3:
                        _addr = pskcipher.decrypt(self.rfile.read(1))
                        addr = pskcipher.decrypt(self.rfile.read(ord(_addr)))
                        _addr += addr
                    elif cmd & 15 == 4:
                        _addr = socket.AF_INET6, pskcipher.decrypt(
                            self.rfile.read(16))
                        addr = socket.inet_ntop(_addr)
                    port = struct.unpack('>H',
                                         pskcipher.decrypt(
                                             self.rfile.read(2)))[0]
                    # verify
                    if ota:
                        header = chr(cmd) + _addr + struct.pack('>H', port)
                        self._ota_chunk_idx = 0
                        rmac = pskcipher.decrypt(self.rfile.read(10))
                        key = pskcipher.decipher_iv + pskcipher.key
                        mac = hmac.new(key, header, hashlib.sha1).digest()[:10]
                        if not compare_digest(rmac, mac):
                            logging.error("OTA Failed!!")
                            break

                    if self._request_is_loopback(
                        (addr, port)) and port not in self.server.forward:
                        logging.info(
                            'server %d access localhost:%d denied. from %s:%d'
                            % (self.server.server_address[1], port,
                               self.client_address[0], self.client_address[1]))
                        break
                    try:
                        remote = None
                        logging.info(
                            'server %d SS request %s:%d from %s:%d %s' %
                            (self.server.server_address[1], addr, port,
                             self.client_address[0], self.client_address[1],
                             'with ota' if ota else ''))
                        remote = create_connection((addr, port),
                                                   timeout=10,
                                                   proxy=self.server.proxy)
                        if ota:
                            return self.ssforward_tcp_ota(self.connection,
                                                          remote,
                                                          pskcipher,
                                                          timeout=60)
                        return self.ssforward_tcp(self.connection,
                                                  remote,
                                                  pskcipher,
                                                  timeout=60)
                    except (IOError, OSError) as e:  # Connection refused
                        logging.warn(
                            'server %s:%d %r on connecting %s:%d' %
                            (self.server.server_address[0],
                             self.server.server_address[1], e, addr, port))
                        return
                else:
                    logging.warning('unknown cmd %d, bad encryption key?' %
                                    cmd)
                    break
            ins, _, _ = select.select([self.connection], [], [], 1)
            while ins:
                data = self.connection.recv(self.bufsize)
                if not data:
                    break
                ins, _, _ = select.select([self.connection], [], [], 1)
        except Exception as e:
            logging.error(repr(e))
            logging.error(traceback.format_exc())
Exemplo n.º 30
0
    def handle(self):
        try:
            self.encryptor = encrypt.Encryptor(KEY, METHOD)
            sock = self.connection
            d = sock.recv(262)

            reply = init_send = None
            if d.startswith('CONNECT '):
                d = recv_all(sock, d, '\r\n\r\n')
                addr, port, addr_to_send = self.get_host_port(
                    d, '443', from_first_line=True)
                reply = 'HTTP/1.1 200 OK\r\n\r\n'
            elif d.startswith('GET ') or d.startswith('HEAD '):
                d = recv_all(sock, d, '\r\n\r\n')
                addr, port, addr_to_send = self.get_host_port(d, '80')
                d = self.clean_path(d)
                if port[0] == PORT and (addr.startswith('192.168')
                                        or addr.startswith('127.0')):
                    mimetype = 'application/x-ns-proxy-autoconfig'
                    with open('proxy.pac', 'rb') as fp:
                        data = fp.read()
                        self.wfile.write(
                            'HTTP/1.1 200\r\nContent-Type: %s\r\nContent-Length: %s\r\n\r\n'
                            % (mimetype, len(data)))
                        self.wfile.write(data)
                    sock.close()
                    logging.info('get proxy pac')
                    return
                d = d.replace('Proxy-Connection:', 'Connection:')
                init_send = d
            elif d.startswith('POST '):
                d = recv_all(sock, d, '\r\n\r\n')
                i = d.find('\r\n\r\n')
                remain = len(d) - (i + 4)
                header = self.parse_header(d)
                if 'Content-Length' not in header:
                    logging.error(d)
                    return
                size = int(header['Content-Length']) - remain
                if size > 0:
                    d += recv_size(sock, size)
                addr, port, addr_to_send = self.get_host_port(d, '80')
                d = self.clean_path(d)
                d = d.replace('Proxy-Connection:', 'Connection:')
                init_send = d
            else:
                sock.send("\x05\x00")
                data = self.rfile.read(4) or '\x00' * 4
                mode = ord(data[1])
                if mode != 1:
                    logging.warn('mode != 1')
                    logging.warn(d)
                    return
                addrtype = ord(data[3])
                addr_to_send = data[3]
                if addrtype == 1:
                    addr_ip = self.rfile.read(4)
                    addr = socket.inet_ntoa(addr_ip)
                    addr_to_send += addr_ip
                elif addrtype == 3:
                    addr_len = self.rfile.read(1)
                    addr = self.rfile.read(ord(addr_len))
                    addr_to_send += addr_len + addr
                elif addrtype == 4:
                    addr_ip = self.rfile.read(16)
                    addr = socket.inet_ntop(socket.AF_INET6, addr_ip)
                    addr_to_send += addr_ip
                else:
                    logging.warn('addr_type not support')
                    # not support
                    return
                addr_port = self.rfile.read(2)
                addr_to_send += addr_port
                port = struct.unpack('>H', addr_port)
                reply = "\x05\x00\x00\x01"
                reply += socket.inet_aton('0.0.0.0') + struct.pack(">H", 2222)

            try:
                if reply:
                    self.wfile.write(reply)
                # reply immediately
                remote = socket.create_connection((SERVER, REMOTE_PORT))
                self.send_encrypt(remote, addr_to_send)
                logging.info('connecting %s:%d' % (addr, port[0]))
            except socket.error, e:
                logging.warn(e)
                return
            self.handle_tcp(sock, remote, (addr, port[0]), init_send)