From 791bac3fdd3cfb0f7336f82b0d2fde7b2e64a23e Mon Sep 17 00:00:00 2001 From: Micheal X Date: Wed, 15 Nov 2023 15:10:57 +1300 Subject: [PATCH] 5.8.7 add support for py_aes_cfb --- code/default/launcher/sys_platform.py | 1 + code/default/smart_router/local/dns_query.py | 19 +++-- code/default/version.txt | 2 +- .../x_tunnel/local/seley_front/rc4_wrap.py | 73 +++++++++++++++---- 4 files changed, 70 insertions(+), 25 deletions(-) diff --git a/code/default/launcher/sys_platform.py b/code/default/launcher/sys_platform.py index b5c5e87113..b8dfbc71c5 100644 --- a/code/default/launcher/sys_platform.py +++ b/code/default/launcher/sys_platform.py @@ -123,6 +123,7 @@ def show_systray(): sys_tray.serve_forever() def on_quit(): + global sys_tray sys_tray.on_quit() elif sys.platform == "ios": diff --git a/code/default/smart_router/local/dns_query.py b/code/default/smart_router/local/dns_query.py index 6474198853..26256e7d6e 100644 --- a/code/default/smart_router/local/dns_query.py +++ b/code/default/smart_router/local/dns_query.py @@ -164,16 +164,19 @@ def get_local_dns_server(self): iplist.append(ip) elif os.path.isfile('/etc/resolv.conf'): - with open('/etc/resolv.conf', 'rb') as fp: - iplist = re.findall(br'(?m)^nameserver\s+(\S+)', fp.read()) + try: + with open('/etc/resolv.conf', 'rb') as fp: + iplist = re.findall(br'(?m)^nameserver\s+(\S+)', fp.read()) - xlog.debug("DNS resolve servers:%s", iplist) + xlog.debug("DNS resolve servers:%s", iplist) - local_ips = g.local_ips - for ip in local_ips: - if ip in iplist: - xlog.warn("remove local DNS server %s from upstream", ip) - iplist.remove(ip) + local_ips = g.local_ips + for ip in local_ips: + if ip in iplist: + xlog.warn("remove local DNS server %s from upstream", ip) + iplist.remove(ip) + except Exception as e: + xlog.warn("load /etc/resolv.conf fail:%r", e) if not iplist: iplist = [ diff --git a/code/default/version.txt b/code/default/version.txt index fb54fe3dc1..97276d1dee 100644 --- a/code/default/version.txt +++ b/code/default/version.txt @@ -1 +1 @@ -5.8.6 \ No newline at end of file +5.8.7 \ No newline at end of file diff --git a/code/default/x_tunnel/local/seley_front/rc4_wrap.py b/code/default/x_tunnel/local/seley_front/rc4_wrap.py index e0b0a803c3..ce7ccc87bb 100644 --- a/code/default/x_tunnel/local/seley_front/rc4_wrap.py +++ b/code/default/x_tunnel/local/seley_front/rc4_wrap.py @@ -2,11 +2,28 @@ import time import struct import json +import os + +import env_info +import xlog +data_path = env_info.data_path +module_data_path = os.path.join(data_path, 'x_tunnel') + +logger = xlog.getLogger("seley_front", log_path=module_data_path, save_start_log=1500, save_warning_log=True) +logger.set_buffer(300) try: - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes -except: - algorithms = None + from py_aes_cfb import lib as aes + logger.debug("load py_aes_cfb success") +except Exception as e: + aes = None + + try: + from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + logger.debug("load cryptography success") + except: + logger.warn("load cryptography failed:%r", e) + algorithms = None import utils @@ -25,16 +42,37 @@ def __init__(self, sock, ip_str=None, sni=None, on_close=None): self.running = True self.h2 = False - if not algorithms: - raise socket.error('no cryptography') + if not aes and not algorithms: + raise socket.error('no cryptography 7') - algorithm = algorithms.AES(self.sni) + key = self.sni iv = b'\x00' * 16 - self.cipher = Cipher(algorithm, mode=modes.CFB(iv)) - self.decryptor = self.cipher.decryptor() - self.encryptor = self.cipher.encryptor() + if aes: + self.encryptor = aes.encryptor_create(key, len(key), iv, len(iv)) + self.decryptor = aes.decryptor_create(key, len(key), iv, len(iv)) + else: + algorithm = algorithms.AES(key) + self.cipher = Cipher(algorithm, mode=modes.CFB(iv)) + self.decryptor = self.cipher.decryptor() + self.encryptor = self.cipher.encryptor() self.wrap() + def encode(self, input): + if aes: + out = bytes(input) + aes.encryptor_update(self.encryptor, input, len(input), out) + return out + else: + return self.encryptor.update(input) + + def decode(self, input): + if aes: + out = bytes(input) + aes.decryptor_update(self.decryptor, input, len(input), out) + return out + else: + return self.decryptor.update(input) + def wrap(self): ip, port = utils.get_ip_port(self.ip_str) if isinstance(ip, str): @@ -53,17 +91,17 @@ def do_handshake(self): data = json.dumps(info) data_len = len(data) dat = magic + struct.pack("I", data_len) + utils.to_bytes(data) - dat = self.encryptor.update(dat) + dat = self.encode(dat) sended = self._sock.send(dat) res = self._sock.recv(6) - res = self.decryptor.update(res) + res = self.decode(res) if res[0:2] != b"SE": raise Exception("handshake failed") data_len = struct.unpack("I", res[2:])[0] res = self._sock.recv(data_len) - res = self.decryptor.update(res) + res = self.decode(res) info = json.loads(res) def is_support_h2(self): @@ -88,6 +126,10 @@ def __del__(self): if self._on_close: self._on_close(self.ip_str, self.sni) + if aes: + aes.encryptor_destroy(self.encryptor) + aes.decryptor_destroy(self.decryptor) + def get_cert(self): self.peer_cert = { "cert": "", @@ -101,7 +143,7 @@ def connect(self, *args, **kwargs): return def send(self, data, flags=0): - data = self.encryptor.update(data) + data = self.encode(data) try: return self._sock.send(data) except Exception as e: @@ -110,7 +152,7 @@ def send(self, data, flags=0): def recv(self, bufsiz, flags=0): data = self._sock.recv(bufsiz) - data = self.decryptor.update(data) + data = self.decode(data) return data def recv_into(self, buf, nbytes=None): @@ -121,8 +163,7 @@ def recv_into(self, buf, nbytes=None): if not data: return None - - data = self.decryptor.update(data) + data = self.decode(data) buf[:len(data)] = data return len(data)