X Tutup
Skip to content

Commit ee6a710

Browse files
authored
Add files via upload
1 parent 33d241d commit ee6a710

File tree

2 files changed

+83
-81
lines changed

2 files changed

+83
-81
lines changed

pproxy/__init__.py

Lines changed: 11 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__ = "0.9.9"
5+
__version__ = "1.0.0"
66
__description__ = "Proxy server that can tunnel among remote servers by regex rules."
77
__author__ = "Qian Wenjie"
88
__license__ = "MIT License"
@@ -140,12 +140,16 @@ def main():
140140
for option in args.listen:
141141
print(f'Serving on {option.bind} by {",".join(i.__name__ for i in option.protos)}', '(SSL)' if option.sslclient else '')
142142
handler = functools.partial(proxy_handler, **vars(args), **vars(option))
143-
server = loop.run_until_complete(option.server(handler))
144-
servers.append(server)
145-
try:
146-
loop.run_forever()
147-
except KeyboardInterrupt:
148-
print('exit')
143+
try:
144+
server = loop.run_until_complete(option.server(handler))
145+
servers.append(server)
146+
except Exception as ex:
147+
print(f'Start server failed.\n\t==> {ex}')
148+
if servers:
149+
try:
150+
loop.run_forever()
151+
except KeyboardInterrupt:
152+
print('exit')
149153
if args.auth_tables:
150154
with open('.auth_tables', 'wb') as f:
151155
pickle.dump(args.auth_tables, f, pickle.HIGHEST_PROTOCOL)

pproxy/cipherpy.py

Lines changed: 72 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from pproxy.cipher import BaseCipher
44

55
# Pure Python Ciphers
6-
ROL = lambda a, b: (a<<b)|((a&0xffffffff)>>(32-b))
76

87
class Table_Cipher(BaseCipher):
98
LIBRARY = False
@@ -55,6 +54,7 @@ def setup(self):
5554
self.key = hashlib.md5(self.key + self.iv).digest()
5655
RC4_Cipher.setup(self)
5756

57+
ROL = lambda a, b: a<<b|(a&0xffffffff)>>(32-b)
5858
class ChaCha20_Cipher(StreamCipher):
5959
KEY_LENGTH = 32
6060
IV_LENGTH = 8
@@ -96,10 +96,11 @@ def core(self):
9696

