Beispiel #1
0
    def __init__(self, _class, serverinfo, user_mgr, log_level):
        self._class = _class
        self.user_mgr = user_mgr

        self.serverinfo = serverinfo
        parse = urllib.parse.urlparse(serverinfo)
        query = urllib.parse.parse_qs(parse.query)
        if parse.scheme == 'ss':
            self.psk, self.method = parse.password, parse.username
            self.ss_enable = True
        elif 'hxs' in parse.scheme:
            self.psk = query.get('PSK', [''])[0]
            self.method = query.get('method', [DEFAULT_METHOD])[0]
            self.ss_enable = self.psk and query.get('ss', ['1'])[0] == '1'
        else:
            raise ValueError('bad serverinfo: {}'.format(self.serverinfo))

        self.aead = is_aead(self.method)

        # HTTP proxy only
        proxy = query.get('proxy', [''])[0]
        self.proxy = parse_hostport(proxy) if proxy else None

        self.address = (parse.hostname, parse.port)

        self.logger = logging.getLogger('hxs_%d' % self.address[1])
        self.logger.setLevel(int(query.get('log_level', [log_level])[0]))
        hdr = logging.StreamHandler()
        formatter = logging.Formatter(
            '%(asctime)s %(name)s:%(levelname)s %(message)s',
            datefmt='%H:%M:%S')
        hdr.setFormatter(formatter)
        self.logger.addHandler(hdr)

        self.logger.warning('starting server: %s', serverinfo)
Beispiel #2
0
    def __init__(self, _class, serverinfo, kmgr, log_level):
        self._class = _class
        self.kmgr = kmgr

        self.serverinfo = serverinfo
        p = urllib.parse.urlparse(serverinfo)
        q = urllib.parse.parse_qs(p.query)
        if p.scheme == 'ss':
            self.PSK, self.method = p.password, p.username
            self.ss_enable = True
        elif p.scheme == 'hxs':
            self.PSK = q.get('PSK', [''])[0]
            self.method = q.get('method', [DEFAULT_METHOD])[0]
            self.ss_enable = self.PSK and urllib.parse.parse_qs(p.query).get('ss', ['1'])[0] == '1'
        else:
            raise ValueError('bad serverinfo: {}'.format(self.serverinfo))

        self.aead = is_aead(self.method)

        # HTTP proxy only
        proxy = q.get('proxy', [''])[0]
        self.proxy = parse_hostport(proxy) if proxy else None

        self.address = (p.hostname, p.port)

        self.logger = logging.getLogger('hxs_%d' % self.address[1])
        self.logger.setLevel(int(q.get('log_level', [log_level])[0]))
        hdr = logging.StreamHandler()
        formatter = logging.Formatter('%(asctime)s %(name)s:%(levelname)s %(message)s',
                                      datefmt='%H:%M:%S')
        hdr.setFormatter(formatter)
        self.logger.addHandler(hdr)

        self.logger.warning('starting server: {}'.format(serverinfo))
Beispiel #3
0
    def __init__(self, proxy, ):
        self.logger = logging.getLogger('ss')
        self.proxy = proxy
        ssmethod, sspassword = self.proxy.username, self.proxy.password
        if sspassword is None:
            ssmethod, sspassword = base64.b64decode(ssmethod).decode().split(':', 1)
        ssmethod = ssmethod.lower()

        self._address = None
        self._port = 0
        self.client_reader = None
        self.client_writer = None
        self.remote_reader = None
        self.remote_writer = None
        self.task = None

        self.aead = is_aead(ssmethod)
        self.crypto = Encryptor(sspassword, ssmethod)
        self.connected = False
        self.last_active = time.time()
        # if eof recieved
        self.remote_eof = False
        self.client_eof = False
        self.data_recved = False
        self._buf = b''
Beispiel #4
0
    def __init__(self, _class, serverinfo, log_level):
        self._class = _class

        self.serverinfo = serverinfo
        p = urllib.parse.urlparse(serverinfo)
        q = urllib.parse.parse_qs(p.query)
        if p.scheme == 'ss':
            self.PSK, self.method = p.password, p.username
            self.ss_enable = True
        else:
            raise ValueError('bad serverinfo: {}'.format(self.serverinfo))

        self.aead = is_aead(self.method)

        # HTTP proxy only
        proxy = q.get('proxy', [''])[0]
        self.proxy = parse_hostport(proxy) if proxy else None

        self.address = (p.hostname, p.port)

        self.logger = logging.getLogger('ss_%d' % self.address[1])
        self.logger.setLevel(int(q.get('log_level', [log_level])[0]))
        hdr = logging.StreamHandler()
        formatter = logging.Formatter(
            '%(asctime)s %(name)s:%(levelname)s %(message)s',
            datefmt='%H:%M:%S')
        hdr.setFormatter(formatter)
        self.logger.addHandler(hdr)

        self.logger.warning('starting server: {}'.format(serverinfo))
