def do_GET(self): #TODO# Can we really just process GET requests? print 'DEBUG: Request path is %s' % (str(self.path), ) uri = path_re.match(self.path) if uri is None: self.send_response(400, 'Bad Request') return (uri, ) = uri.groups() uri = urllib.unquote_plus(uri) uri = urlparse.urlparse(uri) print 'DEBUG: URI to connect to is', uri # sox = socket.socket (socket.AF_INET6, socket.SOCK_STREAM) sox = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sox.connect((uri.hostname, int(uri.port or '443'))) cnx = tlspool.Connection(cryptsocket=sox) cnx.tlsdata.flags = (tlspool.PIOF_STARTTLS_LOCALROLE_CLIENT | tlspool.PIOF_STARTTLS_REMOTEROLE_SERVER | tlspool.PIOF_STARTTLS_FORK | tlspool.PIOF_STARTTLS_DETACH) cnx.tlsdata.remoteid = uri.hostname cnx.tlsdata.ipproto = socket.IPPROTO_TCP cnx.tlsdata.service = 'http' try: sox = cnx.starttls() except: self.send_response(403, 'Forbidden') return print 'DEBUG: Sending headers:\n%s', str(self.headers) sox.send(str(self.headers) + '\r\n') #TODO# Probably too simple self.end_headers() self.send_response(200, 'OK') self.wfile.write(sox.read())
def run(self): """Start the TLS exchange. Both client and server will run one of these, either in the same process (demo mode, -d) or each in their own process (on their own machine) in modes -c and -s, respectively. """ pingdata = (tlspool.TLSPOOL_IDENTITY_V2, tlspool.PIOF_FACILITY_ALL_CURRENT) pingdata = tlspool.ping(*pingdata) facilities = pingdata[1] # Ensure that TLS is supported by TLS Pool and client libraries assert (facilities & tlspool.PIOF_FACILITY_STARTTLS) if self.server: roles = tlspool.PIOF_STARTTLS_LOCALROLE_SERVER | tlspool.PIOF_STARTTLS_REMOTEROLE_CLIENT | tlspool.PIOF_STARTTLS_DETACH else: roles = tlspool.PIOF_STARTTLS_LOCALROLE_CLIENT | tlspool.PIOF_STARTTLS_REMOTEROLE_SERVER | tlspool.PIOF_STARTTLS_DETACH tlsdata = { 'service': 'telnet', 'flags': roles, 'localid': self.localid, 'remoteid': self.remotid, 'ipproto': socket.IPPROTO_TCP, 'timeout': 0xffffffff # ~0 means: Infinite timeout } self.cnx = tlspool.Connection(self.tlsint, **tlsdata) try: self.hold = self.cnx.starttls() except: print 'Failure from STARTTLS' raise
def wrap(self, extsock): """Wrap the given socket in TLS and return the result, along with WSGI environment variables in a tuple. """ fl = (tlspool.PIOF_STARTTLS_LOCALROLE_SERVER | tlspool.PIOF_STARTTLS_REMOTEROLE_CLIENT | tlspool.PIOF_STARTTLS_IGNORE_REMOTEID) hdl = tlspool.Connection(extsock, service='http', flags=fl) hdl.tlsdata.localid = self.server_name intsock = hdl.starttls() env = { 'wsgi.url_scheme': 'https', 'HTTPS': 'on', 'LOCAL_USER': hdl.tlsdata.localid, 'REMOTE_USER': hdl.tlsdata.remoteid, } return intsock, env
def via_tlspool(self, host, port, path, post_body=None): print 'DEBUG: host to connect to is: %s' % host if self.conn is None: print 'DEBUG: creating new socket' # sox = socket.socket (socket.AF_INET6, socket.SOCK_STREAM) sox = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sox.connect((host, int(port or 443))) cnx = tlspool.Connection(cryptsocket=sox) cnx.tlsdata.flags = (tlspool.PIOF_STARTTLS_LOCALROLE_CLIENT | tlspool.PIOF_STARTTLS_REMOTEROLE_SERVER) cnx.tlsdata.remoteid = host cnx.tlsdata.ipproto = socket.IPPROTO_TCP cnx.tlsdata.service = 'http' try: sox = cnx.starttls() self.conn = httplib.HTTPConnection(host, port=port) self.conn.set_debuglevel(1) self.conn.sock = sox except: self.send_response(403, 'Forbidden') return self.conn.putrequest(self.command, path, True, True) for hdnm in self.headers: self.conn.putheader(hdnm, self.headers[hdnm]) content_length = self.headers.getheader('Content-Length') post_body = None if not content_length is None: post_body = self.rfile.read(int(content_length)) self.conn.endheaders(message_body=post_body) response = self.conn.getresponse() self.send_response(response.status, response.reason) for header in response.getheaders(): (headername, headervalue) = header self.send_header(headername, headervalue) self.end_headers() data = response.read() print 'DEBUG: data is %d bytes long' % len(data) self.wfile.write(data) print 'DEBUG: exiting via_tlspool'
import tlspool if len(sys.argv) >= 2: website = sys.argv[1] else: website = 'nlnet.nl' if len(sys.argv) >= 3: tlspool.open_poolhandle(sys.argv[2]) sox = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) sox.connect((website, 443)) cli2srv = (tlspool.PIOF_STARTTLS_LOCALROLE_CLIENT | tlspool.PIOF_STARTTLS_REMOTEROLE_SERVER) cnx = tlspool.Connection(sox, service='http', flags=cli2srv) cnx.tlsdata.localid = '*****@*****.**' cnx.tlsdata.remoteid = website web = cnx.starttls() web.send('GET / HTTP/1.0\r\nHost: ' + website + '\r\n\r\n') dta = web.recv(4096) while dta != '': sys.stdout.write(dta) dta = web.recv(4096) cnx.close()
def do_CONNECT(self): # # Parse the request line, CONNECT servername:port HTTP/1.1 # try: servername, port = self.path.split(':') port = int(port) except: self.send_response(400, 'Bad Request') return # # Connect to the server # # srvtls = socket.socket (socket.AF_INET6, socket.SOCK_STREAM, 0) # if srvtls.connect_ex ( (servername, port) ) != 0: # srvtls.close () if True: srvtls = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) if srvtls.connect_ex((servername, port)) != 0: srvtls.close() srvtls = -1 if srvtls == -1: self.send_response(408, 'Request Timeout') return # # Start TLS on the server connection through the TLS Pool. # This is done without indicating or limiting the client # identity, and anything the TLS Pool wants to do to set # that is permitted. This enables the user to benefit from # the TLS Pool's plethora of connection options. # #OLD# # Since the socket library implements these differently from #OLD# # common sockets (?!?) we shall apply Python's usual wrapper. #OLD# # #OLD# _srvtxt, _clitxt = socket.socketpair () #OLD# srvtxt = socket._socketobject (_sock=_srvtxt) #OLD# clitxt = socket._socketobject (_sock=_clitxt) #OLD# print 'server TLS socket ::', type (srvtls) #OLD# print 'server TXT socket ::', type (srvtxt) # print 'server TXT plainfd =', srvtxt.fromfd #OLD# srvcnx = tlspool.Connection (cryptsocket=srvtls, plainsocket=srvtxt) srvcnx = tlspool.Connection(cryptsocket=srvtls) srvcnx.tlsdata.flags = (tlspool.PIOF_STARTTLS_LOCALROLE_CLIENT | tlspool.PIOF_STARTTLS_REMOTEROLE_SERVER | tlspool.PIOF_STARTTLS_FORK | tlspool.PIOF_STARTTLS_DETACH) srvcnx.tlsdata.remoteid = servername srvcnx.tlsdata.ipproto = socket.IPPROTO_TCP srvcnx.tlsdata.service = 'http' try: clitxt = srvcnx.starttls() except: self.send_response(403, 'Forbidden') return # # Report the success of setting up the backend connection # self.send_response(200, 'Connection Established') self.end_headers() # # Now pass the client connection through the TLS Pool too. # The plaintext connections from the client and server will # be connected. # clitls = self.wfile #OLD# print 'client TLS socket ::', type (clitls) #OLD# print 'client TXT socket ::', type (clitxt) clicnx = tlspool.Connection(cryptsocket=clitls, plainsocket=clitxt) clicnx.tlsdata.flags = (tlspool.PIOF_STARTTLS_LOCALROLE_SERVER | tlspool.PIOF_STARTTLS_REMOTEROLE_CLIENT | tlspool.PIOF_STARTTLS_FORK | tlspool.PIOF_STARTTLS_DETACH | tlspool.PIOF_STARTTLS_IGNORE_REMOTEID | tlspool.PIOF_STARTTLS_LOCALID_ONTHEFLY) clicnx.tlsdata.localid = servername clicnx.tlsdata.ipproto = socket.IPPROTO_TCP clicnx.tlsdata.service = 'http' try: clicnx.starttls() finally: srvcnx.close()