1 """A library for integrating Python's builtin ``ssl`` library with CherryPy.
2
3 The ssl module must be importable for SSL functionality.
4
5 To use this module, set ``CherryPyWSGIServer.ssl_adapter`` to an instance of
6 ``BuiltinSSLAdapter``.
7 """
8
9 try:
10 import ssl
11 except ImportError:
12 ssl = None
13
14 try:
15 from _pyio import DEFAULT_BUFFER_SIZE
16 except ImportError:
17 try:
18 from io import DEFAULT_BUFFER_SIZE
19 except ImportError:
20 DEFAULT_BUFFER_SIZE = -1
21
22 import sys
23
24 from cherrypy import wsgiserver
25
26
28
29 """A wrapper for integrating Python's builtin ssl module with CherryPy."""
30
31 certificate = None
32 """The filename of the server SSL certificate."""
33
34 private_key = None
35 """The filename of the server's private key file."""
36
37 - def __init__(self, certificate, private_key, certificate_chain=None):
43
44 - def bind(self, sock):
45 """Wrap and return the given socket."""
46 return sock
47
48 - def wrap(self, sock):
49 """Wrap and return the given socket, plus WSGI environ entries."""
50 try:
51 s = ssl.wrap_socket(sock, do_handshake_on_connect=True,
52 server_side=True, certfile=self.certificate,
53 keyfile=self.private_key,
54 ssl_version=ssl.PROTOCOL_SSLv23)
55 except ssl.SSLError:
56 e = sys.exc_info()[1]
57 if e.errno == ssl.SSL_ERROR_EOF:
58
59
60
61 return None, {}
62 elif e.errno == ssl.SSL_ERROR_SSL:
63 if e.args[1].endswith('http request'):
64
65 raise wsgiserver.NoSSLError
66 elif e.args[1].endswith('unknown protocol'):
67
68
69 return None, {}
70 raise
71 return s, self.get_environ(s)
72
73
75 """Create WSGI environ entries to be merged into each request."""
76 cipher = sock.cipher()
77 ssl_environ = {
78 "wsgi.url_scheme": "https",
79 "HTTPS": "on",
80 'SSL_PROTOCOL': cipher[1],
81 'SSL_CIPHER': cipher[0]
82
83
84 }
85 return ssl_environ
86
87 if sys.version_info >= (3, 0):
90 else:
93