PDirect.py 7.8 KB

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