X Tutup
Skip to content

Commit 06d8af0

Browse files
authored
v1.4.1
1 parent 3ff912a commit 06d8af0

File tree

4 files changed

+31
-28
lines changed

4 files changed

+31
-28
lines changed

pproxy/__init__.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from pproxy import proto
33

44
__title__ = 'pproxy'
5-
__version__ = "1.5"
5+
__version__ = "1.5.1"
66
__description__ = "Proxy server that can tunnel among remote servers by regex rules."
77
__author__ = "Qian Wenjie"
88
__license__ = "MIT License"
@@ -92,11 +92,11 @@ async def check_server_alive(interval, rserver, verbose):
9292
reader, writer = await asyncio.wait_for(remote.connect(), timeout=SOCKET_TIMEOUT)
9393
except Exception as ex:
9494
if remote.alive:
95-
verbose(f'{remote.bind}: OFFLINE')
95+
verbose(f'{remote.bind} -> OFFLINE')
9696
remote.alive = False
9797
continue
9898
if not remote.alive:
99-
verbose(f'{remote.bind}: ONLINE')
99+
verbose(f'{remote.bind} -> ONLINE')
100100
remote.alive = True
101101
try:
102102
writer.close()
@@ -156,7 +156,7 @@ def main():
156156
parser.add_argument('-i', dest='listen', default=[], action='append', type=uri_compile, help='proxy server setting uri (default: http+socks://:8080/)')
157157
parser.add_argument('-r', dest='rserver', default=[], action='append', type=uri_compile, help='remote server setting uri (default: direct)')
158158
parser.add_argument('-b', dest='block', type=pattern_compile, help='block regex rules')
159-
parser.add_argument('-a', dest='alive', default=0, type=int, help='interval to check remote alive (default: no check)')
159+
parser.add_argument('-a', dest='alived', default=0, type=int, help='interval to check remote alive (default: no check)')
160160
parser.add_argument('-v', dest='v', action='store_true', help='print verbose output')
161161
parser.add_argument('--ssl', dest='sslfile', help='certfile[,keyfile] if server listen in ssl mode')
162162
parser.add_argument('--pac', dest='pac', help='http PAC path')
@@ -193,15 +193,15 @@ def main():
193193
servers = []
194194
for option in args.listen:
195195
print('Serving on', option.bind, 'by', ",".join(i.name for i in option.protos) + ('(SSL)' if option.sslclient else ''), '({}{})'.format(option.cipher.name, ' '+','.join(i.name() for i in option.cipher.plugins) if option.cipher and option.cipher.plugins else '') if option.cipher else '')
196-
handler = functools.partial(functools.partial(proxy_handler, **vars(args)), **vars(option))
196+
handler = functools.partial(proxy_handler, **vars(args), **vars(option))
197197
try:
198198
server = loop.run_until_complete(option.server(handler))
199199
servers.append(server)
200200
except Exception as ex:
201201
print('Start server failed.\n\t==>', ex)
202202
if servers:
203-
if args.alive > 0 and args.rserver:
204-
asyncio.ensure_future(check_server_alive(args.alive, args.rserver, args.verbose if args.v else DUMMY))
203+
if args.alived > 0 and args.rserver:
204+
asyncio.ensure_future(check_server_alive(args.alived, args.rserver, args.verbose if args.v else DUMMY))
205205
try:
206206
loop.run_forever()
207207
except KeyboardInterrupt:

pproxy/cipher.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def name(cls):
2828
return cls.__name__.replace('_Cipher', '').replace('_', '-').lower()
2929

3030
class AEADCipher(BaseCipher):
31+
PACKET_LIMIT = 16*1024-1
3132
def setup_iv(self, iv=None):
3233
self.iv = os.urandom(self.IV_LENGTH) if iv is None else iv
3334
randkey = hmac.new(self.iv, self.key, hashlib.sha1).digest()
@@ -50,24 +51,27 @@ def nonce(self):
5051
def decrypt(self, s):
5152
self._buffer.extend(s)
5253
ret = bytearray()
53-
while 1:
54-
if self._declen is None:
55-
if len(self._buffer) < 2+self.TAG_LENGTH:
56-
break
57-
self._declen = int.from_bytes(self.decrypt_and_verify(self._buffer[:2], self._buffer[2:2+self.TAG_LENGTH]), 'big')
58-
assert self._declen <= 16*1024-1
59-
del self._buffer[:2+self.TAG_LENGTH]
60-
else:
61-
if len(self._buffer) < self._declen+self.TAG_LENGTH:
62-
break
63-
ret.extend(self.decrypt_and_verify(self._buffer[:self._declen], self._buffer[self._declen:self._declen+self.TAG_LENGTH]))
64-
del self._buffer[:self._declen+self.TAG_LENGTH]
65-
self._declen = None
54+
try:
55+
while 1:
56+
if self._declen is None:
57+
if len(self._buffer) < 2+self.TAG_LENGTH:
58+
break
59+
self._declen = int.from_bytes(self.decrypt_and_verify(self._buffer[:2], self._buffer[2:2+self.TAG_LENGTH]), 'big')
60+
assert self._declen <= self.PACKET_LIMIT
61+
del self._buffer[:2+self.TAG_LENGTH]
62+
else:
63+
if len(self._buffer) < self._declen+self.TAG_LENGTH:
64+
break
65+
ret.extend(self.decrypt_and_verify(self._buffer[:self._declen], self._buffer[self._declen:self._declen+self.TAG_LENGTH]))
66+
del self._buffer[:self._declen+self.TAG_LENGTH]
67+
self._declen = None
68+
except Exception:
69+
return bytes([0])
6670
return bytes(ret)
6771
def encrypt(self, s):
6872
ret = bytearray()
69-
for i in range(0, len(s), 16*1024-1):
70-
buf = s[i:i+16*1024-1]
73+
for i in range(0, len(s), self.PACKET_LIMIT):
74+
buf = s[i:i+self.PACKET_LIMIT]
7175
len_chunk, len_tag = self.encrypt_and_digest(len(buf).to_bytes(2, 'big'))
7276
body_chunk, body_tag = self.encrypt_and_digest(buf)
7377
ret.extend(len_chunk+len_tag+body_chunk+body_tag)

