OpenSecurity/install/web.py-0.37/web/wsgiserver/ssl_builtin.py
changeset 3 65432e6c6042
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/OpenSecurity/install/web.py-0.37/web/wsgiserver/ssl_builtin.py	Mon Dec 02 14:02:05 2013 +0100
     1.3 @@ -0,0 +1,72 @@
     1.4 +"""A library for integrating Python's builtin ``ssl`` library with CherryPy.
     1.5 +
     1.6 +The ssl module must be importable for SSL functionality.
     1.7 +
     1.8 +To use this module, set ``CherryPyWSGIServer.ssl_adapter`` to an instance of
     1.9 +``BuiltinSSLAdapter``.
    1.10 +"""
    1.11 +
    1.12 +try:
    1.13 +    import ssl
    1.14 +except ImportError:
    1.15 +    ssl = None
    1.16 +
    1.17 +from cherrypy import wsgiserver
    1.18 +
    1.19 +
    1.20 +class BuiltinSSLAdapter(wsgiserver.SSLAdapter):
    1.21 +    """A wrapper for integrating Python's builtin ssl module with CherryPy."""
    1.22 +    
    1.23 +    certificate = None
    1.24 +    """The filename of the server SSL certificate."""
    1.25 +    
    1.26 +    private_key = None
    1.27 +    """The filename of the server's private key file."""
    1.28 +    
    1.29 +    def __init__(self, certificate, private_key, certificate_chain=None):
    1.30 +        if ssl is None:
    1.31 +            raise ImportError("You must install the ssl module to use HTTPS.")
    1.32 +        self.certificate = certificate
    1.33 +        self.private_key = private_key
    1.34 +        self.certificate_chain = certificate_chain
    1.35 +    
    1.36 +    def bind(self, sock):
    1.37 +        """Wrap and return the given socket."""
    1.38 +        return sock
    1.39 +    
    1.40 +    def wrap(self, sock):
    1.41 +        """Wrap and return the given socket, plus WSGI environ entries."""
    1.42 +        try:
    1.43 +            s = ssl.wrap_socket(sock, do_handshake_on_connect=True,
    1.44 +                    server_side=True, certfile=self.certificate,
    1.45 +                    keyfile=self.private_key, ssl_version=ssl.PROTOCOL_SSLv23)
    1.46 +        except ssl.SSLError, e:
    1.47 +            if e.errno == ssl.SSL_ERROR_EOF:
    1.48 +                # This is almost certainly due to the cherrypy engine
    1.49 +                # 'pinging' the socket to assert it's connectable;
    1.50 +                # the 'ping' isn't SSL.
    1.51 +                return None, {}
    1.52 +            elif e.errno == ssl.SSL_ERROR_SSL:
    1.53 +                if e.args[1].endswith('http request'):
    1.54 +                    # The client is speaking HTTP to an HTTPS server.
    1.55 +                    raise wsgiserver.NoSSLError
    1.56 +            raise
    1.57 +        return s, self.get_environ(s)
    1.58 +    
    1.59 +    # TODO: fill this out more with mod ssl env
    1.60 +    def get_environ(self, sock):
    1.61 +        """Create WSGI environ entries to be merged into each request."""
    1.62 +        cipher = sock.cipher()
    1.63 +        ssl_environ = {
    1.64 +            "wsgi.url_scheme": "https",
    1.65 +            "HTTPS": "on",
    1.66 +            'SSL_PROTOCOL': cipher[1],
    1.67 +            'SSL_CIPHER': cipher[0]
    1.68 +##            SSL_VERSION_INTERFACE 	string 	The mod_ssl program version
    1.69 +##            SSL_VERSION_LIBRARY 	string 	The OpenSSL program version
    1.70 +            }
    1.71 +        return ssl_environ
    1.72 +    
    1.73 +    def makefile(self, sock, mode='r', bufsize=-1):
    1.74 +        return wsgiserver.CP_fileobject(sock, mode, bufsize)
    1.75 +