Beispiel #5
0
def test():
    print('encrypt and decrypt 20MB data.')

    lst = sorted(method_supported.keys())
    lst = sorted(lst, key=lambda method: is_aead(method))
    size = max([len(x) for x in lst])
    format_ = '%-{:d}s %.4fs'.format(size)

    for method in lst:
        try:
            time_used = test_one(method)
            print(format_ % (method, time_used))
        except Exception as e:
            print(traceback.format_exc())
Beispiel #6
0
def test_for_result():
    result = []
    result.append('encrypt and decrypt 20MB data.')

    lst = sorted(method_supported.keys())
    lst = sorted(lst, key=lambda method: is_aead(method))
    size = max([len(x) for x in lst])
    format_ = '%-{:d}s %.4fs'.format(size)

    for method in lst:
        try:
            time_used = test_one(method)
            result.append(format_ % (method, time_used))
        except Exception as e:
            result.append(format_ % method)
    return '\n'.join(result)
Beispiel #7
0
def test_one(method):
    data = os.urandom(10240)
    if is_aead(method):
        cipher = AEncryptor(b'123456', method, b"ctx", check_iv=False)
        cipher1 = AEncryptor(b'123456', method, b"ctx", check_iv=False)
    else:
        cipher = Encryptor(b'123456', method, check_iv=False)
        cipher1 = Encryptor(b'123456', method, check_iv=False)
    ct1 = cipher.encrypt(data)
    cipher1.decrypt(ct1)
    time_log = time.time()
    for _ in range(1024):
        ct1 = cipher.encrypt(data)
        ct2 = cipher.encrypt(data)
        cipher1.decrypt(ct1)
        cipher1.decrypt(ct2)
    return time.time() - time_log
Beispiel #8
0
    async def get_key(self):
        self.logger.debug('hxsocks2 getKey')
        usn, psw = (self.proxy.username, self.proxy.password)
        self.logger.info('%s connect to server', self.name)
        from .connection import open_connection
        self.remote_reader, self.remote_writer, _ = await open_connection(
            self.proxy.hostname,
            self.proxy.port,
            proxy=self.proxy.get_via(),
            timeout=self.timeout,
            tunnel=True)

        # prep key exchange request
        self.__pskcipher = Encryptor(self._psk, self.method)
        ecc = ECC(self.__pskcipher._key_len)
        pubk = ecc.get_pub_key()
        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)

        # send key exchange request
        self.remote_writer.write(ct)
        await self.remote_writer.drain()

        # read iv
        iv = await self._rfile_read(self.__pskcipher._iv_len, self.timeout)
        self.__pskcipher.decrypt(iv)

        # read server response
        if is_aead(self.method):
            ct_len = await self._rfile_read(18, self.timeout)
            ct_len = self.__pskcipher.decrypt(ct_len)
            ct_len, = struct.unpack('!H', ct_len)
            ct = await self._rfile_read(ct_len + 16)
            ct = self.__pskcipher.decrypt(ct)
            data = ct[2:]
        else:
            resp_len = await self._rfile_read(2, self.timeout)
            resp_len = self.__pskcipher.decrypt(resp_len)
            resp_len, = struct.unpack('>H', resp_len)
            data = await self._rfile_read(resp_len)
            data = self.__pskcipher.decrypt(data)

        data = io.BytesIO(data)

        resp_code = byte2int(data.read(1))
        if resp_code == 0:
            self.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.
            host, port = self.proxy._host_port
            server_id = '%s_%d' % (host, port)
            if server_id not in KNOWN_HOSTS:
                self.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:
                self.logger.error('hxs: server %s certificate mismatch! PLEASE CHECK!', server_id)
                raise ConnectionResetError(0, 'hxs: bad certificate')

            if auth == hmac.new(psw.encode(), pubk + server_key + usn.encode(), hashlib.sha256).digest():
                try:
                    ECC.verify_with_pub_key(server_cert, auth, signature, self.hash_algo)
                    shared_secret = ecc.get_dh_key(server_key)
                    self.logger.debug('hxs key exchange success')
                    self.__cipher = AEncryptor(shared_secret, self.method, CTX)
                    # start reading from connection
                    asyncio.ensure_future(self.read_from_connection())
                    asyncio.ensure_future(self.stat())
                    self.connected = True
                    return
                except InvalidSignature:
                    self.logger.error('hxs getKey Error: server auth failed, bad signature')
            else:
                self.logger.error('hxs getKey Error: server auth failed, bad username or password')
        else:
            self.logger.error('hxs getKey Error. bad password or timestamp.')
        raise ConnectionResetError(0, 'hxs getKey Error')
