edu-op.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #!/usr/bin/python
  2. import socket, threading, thread, select, signal, sys, time, getopt
  3. # Listen
  4. LISTENING_ADDR = '0.0.0.0'
  5. LISTENING_PORT = sys.argv[1]
  6. # Pass
  7. PASS = ''
  8. # CONST
  9. BUFLEN = 4096 * 4
  10. TIMEOUT = 60
  11. DEFAULT_HOST = '127.0.0.1:1194'
  12. RESPONSE = 'HTTP/1.1 101 <b><u><font color="cyan">Setup By Geo Gabut</font></b>\r\n\r\nContent-Length: 104857600000\r\n\r\n'
  13. class Server(threading.Thread):
  14. def __init__(self, host, port):
  15. threading.Thread.__init__(self)
  16. self.running = False
  17. self.host = host
  18. self.port = port
  19. self.threads = []
  20. self.threadsLock = threading.Lock()
  21. self.logLock = threading.Lock()
  22. def run(self):
  23. self.soc = socket.socket(socket.AF_INET)
  24. self.soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  25. self.soc.settimeout(2)
  26. intport = int(self.port)
  27. self.soc.bind((self.host, intport))
  28. self.soc.listen(0)
  29. self.running = True
  30. try:
  31. while self.running:
  32. try:
  33. c, addr = self.soc.accept()
  34. c.setblocking(1)
  35. except socket.timeout:
  36. continue
  37. conn = ConnectionHandler(c, self, addr)
  38. conn.start()
  39. self.addConn(conn)
  40. finally:
  41. self.running = False
  42. self.soc.close()
  43. def printLog(self, log):
  44. self.logLock.acquire()
  45. print log
  46. self.logLock.release()
  47. def addConn(self, conn):
  48. try:
  49. self.threadsLock.acquire()
  50. if self.running:
  51. self.threads.append(conn)
  52. finally:
  53. self.threadsLock.release()
  54. def removeConn(self, conn):
  55. try:
  56. self.threadsLock.acquire()
  57. self.threads.remove(conn)
  58. finally:
  59. self.threadsLock.release()
  60. def close(self):
  61. try:
  62. self.running = False
  63. self.threadsLock.acquire()
  64. threads = list(self.threads)
  65. for c in threads:
  66. c.close()
  67. finally:
  68. self.threadsLock.release()
  69. class ConnectionHandler(threading.Thread):
  70. def __init__(self, socClient, server, addr):
  71. threading.Thread.__init__(self)
  72. self.clientClosed = False
  73. self.targetClosed = True
  74. self.client = socClient
  75. self.client_buffer = ''
  76. self.server = server
  77. self.log = 'Connection: ' + str(addr)
  78. def close(self):
  79. try:
  80. if not self.clientClosed:
  81. self.client.shutdown(socket.SHUT_RDWR)
  82. self.client.close()
  83. except:
  84. pass
  85. finally:
  86. self.clientClosed = True
  87. try:
  88. if not self.targetClosed:
  89. self.target.shutdown(socket.SHUT_RDWR)
  90. self.target.close()
  91. except:
  92. pass
  93. finally:
  94. self.targetClosed = True
  95. def run(self):
  96. try:
  97. self.client_buffer = self.client.recv(BUFLEN)
  98. hostPort = self.findHeader(self.client_buffer, 'X-Real-Host')
  99. if hostPort == '':
  100. hostPort = DEFAULT_HOST
  101. split = self.findHeader(self.client_buffer, 'X-Split')
  102. if split != '':
  103. self.client.recv(BUFLEN)
  104. if hostPort != '':
  105. passwd = self.findHeader(self.client_buffer, 'X-Pass')
  106. if len(PASS) != 0 and passwd == PASS:
  107. self.method_CONNECT(hostPort)
  108. elif len(PASS) != 0 and passwd != PASS:
  109. self.client.send('HTTP/1.1 400 WrongPass!\r\n\r\n')
  110. elif hostPort.startswith('127.0.0.1') or hostPort.startswith('localhost'):
  111. self.method_CONNECT(hostPort)
  112. else:
  113. self.client.send('HTTP/1.1 403 Forbidden!\r\n\r\n')
  114. else:
  115. print '- No X-Real-Host!'
  116. self.client.send('HTTP/1.1 400 NoXRealHost!\r\n\r\n')
  117. except Exception as e:
  118. self.log += ' - error: ' + e.strerror
  119. self.server.printLog(self.log)
  120. pass
  121. finally:
  122. self.close()
  123. self.server.removeConn(self)
  124. def findHeader(self, head, header):
  125. aux = head.find(header + ': ')
  126. if aux == -1:
  127. return ''
  128. aux = head.find(':', aux)
  129. head = head[aux+2:]
  130. aux = head.find('\r\n')
  131. if aux == -1:
  132. return ''
  133. return head[:aux];
  134. def connect_target(self, host):
  135. i = host.find(':')
  136. if i != -1:
  137. port = int(host[i+1:])
  138. host = host[:i]
  139. else:
  140. if self.method=='CONNECT':
  141. port = 443
  142. else:
  143. port = sys.argv[1]
  144. (soc_family, soc_type, proto, _, address) = socket.getaddrinfo(host, port)[0]
  145. self.target = socket.socket(soc_family, soc_type, proto)
  146. self.targetClosed = False
  147. self.target.connect(address)
  148. def method_CONNECT(self, path):
  149. self.log += ' - CONNECT ' + path
  150. self.connect_target(path)
  151. self.client.sendall(RESPONSE)
  152. self.client_buffer = ''
  153. self.server.printLog(self.log)
  154. self.doCONNECT()
  155. def doCONNECT(self):
  156. socs = [self.client, self.target]
  157. count = 0
  158. error = False
  159. while True:
  160. count += 1
  161. (recv, _, err) = select.select(socs, [], socs, 3)
  162. if err:
  163. error = True
  164. if recv:
  165. for in_ in recv:
  166. try:
  167. data = in_.recv(BUFLEN)
  168. if data:
  169. if in_ is self.target:
  170. self.client.send(data)
  171. else:
  172. while data:
  173. byte = self.target.send(data)
  174. data = data[byte:]
  175. count = 0
  176. else:
  177. break
  178. except:
  179. error = True
  180. break
  181. if count == TIMEOUT:
  182. error = True
  183. if error:
  184. break
  185. def print_usage():
  186. print 'Usage: proxy.py -p <port>'
  187. print ' proxy.py -b <bindAddr> -p <port>'
  188. print ' proxy.py -b 0.0.0.0 -p 80'
  189. def parse_args(argv):
  190. global LISTENING_ADDR
  191. global LISTENING_PORT
  192. try:
  193. opts, args = getopt.getopt(argv,"hb:p:",["bind=","port="])
  194. except getopt.GetoptError:
  195. print_usage()
  196. sys.exit(2)
  197. for opt, arg in opts:
  198. if opt == '-h':
  199. print_usage()
  200. sys.exit()
  201. elif opt in ("-b", "--bind"):
  202. LISTENING_ADDR = arg
  203. elif opt in ("-p", "--port"):
  204. LISTENING_PORT = int(arg)
  205. def main(host=LISTENING_ADDR, port=LISTENING_PORT):
  206. print "\n:-------PythonProxy-------:\n"
  207. print "Listening addr: " + LISTENING_ADDR
  208. print "Listening port: " + str(LISTENING_PORT) + "\n"
  209. print ":-------------------------:\n"
  210. server = Server(LISTENING_ADDR, LISTENING_PORT)
  211. server.start()
  212. while True:
  213. try:
  214. time.sleep(2)
  215. except KeyboardInterrupt:
  216. print 'Stopping...'
  217. server.close()
  218. break
  219. ####### parse_args(sys.argv[1:])
  220. if __name__ == '__main__':
  221. main()