9797
class CFBCipher(StreamCipher):
9898
def setup(self):
99-
self.bit_mode = self.SEGMENT_SIZE % 8 != 0
100-
self.stream = self.core_bit() if self.bit_mode else self.core()
99+
segment_bit = getattr(self, 'SEGMENT_SIZE', self.IV_LENGTH*8)
100+
self.bit_mode = segment_bit % 8 != 0
101+
self.stream = self.core_bit(segment_bit) if self.bit_mode else self.core(segment_bit//8)
101102
self.last = None
102-
self.cipher = self.CIPHER(self.key)
103+
self.cipher = self.CIPHER.new(self.key)
103104
def process(self, s, inv=False):
104105
r = bytearray()
105106
for i in s:
@@ -119,35 +120,39 @@ def encrypt(self, s):
119120
return self.process(s, False)
120121
def decrypt(self, s):
121122
return self.process(s, True)
122-
def core(self):
123+
def core(self, segment_byte):
123124
next_iv = bytearray(self.iv)
124-
segment_byte = self.SEGMENT_SIZE // 8
125125
while 1:
126126
data = self.cipher.encrypt(next_iv)
127127
del next_iv[:segment_byte]
128128
for i in range(segment_byte):
129129
next_iv.append((yield data[i]))
130-
def core_bit(self):
130+
def core_bit(self, segment_bit):
131131
next_iv = int.from_bytes(self.iv, 'big')
132-
mask = (1 << (self.IV_LENGTH*8)) - 1
132+
mask = (1 << self.IV_LENGTH*8) - 1
133133
while 1:
134134
data = self.cipher.encrypt(next_iv.to_bytes(self.IV_LENGTH, 'big'))
135-
next_iv = (next_iv << self.SEGMENT_SIZE) & mask
136-
for i in range(self.SEGMENT_SIZE):
137-
next_iv |= (yield (data[i//8]>>(7-i%8))&1)<<(self.SEGMENT_SIZE-1-i)
135+
next_iv = next_iv<<segment_bit & mask
136+
for i in range(segment_bit):
137+
next_iv |= (yield (data[i//8]>>(7-i%8))&1)<<(segment_bit-1-i)
138+
139+
class CFB8Cipher(CFBCipher):
140+
SEGMENT_SIZE = 8
141+
142+
class CFB1Cipher(CFBCipher):
143+
SEGMENT_SIZE = 1
138144

139145
class CTRCipher(StreamCipher):
140146
def setup(self):
141147
self.stream = self.core()
142-
self.cipher = self.CIPHER(self.key)
148+
self.cipher = self.CIPHER.new(self.key)
143149
def encrypt(self, s):
144150
return bytes(i^next(self.stream) for i in s)
145151
decrypt = encrypt
146152
def core(self):
147153
next_iv = int.from_bytes(self.iv, 'big')
148154
while 1:
149-
data = self.cipher.encrypt(next_iv.to_bytes(self.IV_LENGTH, 'big'))
150-
yield from data
155+
yield from self.cipher.encrypt(next_iv.to_bytes(self.IV_LENGTH, 'big'))
151156
next_iv = 0 if next_iv >= (1<<(self.IV_LENGTH*8))-1 else next_iv+1
152157

153158
class OFBCipher(CTRCipher):
@@ -157,94 +162,53 @@ def core(self):
157162
data = self.cipher.encrypt(data)
158163
yield from data
159164

160-
class AES:
165+
class RAW:
166+
CACHE = {}
167+
@classmethod
168+
def new(cls, key):
169+
if key in cls.CACHE:
170+
return cls.CACHE[key]
171+
ret = cls.CACHE[key] = cls(key)
172+
return ret
173+
174+
class AES(RAW):
161175
g1 = base64.b64decode(b'Y3x3e/Jrb8UwAWcr/terdsqCyX36WUfwrdSir5ykcsC3/ZMmNj/3zDSl5fFx2DEVBMcjwxiWBZoHEoDi6yeydQmDLBobblqgUjvWsynjL4RT0QDtIPyxW2rLvjlKTFjP0O+q+0NNM4VF+QJ/UDyfqFGjQI+SnTj1vLbaIRD/89LNDBPsX5dEF8Snfj1kXRlzYIFP3CIqkIhG7rgU3l4L2+AyOgpJBiRcwtOsYpGV5HnnyDdtjdVOqWxW9Opleq4IunglLhymtMbo3XQfS72LinA+tWZIA/YOYTVXuYbBHZ7h+JgRadmOlJseh+nOVSjfjKGJDb/mQmhBmS0PsFS7Fg==')
162176
g2 = [((a<<1)&0xff)^0x1b if a&0x80 else a<<1 for a in g1]
163177
g3 = [a^(((a<<1)&0xff)^0x1b if a&0x80 else a<<1) for a in g1]
164178
Rcon = base64.b64decode(b'jQECBAgQIECAGzZs2KtNmi9evGPGlzVq1LN9+u/FkTly5NO9YcKfJUqUM2bMgx06dOjL')
165179
shifts = tuple((j,j&3|((j>>2)+(j&3))*4&12,(j+3)&3|((j>>2)+((j+3)&3))*4&12,(j+2)&3|((j>>2)+((j+2)&3))*4&12,(j+1)&3|((j>>2)+((j+1)&3))*4&12) for j in range(16))
166180
def __init__(self, key):
167-
size = len(key)
181+
size, ekey = len(key), bytearray(key)
168182
nbr = {16:10, 24:12, 32:14}[size]
169-
ekey = bytearray(key)
170183
while len(ekey) < 16*(nbr+1):
171184
t = ekey[-4:]
172185
if len(ekey) % size == 0:
173186
t = [self.g1[i] for i in t[1:]+t[:1]]
174187
t[0] ^= self.Rcon[len(ekey)//size%51]
175188
if size == 32 and len(ekey) % size == 16:
176189
t = [self.g1[i] for i in t]
177-
for m in t:
178-
ekey.append(ekey[-size] ^ m)
190+
ekey.extend(m^ekey[i-size] for i, m in enumerate(t))
179191
self.ekey = tuple(ekey[i*16:i*16+16] for i in range(nbr+1))
180192
def encrypt(self, data):
181193
s = [data[j]^self.ekey[0][j] for j in range(16)]
182194
for key in self.ekey[1:-1]:
183195
s = [self.g2[s[a]]^self.g1[s[b]]^self.g1[s[c]]^self.g3[s[d]]^key[j] for j,a,b,c,d in self.shifts]
184196
return bytes(self.g1[s[self.shifts[j][1]]]^self.ekey[-1][j] for j in range(16))
185197

186-
class AES_256_CFB_Cipher(CFBCipher):
187-
KEY_LENGTH = 32
188-
IV_LENGTH = 16
189-
SEGMENT_SIZE = IV_LENGTH*8
190-
CIPHER = AES
191-
192-
class AES_192_CFB_Cipher(AES_256_CFB_Cipher):
193-
KEY_LENGTH = 24
194-
195-
class AES_128_CFB_Cipher(AES_256_CFB_Cipher):
196-
KEY_LENGTH = 16
197-
198-
class AES_256_CFB8_Cipher(AES_256_CFB_Cipher):
199-
SEGMENT_SIZE = 8
200-
201-
class AES_192_CFB8_Cipher(AES_256_CFB8_Cipher):
202-
KEY_LENGTH = 24
203-
204-
class AES_128_CFB8_Cipher(AES_256_CFB8_Cipher):
205-
KEY_LENGTH = 16
206-
207-
class AES_256_CFB1_Cipher(AES_256_CFB_Cipher):
208-
SEGMENT_SIZE = 1
209-
210-
class AES_192_CFB1_Cipher(AES_256_CFB1_Cipher):
211-
KEY_LENGTH = 24
212-
213-
class AES_128_CFB1_Cipher(AES_256_CFB1_Cipher):
214-
KEY_LENGTH = 16
198+
for method in (CFBCipher, CFB8Cipher, CFB1Cipher, CTRCipher, OFBCipher):
199+
for key in (32, 24, 16):
200+
name = f'AES_{key*8}_{method.__name__[:-6]}_Cipher'
201+
globals()[name] = type(name, (method,), dict(KEY_LENGTH=key, IV_LENGTH=16, CIPHER=AES))
215202

216-
class AES_256_CTR_Cipher(CTRCipher):
217-
KEY_LENGTH = 32
218-
IV_LENGTH = 16
219-
CIPHER = AES
220-
221-
class AES_192_CTR_Cipher(AES_256_CTR_Cipher):
222-
KEY_LENGTH = 24
223-
224-
class AES_128_CTR_Cipher(AES_256_CTR_Cipher):
225-
KEY_LENGTH = 16
226-
227-
class AES_256_OFB_Cipher(OFBCipher):
228-
KEY_LENGTH = 32
229-
IV_LENGTH = 16
230-
CIPHER = AES
231-
232-
class AES_192_OFB_Cipher(AES_256_OFB_Cipher):
233-
KEY_LENGTH = 24
234-
235-
class AES_128_OFB_Cipher(AES_256_OFB_Cipher):
236-
KEY_LENGTH = 16
237-
238-
class Blowfish:
203+
class Blowfish(RAW):
239204
P = None
240205
@staticmethod
241206
def hex_pi():
242207
N, n, d = 0, 0, 1
243-
while 1:
208+
for N in range(1<<20):
244209
xn, xd = 120*N**2 + 151*N + 47, 512*N**4 + 1024*N**3 + 712*N**2 + 194*N + 15
245210
n, d = ((16 * n * xd) + (xn * d)) % (d * xd), d * xd
246211
yield b'%x' % (16 * n // d)
247-
N += 1
248212
def __init__(self, key):
249213
if not self.P:
250214
pi = self.hex_pi()
@@ -265,8 +229,42 @@ def encrypt(self, s):
265229
class BF_CFB_Cipher(CFBCipher):
266230
KEY_LENGTH = 16
267231
IV_LENGTH = 8
268-
SEGMENT_SIZE = IV_LENGTH*8
269232
CIPHER = Blowfish
270233

234+
class Camellia(RAW):
235+
S1 = base64.b64decode(b'cIIs7LMnwOXkhVc16gyuQSPva5NFGaUh7Q5PTh1lkr2GuK+PfOsfzj4w3F9exQsapuE5ytVHXT3ZAVrWUVZsTYsNmmb7zLAtdBIrIPCxhJnfTMvCNH52BW23qTHRFwTXFFg6Yd4bERwyD5wWUxjyIv5Ez7LDtXqRJAjoqGD8aVCq0KB9oYlil1RbHpXg/2TSEMQASKP3dduKA+baCT/dlIdcgwLNSpAzc2f2851/v+JSm9gmyDfGO4GWb0sTvmMu6XmnjJ9uvI4p9fm2L/20WXiYBmrnRnG61CWrQoiijfpyB7lV+O6sCjZJKmg8OPGkQCjTe7vJQ8EV4630d8eAng==')
236+
S2, S3, S4 = bytes(i>>7|(i&0x7f)<<1 for i in S1), bytes(i>>1|(i&1)<<7 for i in S1), S1[::2]+S1[1::2]
237+
S = (S1, S4, S3, S2, S4, S3, S2, S1)
238+
KS = base64.b64decode(b'AAIICiAiKCpIShETGTM5OxIQQkBKSCMhKykAAgwOJCYoKkRGTE4RExkbMTM1Nz0/EhAaGEZESkgjIS8t')
239+
KS = tuple((i%16//4, i%4*32, (64,51,49,36,34)[i>>4]) for i in KS)
240+
def R(self, s, t):
241+
t = sum(S[((t^s>>64)>>(i*8))&0xff]<<(i*8+32)%64 for i,S in enumerate(self.S))
242+
t = t^t>>32<<8&0xffffff00^t>>56^((t>>32<<56|t>>8)^t<<48)&0xffff<<48^(t>>8^t<<16)&0xffff<<32
243+
return (t^t>>8&0xff<<24^t>>40^t<<16&0xff<<56^t<<56^(t>>32<<48^t>>16^t<<24)&0xffffff<<32^s)<<64&(1<<128)-1|s>>64
244+
def __init__(self, key):
245+
q, R = [int.from_bytes(key[:16], 'big'), int.from_bytes(key[16:], 'big'), 0, 0], self.R
246+
q[1] = q[1]<<64|q[1]^((1<<64)-1) if len(key)==24 else q[1]
247+
q[2] = R(R(R(R(q[0]^q[1],0xa09e667f3bcc908b),0xb67ae8584caa73b2)^q[0],0xc6ef372fe94f82be),0x54ff53a5f1d36f1c)
248+
q[3] = R(R(q[2]^q[1],0x10e527fade682d1d),0xb05688c2b3e6c1fd)
249+
nr, ks = (22, self.KS[:26]) if len(key)==16 else (29, self.KS[26:])
250+
e = [(q[n]<<m>>o|q[n]>>128-m+o)&(1<<64)-1 for n, m, o in ks]
251+
self.e = [e[i+i//7]<<64|e[i+i//7+1] if i%7==0 else e[i+i//7+1] for i in range(nr)]
252+
def encrypt(self, s):
253+
s = int.from_bytes(s, 'big')^self.e[0]
254+
for idx, k in enumerate(self.e[1:-1]):
255+
s = s^((s&k)>>95&0xfffffffe|(s&k)>>127)<<64^((s&k)<<1&~1<<96^(s&k)>>31^s<<32|k<<32)&0xffffffff<<96 ^ ((s|k)&0xffffffff)<<32^((s|k)<<1^s>>31)&k>>31&0xfffffffe^((s|k)>>31^s>>63)&k>>63&1 if (idx+1)%7==0 else self.R(s, k)
256+
return (s>>64^(s&(1<<64)-1)<<64^self.e[-1]).to_bytes(16, 'big')
257+
258+
class Camellia_256_CFB_Cipher(CFBCipher):
259+
KEY_LENGTH = 32
260+
IV_LENGTH = 16
261+
CIPHER = Camellia
262+
263+
class Camellia_192_CFB_Cipher(Camellia_256_CFB_Cipher):
264+
KEY_LENGTH = 24
265+
266+
class Camellia_128_CFB_Cipher(Camellia_256_CFB_Cipher):
267+
KEY_LENGTH = 16
268+
271269
MAP = {name[:-7].replace('_', '-').lower()+'-py': cls for name, cls in globals().items() if name.endswith('_Cipher')}
272270

0 commit comments

Comments
 (0)
X Tutup