Beispiel #9
0
    def __init__(self, path_to_conf, parent=None):
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        icon = QIcon(
            os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'icon.png'))
        self.setWindowIcon(icon)

        self.port = 0
        self.path_to_conf = path_to_conf
        self.load_conf(path_to_conf)

        self.tray = SystemTrayIcon(icon, self)
        self.tray.show()
        self.consoleText = deque(maxlen=300)
        self.runner = QProcess(self)

        # log
        self.ui.console.setWordWrapMode(3)

        # local rules
        self.ui.AddLocalRuleButton.clicked.connect(self.addLocalRule)
        self.ui.isgfwedTestButton.clicked.connect(self.isgfwedTest)
        self.spacer_LR = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                     QSizePolicy.Expanding)
        self.ui.LocalRulesLayout.addItem(self.spacer_LR)
        self.local_rule_list = []

        # redir rules
        self.ui.AddRedirectorRuleButton.clicked.connect(self.addRedirRule)
        self.spacer_RR = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                     QSizePolicy.Expanding)
        self.ui.RedirectorRulesLayout.addItem(self.spacer_RR)
        self.redir_rule_list = []

        # proxyList
        self.ui.proxyAddButton.clicked.connect(self.addProxy)
        self.ui.proxyRemoveButton.clicked.connect(self.delProxy)
        self.ui.protocolBox.currentIndexChanged.connect(self.protocolChanged)
        self.ui.proxyDisableButton.clicked.connect(self.disableProxy)
        self.ui.proxyActivateButton.clicked.connect(self.activateProxy)
        self.ui.exclusiveProxyAddButton.clicked.connect(self.exclusiveProxyAdd)
        self.ui.hostnameEdit.textChanged.connect(self.proxy_hostname_changed)
        header = [
            _tr("MainWindow", "name"),
            _tr("MainWindow", "address"),
            _tr("MainWindow", "priority"),
            _tr("MainWindow", "resp"),
        ]
        data = []
        self.PL_table_model = MyTableModel(self, data, header)

        self.ui.proxyListView.setModel(self.PL_table_model)
        self.ui.proxyListView.pressed.connect(self.on_proxy_select)
        import hxcrypto
        self.method_list = ['']
        self.method_list.extend(
            sorted(sorted(hxcrypto.method_supported.keys()),
                   key=lambda x: hxcrypto.is_aead(x)))
        self.ui.encryptionBox.addItems(self.method_list)

        self.ui.protocolBox.addItems(SUPPORTED_PROTOCOL)

        # port forward
        self.ui.PFAddButton.clicked.connect(self.addForward)
        self.ui.PFRemoveButton.clicked.connect(self.delForward)
        header = [
            _tr("MainWindow", "target"),
            _tr("MainWindow", "proxy"),
            _tr("MainWindow", "port"),
        ]
        data = []
        self.PF_table_model = MyTableModel(self, data, header)
        self.ui.PFView.setModel(self.PF_table_model)

        # settings
        self.ui.gfwlistToggle.stateChanged.connect(self.gfwlistToggle)
        self.ui.adblockToggle.stateChanged.connect(self.adblockToggle)
        self.ui.editConfButton.clicked.connect(self.openconf)
        self.ui.editLocalButton.clicked.connect(self.openlocal)
        self.ui.sys_proxy_toggle.setCheckState(
            QtCore.Qt.Checked if self.ieproxy else QtCore.Qt.Unchecked)
        self.ui.sys_proxy_toggle.stateChanged.connect(self.sysProxyToggle)
        if not sys.platform.startswith('win'):
            self.ui.sys_proxy_toggle.setEnabled(False)

        self.createProcess()