pproxy/cipherpy.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ def encrypt(self, data):
264264

265265
for method in (CFBCipher, CFB8Cipher, CFB1Cipher, CTRCipher, OFBCipher, GCMCipher):
266266
for key in (32, 24, 16):
267-
name = 'AES_{}_{}_Cipher'.format(key*8, method.__name__[:-6])
267+
name = f'AES_{key*8}_{method.__name__[:-6]}_Cipher'
268268
globals()[name] = type(name, (method,), dict(KEY_LENGTH=key, IV_LENGTH=key if method is GCMCipher else 16, CIPHER=AES))
269269

270270
class Blowfish(RAW):
@@ -361,8 +361,7 @@ class SEED(RAW):
361361
S1 = base64.b64decode(b'OOgtps/es7ivYFXHRG9rW8NiM7UpoOKn05ERBhy8NkvviGyoF8QW9MJF4dY/PY6YKE72PqX5Dd/YK2Z6Jy/xckLUQcBzZ6yL962AH8osqjTSC+7pXZQY+FeuCMUTzYa5/33BMfWKarHRINcCIgRocQfbnZlhvuZZ3VGQ3Jqjq9CBD0ca4+yNv5Z7XKKhYyNNyJ6cOgwuum6fWvKS80l4zBX7cHV/NRADZG3GdNW06gl2Gf5AEuC9BfoB8CpeqVZDhRSJm7DlSHmX/B6CIYwbX3dUsh0lTwBG7VhS637ayf0wlWU8tuS7fA5QOSYyhGmTN+ckpMtTCofZTIOPzjtKtw==')
362362
G = lambda self, x, M=b'\xfc\xf3\xcf\x3f': sum((self.S0[x&0xff]&M[i]^self.S1[x>>8&0xff]&M[i+1&3]^self.S0[x>>16&0xff]&M[i+2&3]^self.S1[x>>24&0xff]&M[i+3&3])<<i*8 for i in range(4))
363363
def __init__(self, key):
364-
self.e = []
365-
key0, key1 = struct.unpack('>QQ', key)
364+
self.e, key0, key1 = [], *struct.unpack('>QQ', key)
366365
for i, kc in enumerate((0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc, 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf, 0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1, 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b)):
367366
self.e.append((self.G((key0>>32)+(key1>>32)-kc), self.G(key0-key1+kc)))
368367
key0, key1 = (key0, (key1<<8|key1>>56)&(1<<64)-1) if i&1 else ((key0<<56|key0>>8)&(1<<64)-1, key1)

pproxy/proto.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def patch_ota_reader(self, cipher, reader):
6161
async def patched_read():
6262
nonlocal chunk_id
6363
try:
64-
data_len = int.from_bytes((await reader.readexactly(2)), 'big')
64+
data_len = int.from_bytes(await reader.readexactly(2), 'big')
6565
except Exception:
6666
return None
6767
checksum_client = await reader.readexactly(10)
@@ -92,7 +92,7 @@ async def parse(self, header, reader, auth, authtable, reader_cipher, **kw):
9292
assert ota or not reader_cipher or not reader_cipher.ota, 'SS client must support OTA'
9393
if ota and reader_cipher:
9494
checksum = hmac.new(reader_cipher.iv+reader_cipher.key, header+data, hashlib.sha1).digest()
95-
assert checksum[:10] == (await reader.read_n(10)), 'Unknown OTA checksum'
95+
assert checksum[:10] == await reader.read_n(10), 'Unknown OTA checksum'
9696
self.patch_ota_reader(reader_cipher, reader)
9797
return host_name, port, b''
9898
async def connect(self, reader_remote, writer_remote, rauth, host_name, port, initbuf, writer_cipher_r, **kw):
@@ -140,7 +140,7 @@ class HTTP(BaseProtocol):
140140
def correct_header(self, header, **kw):
141141
return header and header.isalpha()
142142
async def parse(self, header, reader, writer, auth, authtable, httpget, **kw):
143-
lines = header + (await reader.read_until(b'\r\n\r\n'))
143+
lines = header + await reader.read_until(b'\r\n\r\n')
144144
headers = lines[:-4].decode().split('\r\n')
145145
method, path, ver = HTTP_LINE.match(headers.pop(0)).groups()
146146
lines = '\r\n'.join(i for i in headers if not i.startswith('Proxy-'))

0 commit comments

Comments
 (0)
X Tutup