Ejemplo n.º 1
0
 def create_key(cls, user, client_pkey, klen):
     if cls.notvalid(user, client_pkey):
         return 0, 0
     if len(cls.userpkeys[user]) > 3:
         cls.del_key(cls.userpkeys[user][0])
     dh = ECC(klen)
     shared_secret = dh.get_dh_key(client_pkey)
     client_pkey = hashlib.md5(client_pkey).digest()
     cls.userpkeys[user].append(client_pkey)
     cls.pkeyuser[client_pkey] = user
     cls.pkeykey[client_pkey] = shared_secret
     cls.pkeytime[client_pkey] = time.time()
     return dh.get_pub_key(), USER_PASS[user]
Ejemplo n.º 2
0
def main():
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s %(levelname)-8s %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S',
                        filemode='a+')

    hello = 'hxsocks-server %s' % __version__
    if gevent:
        hello += ' with gevent %s' % gevent.__version__
    print(hello)
    print('by v3aqb')
    global SERVER_CERT
    try:
        SERVER_CERT = ECC(from_file=os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'cert.pem'))
    except:
        logging.warning('server cert not found, creating...')
        SERVER_CERT = ECC(key_len=32)
        SERVER_CERT.save(
            os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'cert.pem'))

    servers = ['hxs://0.0.0.0:9000']
    forward = []
    if os.path.exists(
            os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'config.json')):
        global USER_PASS
        d = json.loads(
            open(
                os.path.join(os.path.dirname(os.path.abspath(__file__)),
                             'config.json')).read())
        USER_PASS = d['users']
        servers = d['servers']
        forward = d.get('forward', [])
    for s in servers:
        logging.info('starting server: %s' % s)
        ssserver = HXSocksServer(s, forward, HXSocksHandler)
        threading.Thread(target=ssserver.serve_forever).start()
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
    def getKey(self):
        logger.debug('hxsocks2 getKey')
        host, port, usn, psw = (self.hxsServer.hostname, self.hxsServer.port, self.hxsServer.username, self.hxsServer.password)
        logger.debug('hxsocks2 connect to server')
        from connection import create_connection
        self._sock = create_connection((host, port), self.timeout, parentproxy=self.parentproxy, tunnel=True)

        self._rfile = self._sock.makefile('rb')

        acipher = ECC(self.__pskcipher._key_len)
        pubk = acipher.get_pub_key()
        logger.debug('hxsocks2 send key exchange request')
        ts = int(time.time()) // 30
        ts = struct.pack('>I', ts)
        padding_len = random.randint(64, 255)
        data = b''.join([chr(len(pubk)).encode('latin1'),
                         pubk,
                         hmac.new(psw.encode(), ts + pubk + usn.encode(), hashlib.sha256).digest(),
                         b'\x00' * padding_len])
        data = chr(20).encode() + struct.pack('>H', len(data)) + data

        ct = self.__pskcipher.encrypt(data)
        self._sock.sendall(ct)

        self.__pskcipher.decrypt(self._rfile.read(self.__pskcipher._iv_len))

        if encrypt.is_aead(self.method):
            ct_len = self.__pskcipher.decrypt(self._rfile.read(18))
            ct_len, = struct.unpack('!H', ct_len)
            ct = self.__pskcipher.decrypt(self._rfile.read(ct_len + 16))
            data = ct[2:]
        else:
            resp_len = self.__pskcipher.decrypt(self._rfile.read(2))
            resp_len, = struct.unpack('>H', resp_len)
            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.
            server_id = '%s_%d' % (host, port)
            if server_id not in known_hosts:
                logger.info('hxs: server %s new cert %s saved.' % (server_id, hashlib.sha256(server_cert).hexdigest()[:8]))
                with open('./.hxs_known_hosts/' + server_id + '.cert', 'wb') as f:
                    f.write(server_cert)
                    known_hosts[server_id] = server_cert
            elif known_hosts[server_id] != server_cert:
                logger.error('hxs: server %s certificate mismatch! PLEASE CHECK!' % server_id)
                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)
                    logger.debug('hxs key exchange success')
                    self.__cipher = AEncryptor(shared_secret, self.method, CTX)
                    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.')
        raise OSError(0, 'hxs getKey Error')