15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""TLS Lite + asyncore.""" 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import asyncore 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from tlslite.TLSConnection import TLSConnection 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from AsyncStateMachine import AsyncStateMachine 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TLSAsyncDispatcherMixIn(AsyncStateMachine): 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """This class can be "mixed in" with an 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L{asyncore.dispatcher} to add TLS support. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This class essentially sits between the dispatcher and the select 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop, intercepting events and only calling the dispatcher when 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) applicable. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) In the case of handle_read(), a read operation will be activated, 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) and when it completes, the bytes will be placed in a buffer where 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the dispatcher can retrieve them by calling recv(), and the 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispatcher's handle_read() will be called. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) In the case of handle_write(), the dispatcher's handle_write() will 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) be called, and when it calls send(), a write operation will be 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) activated. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) To use this class, you must combine it with an asyncore.dispatcher, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) and pass in a handshake operation with setServerHandshakeOp(). 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Below is an example of using this class with medusa. This class is 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixed in with http_channel to create http_tls_channel. Note: 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1. the mix-in is listed first in the inheritance list 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2. the input buffer size must be at least 16K, otherwise the 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispatcher might not read all the bytes from the TLS layer, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) leaving some bytes in limbo. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3. IE seems to have a problem receiving a whole HTTP response in a 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) single TLS record, so HTML pages containing '\\r\\n\\r\\n' won't 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) be displayed on IE. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Add the following text into 'start_medusa.py', in the 'HTTP Server' 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) section:: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) from tlslite.api import * 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = open("./serverX509Cert.pem").read() 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x509 = X509() 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x509.parse(s) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) certChain = X509CertChain([x509]) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = open("./serverX509Key.pem").read() 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) privateKey = parsePEMKey(s, private=True) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class http_tls_channel(TLSAsyncDispatcherMixIn, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_server.http_channel): 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ac_in_buffer_size = 16384 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__ (self, server, conn, addr): 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_server.http_channel.__init__(self, server, conn, addr) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSAsyncDispatcherMixIn.__init__(self, conn) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.tlsConnection.ignoreAbruptClose = True 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.setServerHandshakeOp(certChain=certChain, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) privateKey=privateKey) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hs.channel_class = http_tls_channel 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) If the TLS layer raises an exception, the exception will be caught 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in asyncore.dispatcher, which will call close() on this class. The 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLS layer always closes the TLS connection before raising an 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exception, so the close operation will complete right away, causing 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asyncore.dispatcher.close() to be called, which closes the socket 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) and removes this instance from the asyncore loop. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, sock=None): 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsyncStateMachine.__init__(self) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sock: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.tlsConnection = TLSConnection(sock) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #Calculate the sibling I'm being mixed in with. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #This is necessary since we override functions 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #like readable(), handle_read(), etc., but we 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #also want to call the sibling's versions. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for cl in self.__class__.__bases__: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if cl != TLSAsyncDispatcherMixIn and cl != AsyncStateMachine: 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.siblingClass = cl 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise AssertionError() 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def readable(self): 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = self.wantsReadEvent() 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if result != None: 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.siblingClass.readable(self) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def writable(self): 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = self.wantsWriteEvent() 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if result != None: 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.siblingClass.writable(self) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def handle_read(self): 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.inReadEvent() 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def handle_write(self): 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.inWriteEvent() 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def outConnectEvent(self): 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.siblingClass.handle_connect(self) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def outCloseEvent(self): 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asyncore.dispatcher.close(self) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def outReadEvent(self, readBuffer): 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.readBuffer = readBuffer 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.siblingClass.handle_read(self) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def outWriteEvent(self): 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.siblingClass.handle_write(self) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def recv(self, bufferSize=16384): 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if bufferSize < 16384 or self.readBuffer == None: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise AssertionError() 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) returnValue = self.readBuffer 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.readBuffer = None 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return returnValue 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def send(self, writeBuffer): 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.setWriteOp(writeBuffer) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return len(writeBuffer) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def close(self): 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if hasattr(self, "tlsConnection"): 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.setCloseOp() 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asyncore.dispatcher.close(self)