CherryPy Project Download

TlsLite: tlslite_cherry.py

Line 
1 """HTTPS servers for CherryPy using the TLS Lite package."""
2
3
4 # A shameless rip of an eerily similar module that used M2Crypto
5 # to do the same thing.  Kudos to Tim Evans for all that; his module
6 # didn't work for me, so I did this instead.
7
8 # I have only the very vaguest notion what I am doing here.  Ergo,
9 # this code is appropriate for only a ridiculously basic CherryPy
10 # SSL server setup.  It works for me.  Your mileage may vary.
11
12 # Daniel McNair
13
14
15 from tlslite.api import *
16 from cherrypy import cpg, _cphttpserver, _cputil
17
18
19 class SslCherryConnection(TLSConnection):
20     def __init__(self, socket):
21         """Create a TLSConnection using the key file specified in the config"""
22
23         TLSConnection.__init__(self, socket)
24
25         self.__socket = socket
26
27         s = open(cpg.configOption.sslCertificateFile).read()
28         x509 = X509()
29         x509.parse(s)
30         self.certChain = X509CertChain([x509])
31         s = open(cpg.configOption.sslKeyFile).read()
32         self.privateKey = parsePEMKey(s, private=True)
33         self.sessionCache = SessionCache()
34
35         self._cpLogMessage = _cputil.getSpecialFunction('_cpLogMessage')
36
37     # forward these things to my socket object
38     def bind(self, *args):
39         return self.__socket.bind(*args)
40     def listen(self, *args):
41         return self.__socket.listen(*args)
42     def setblocking(self, *args):
43         return self.__socket.setblocking(*args)
44
45     def accept(self):
46         """Accept a connection and perform SSL/TLS handshaking on it."""
47
48         # dm- it seems to me that this whole while 1: thingee here
49         # is intended just to turn this accept() call on a non-blocking
50         # socket into a blocking method.  Any ideas why?
51
52         while 1:
53             try:
54                 # get the raw socket
55                 sock, addr = self.__socket.accept()
56
57                 # now wrap that
58                 conn = SslCherryConnection(sock)
59
60                 # do handshaking
61                 conn.handshakeServer(certChain=self.certChain,
62                                      privateKey=self.privateKey,
63                                      reqCert=False,
64                                      sessionCache=self.sessionCache)
65
66                 # give back the new connection object
67                 return conn, addr
68             except TLSRemoteAlert, alert:
69                 self._cpLogMessage('Remote alert "%s"' % alert.description,
70                                    'TLS', 1)
71
72 # dm- believe it or not I didn't change anything below this line
73
74 class SslCherryServer(_cphttpserver.CherryHTTPServer):
75     """Single threaded HTTPS server"""
76
77     def server_bind(self):
78         """Wrap the socket with a SslCherryConnection object before proceeding as normal"""
79
80         self.socket = SslCherryConnection(self.socket)
81         _cphttpserver.CherryHTTPServer.server_bind(self)
82
83
84 class SslCherryPooledThreadServer(_cphttpserver.PooledThreadServer):
85     """Thread pooled HTTPS server"""
86
87     def server_bind(self):
88         """Wrap the socket with a SslCherryConnection object before proceeding as normal"""
89
90         self.socket = SslCherryConnection(self.socket)
91         _cphttpserver.PooledThreadServer.server_bind(self)
92
93
94 def start(configFile=None, parsedConfigFile=None, configDict={}):
95     """Start an HTTPS server instead of an HTTP server"""
96
97     # Initialise config
98     cpg.server.start(configFile, parsedConfigFile, configDict, True)
99
100     # Choose server class
101     if cpg.configOption.threadPool > 1:
102         MyCherryHTTPServer = SslCherryPooledThreadServer
103     else:
104         MyCherryHTTPServer = SslCherryServer
105
106     # Below is similar to _cphttpserver.start
107     if (cpg.configOption.threadPool > 1) and \
108             cpg.configOption.sessionStorageType == 'file':
109         cpg._sessionFileLock = threading.RLock()
110
111     MyCherryHTTPServer.request_queue_size = cpg.configOption.socketQueueSize
112
113     _cphttpserver.CherryHTTPRequestHandler.protocol_version = cpg.configOption.protocolVersion
114
115     _cphttpserver.run_server(_cphttpserver.CherryHTTPRequestHandler, MyCherryHTTPServer,
116                              (cpg.configOption.socketHost, cpg.configOption.socketPort),
117                              cpg.configOption.socketFile)

Hosted by WebFaction

Log in as guest/cherrypy to create/edit wiki pages