Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I've investigated the problem a little bit. It's easy to make a socket behave like two different servers (depending on the type of data received). What's bad here is that python's _ssl library reads directly from socket._socket, which is a native python object and therefore can't be hooked normally.</p> <p>One way is to write a C module that will hook native python socket. Another solution is to have 1 frontend and 2 backends (https and http). Frontend listens on 4443 and decides whether it should commutate connection with https backend or http backend. You can add the same handlers to the both servers and they'll behave in the same way. Another problem is that on backend we don't know the ip of the client, but there are workarounds (Like the dict {(Frontend to backend source port number): Client IP} that frontend will be keeping and backends will be looking at).</p> <p>Comparing with the C solution, the second looks quite dirty, but here it is. </p> <pre><code>import BaseHTTPServer, SimpleHTTPServer import ssl import socket import select import threading FRONTEND_PORT = 4443 BACKEND_PORT_SSL = 44431 BACKEND_PORT_HTTP = 44432 HOST = 'localhost' httpd_ssl = BaseHTTPServer.HTTPServer((HOST, BACKEND_PORT_SSL), SimpleHTTPServer.SimpleHTTPRequestHandler) httpd_ssl.socket = ssl.wrap_socket (httpd_ssl.socket, certfile='key.pem', server_side=True) httpd_direct = BaseHTTPServer.HTTPServer((HOST, BACKEND_PORT_HTTP), SimpleHTTPServer.SimpleHTTPRequestHandler) def serve_forever(http_server): http_server.serve_forever() def categorize(sock, addr): data = sock.recv(1) if data == '\x16': port = BACKEND_PORT_SSL else: port = BACKEND_PORT_HTTP other_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) other_sock.connect((HOST, port)) other_sock.send(data) inp = [sock, other_sock] select_timeout = 1.0 try: while 1: r,w,x = select.select(inp,[],[],select_timeout) if not r: continue for s in r: o_s = inp[1] if inp[0]==s else inp[0] buf = s.recv(4096) if not buf: raise socket.error o_s.send(buf) except socket.error: pass finally: for s in inp: s.close() threading.Thread(target=serve_forever, args=(httpd_ssl,)).start() threading.Thread(target=serve_forever, args=(httpd_direct,)).start() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((HOST, FRONTEND_PORT)) sock.listen(10) while True: conn, addr = sock.accept() threading.Thread(target=categorize, args=(conn, addr)).start() </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload