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)
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))
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''
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))
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())
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)
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
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')
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()