ws-stunnel 7.4 KB

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