1
0

PPriv.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Edit By GlEmYsSoN & @e8th4ever
  4. from pprint import pprint
  5. import sys
  6. import http.client
  7. from socketserver import ThreadingMixIn
  8. from http.server import HTTPServer, BaseHTTPRequestHandler
  9. from threading import Lock, Timer
  10. from io import StringIO
  11. from urllib.parse import urlsplit
  12. import socket
  13. import select
  14. import gzip
  15. import zlib
  16. import re
  17. import traceback
  18. import subprocess
  19. subprocess.call("clear",shell=True)
  20. if sys.argv[2:]:
  21. msg1 = sys.argv[2]
  22. else:
  23. msg1 = 'ADM-ULTIMATE'
  24. if sys.argv[3:]:
  25. server = sys.argv[3]
  26. else:
  27. server = "127.0.0.1"
  28. msg2 = 'Server Forbidden'
  29. class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
  30. address_family = socket.AF_INET
  31. def handle_error(self, request, client_address):
  32. print('-'*40, file=sys.stderr)
  33. print('Exception happened during processing of request from', client_address, file=sys.stderr)
  34. traceback.print_exc()
  35. print('-'*40, file=sys.stderr)
  36. class ThreadingHTTPServer6(ThreadingHTTPServer):
  37. address_family = socket.AF_INET6
  38. class SimpleHTTPProxyHandler(BaseHTTPRequestHandler):
  39. global_lock = Lock()
  40. conn_table = {}
  41. timeout = 300
  42. upstream_timeout = 300
  43. proxy_via = None
  44. def log_error(self, format, *args):
  45. if format == "Request timed out: %r":
  46. return
  47. self.log_message(format, *args)
  48. def do_CONNECT(self):
  49. req = self
  50. reqbody = None
  51. if ':22' in req.path:
  52. hostip = req.path.replace(':22', '')
  53. elif ':443' in req.path:
  54. hostip = req.path.replace(':443', '')
  55. req.path = "https://%s/" % req.path.replace(':443', '')
  56. replaced_reqbody = self.request_handler(req, reqbody)
  57. if replaced_reqbody is True:
  58. return
  59. u = urlsplit(req.path)
  60. address = (u.hostname, u.port or 443)
  61. try:
  62. conn = socket.create_connection(address)
  63. except socket.error:
  64. return
  65. self.send_response(200, msg1)
  66. self.send_header('Connection', 'close')
  67. self.end_headers()
  68. conns = [self.connection, conn]
  69. keep_connection = True
  70. while keep_connection:
  71. if not server.find(hostip) != -1:
  72. self.send_error(403, msg2)
  73. self.close_connection
  74. keep_connection = False
  75. rlist, wlist, xlist = select.select(conns, [], conns, self.timeout)
  76. if xlist:
  77. break
  78. for r in rlist:
  79. other = conns[1] if r is conns[0] else conns[0]
  80. data = r.recv(8192)
  81. if data:
  82. other.sendall(data)
  83. keep_connection = True
  84. conn.close()
  85. def do_HEAD(self):
  86. self.do_SPAM()
  87. def do_GET(self):
  88. self.do_SPAM()
  89. def do_POST(self):
  90. self.do_SPAM()
  91. def do_SPAM(self):
  92. req = self
  93. content_length = int(req.headers.get('Content-Length', 0))
  94. if content_length > 0:
  95. reqbody = self.rfile.read(content_length)
  96. else:
  97. reqbody = None
  98. replaced_reqbody = self.request_handler(req, reqbody)
  99. if replaced_reqbody is True:
  100. return
  101. elif replaced_reqbody is not None:
  102. reqbody = replaced_reqbody
  103. if 'Content-Length' in req.headers:
  104. req.headers['Content-Length'] = str(len(reqbody))
  105. self.remove_hop_by_hop_headers(req.headers)
  106. if self.upstream_timeout:
  107. req.headers['Connection'] = 'Keep-Alive'
  108. else:
  109. req.headers['Connection'] = 'close'
  110. if self.proxy_via:
  111. self.modify_via_header(req.headers)
  112. try:
  113. res, resdata = self.request_to_upstream_server(req, reqbody)
  114. except socket.error:
  115. return
  116. content_encoding = res.headers.get('Content-Encoding', 'identity')
  117. resbody = self.decode_content_body(resdata, content_encoding)
  118. replaced_resbody = self.response_handler(req, reqbody, res, resbody)
  119. if replaced_resbody is True:
  120. return
  121. elif replaced_resbody is not None:
  122. resdata = self.encode_content_body(replaced_resbody, content_encoding)
  123. if 'Content-Length' in res.headers:
  124. res.headers['Content-Length'] = str(len(resdata))
  125. resbody = replaced_resbody
  126. self.remove_hop_by_hop_headers(res.headers)
  127. if self.timeout:
  128. res.headers['Connection'] = 'Keep-Alive'
  129. else:
  130. res.headers['Connection'] = 'close'
  131. if self.proxy_via:
  132. self.modify_via_header(res.headers)
  133. self.send_response(res.status, res.reason)
  134. for k, v in list(res.headers.items()):
  135. if k == 'set-cookie':
  136. for value in self.split_set_cookie_header(v):
  137. self.send_header(k, value)
  138. else:
  139. self.send_header(k, v)
  140. self.end_headers()
  141. if self.command != 'HEAD':
  142. self.wfile.write(resdata)
  143. with self.global_lock:
  144. self.save_handler(req, reqbody, res, resbody)
  145. def request_to_upstream_server(self, req, reqbody):
  146. u = urlsplit(req.path)
  147. origin = (u.scheme, u.netloc)
  148. req.headers['Host'] = u.netloc
  149. selector = "%s?%s" % (u.path, u.query) if u.query else u.path
  150. while True:
  151. with self.lock_origin(origin):
  152. conn = self.open_origin(origin)
  153. try:
  154. conn.request(req.command, selector, reqbody, headers=dict(req.headers))
  155. except socket.error:
  156. self.close_origin(origin)
  157. raise
  158. try:
  159. res = conn.getresponse(buffering=True)
  160. except http.client.BadStatusLine as e:
  161. if e.line == "''":
  162. self.close_origin(origin)
  163. continue
  164. else:
  165. raise
  166. resdata = res.read()
  167. res.headers = res.msg
  168. if not self.upstream_timeout or 'close' in res.headers.get('Connection', ''):
  169. self.close_origin(origin)
  170. else:
  171. self.reset_timer(origin)
  172. return res, resdata
  173. def lock_origin(self, origin):
  174. d = self.conn_table.setdefault(origin, {})
  175. if not 'lock' in d:
  176. d['lock'] = Lock()
  177. return d['lock']
  178. def open_origin(self, origin):
  179. conn = self.conn_table[origin].get('connection')
  180. if not conn:
  181. scheme, netloc = origin
  182. if scheme == 'https':
  183. conn = http.client.HTTPSConnection(netloc)
  184. else:
  185. conn = http.client.HTTPConnection(netloc)
  186. self.reset_timer(origin)
  187. self.conn_table[origin]['connection'] = conn
  188. return conn
  189. def reset_timer(self, origin):
  190. timer = self.conn_table[origin].get('timer')
  191. if timer:
  192. timer.cancel()
  193. if self.upstream_timeout:
  194. timer = Timer(self.upstream_timeout, self.close_origin, args=[origin])
  195. timer.daemon = True
  196. timer.start()
  197. else:
  198. timer = None
  199. self.conn_table[origin]['timer'] = timer
  200. def close_origin(self, origin):
  201. timer = self.conn_table[origin]['timer']
  202. if timer:
  203. timer.cancel()
  204. conn = self.conn_table[origin]['connection']
  205. conn.close()
  206. del self.conn_table[origin]['connection']
  207. def remove_hop_by_hop_headers(self, headers):
  208. hop_by_hop_headers = ['Connection', 'Keep-Alive', 'Proxy-Authenticate', 'Proxy-Authorization', 'TE', 'Trailers', 'Trailer', 'Transfer-Encoding', 'Upgrade']
  209. connection = headers.get('Connection')
  210. if connection:
  211. keys = re.split(r',\s*', connection)
  212. hop_by_hop_headers.extend(keys)
  213. for k in hop_by_hop_headers:
  214. if k in headers:
  215. del headers[k]
  216. def modify_via_header(self, headers):
  217. via_string = "%s %s" % (self.protocol_version, self.proxy_via)
  218. via_string = re.sub(r'^HTTP/', '', via_string)
  219. original = headers.get('Via')
  220. if original:
  221. headers['Via'] = original + ', ' + via_string
  222. else:
  223. headers['Via'] = via_string
  224. def decode_content_body(self, data, content_encoding):
  225. if content_encoding in ('gzip', 'x-gzip'):
  226. io = StringIO(data)
  227. with gzip.GzipFile(fileobj=io) as f:
  228. body = f.read()
  229. elif content_encoding == 'deflate':
  230. body = zlib.decompress(data)
  231. elif content_encoding == 'identity':
  232. body = data
  233. else:
  234. raise Exception("Unknown Content-Encoding: %s" % content_encoding)
  235. return body
  236. def encode_content_body(self, body, content_encoding):
  237. if content_encoding in ('gzip', 'x-gzip'):
  238. io = StringIO()
  239. with gzip.GzipFile(fileobj=io, mode='wb') as f:
  240. f.write(body)
  241. data = io.getvalue()
  242. elif content_encoding == 'deflate':
  243. data = zlib.compress(body)
  244. elif content_encoding == 'identity':
  245. data = body
  246. else:
  247. raise Exception("Unknown Content-Encoding: %s" % content_encoding)
  248. return data
  249. def split_set_cookie_header(self, value):
  250. re_cookies = r'([^=]+=[^,;]+(?:;\s*Expires=[^,]+,[^,;]+|;[^,;]+)*)(?:,\s*)?'
  251. return re.findall(re_cookies, value, flags=re.IGNORECASE)
  252. def request_handler(self, req, reqbody):
  253. pass
  254. def response_handler(self, req, reqbody, res, resbody):
  255. pass
  256. def save_handler(self, req, reqbody, res, resbody):
  257. pass
  258. def test(HandlerClass=SimpleHTTPProxyHandler, ServerClass=ThreadingHTTPServer, protocol="HTTP/1.1"):
  259. port = int(sys.argv[1])
  260. server_address = ('', port)
  261. HandlerClass.protocol_version = protocol
  262. httpd = ServerClass(server_address, HandlerClass)
  263. sa = httpd.socket.getsockname()
  264. print("Servidor: " + str(sa[0]) + " Porta " + str(sa[1]))
  265. httpd.serve_forever()
  266. if __name__ == '__main__':
  267. test()