1# Author: Trevor Perrin
2# See the LICENSE file for legal information regarding use of this file.
3
4"""TLS Lite + SocketServer."""
5
6from tlslite.tlsconnection import TLSConnection
7
8class TLSSocketServerMixIn:
9    """
10    This class can be mixed in with any L{SocketServer.TCPServer} to
11    add TLS support.
12
13    To use this class, define a new class that inherits from it and
14    some L{SocketServer.TCPServer} (with the mix-in first). Then
15    implement the handshake() method, doing some sort of server
16    handshake on the connection argument.  If the handshake method
17    returns True, the RequestHandler will be triggered.  Below is a
18    complete example of a threaded HTTPS server::
19
20        from SocketServer import *
21        from BaseHTTPServer import *
22        from SimpleHTTPServer import *
23        from tlslite import *
24
25        s = open("./serverX509Cert.pem").read()
26        x509 = X509()
27        x509.parse(s)
28        certChain = X509CertChain([x509])
29
30        s = open("./serverX509Key.pem").read()
31        privateKey = parsePEMKey(s, private=True)
32
33        sessionCache = SessionCache()
34
35        class MyHTTPServer(ThreadingMixIn, TLSSocketServerMixIn,
36                           HTTPServer):
37          def handshake(self, tlsConnection):
38              try:
39                  tlsConnection.handshakeServer(certChain=certChain,
40                                                privateKey=privateKey,
41                                                sessionCache=sessionCache)
42                  tlsConnection.ignoreAbruptClose = True
43                  return True
44              except TLSError, error:
45                  print "Handshake failure:", str(error)
46                  return False
47
48        httpd = MyHTTPServer(('localhost', 443), SimpleHTTPRequestHandler)
49        httpd.serve_forever()
50    """
51
52
53    def finish_request(self, sock, client_address):
54        tlsConnection = TLSConnection(sock)
55        if self.handshake(tlsConnection) == True:
56            self.RequestHandlerClass(tlsConnection, client_address, self)
57            tlsConnection.close()
58
59    #Implement this method to do some form of handshaking.  Return True
60    #if the handshake finishes properly and the request is authorized.
61    def handshake(self, tlsConnection):
62        raise NotImplementedError()