2 Backport SSL functions and exceptions:
3 - BACKPORT_SSL_ERRORS (bool)
4 - SSLWantReadError, SSLWantWriteError, SSLEOFError
5 - BACKPORT_SSL_CONTEXT (bool)
13 from trollius.py33_exceptions import _wrap_error
15 __all__ = ["SSLContext", "BACKPORT_SSL_ERRORS", "BACKPORT_SSL_CONTEXT",
16 "SSLWantReadError", "SSLWantWriteError", "SSLEOFError",
20 SSLWantReadError = ssl.SSLWantReadError
21 SSLWantWriteError = ssl.SSLWantWriteError
22 SSLEOFError = ssl.SSLEOFError
23 BACKPORT_SSL_ERRORS = False
24 except AttributeError:
26 BACKPORT_SSL_ERRORS = True
28 class SSLWantReadError(ssl.SSLError):
31 class SSLWantWriteError(ssl.SSLError):
34 class SSLEOFError(ssl.SSLError):
39 SSLContext = ssl.SSLContext
40 BACKPORT_SSL_CONTEXT = False
41 wrap_socket = ssl.wrap_socket
42 except AttributeError:
44 BACKPORT_SSL_CONTEXT = True
46 if (sys.version_info < (2, 6, 6)):
47 # SSLSocket constructor has bugs in Python older than 2.6.6:
48 # http://bugs.python.org/issue5103
49 # http://bugs.python.org/issue7943
50 from socket import socket, error as socket_error, _delegate_methods
53 class BackportSSLSocket(ssl.SSLSocket):
54 # Override SSLSocket.__init__()
55 def __init__(self, sock, keyfile=None, certfile=None,
56 server_side=False, cert_reqs=ssl.CERT_NONE,
57 ssl_version=ssl.PROTOCOL_SSLv23, ca_certs=None,
58 do_handshake_on_connect=True,
59 suppress_ragged_eofs=True):
60 socket.__init__(self, _sock=sock._sock)
61 # The initializer for socket overrides the methods send(), recv(), etc.
62 # in the instancce, which we don't need -- but we want to provide the
63 # methods defined in SSLSocket.
64 for attr in _delegate_methods:
67 except AttributeError:
70 if certfile and not keyfile:
72 # see if it's connected
74 socket.getpeername(self)
75 except socket_error as e:
76 if e.errno != errno.ENOTCONN:
78 # no, no connection yet
79 self._connected = False
82 # yes, create the SSL object
83 self._connected = True
84 self._sslobj = _ssl.sslwrap(self._sock, server_side,
86 cert_reqs, ssl_version, ca_certs)
87 if do_handshake_on_connect:
89 self.keyfile = keyfile
90 self.certfile = certfile
91 self.cert_reqs = cert_reqs
92 self.ssl_version = ssl_version
93 self.ca_certs = ca_certs
94 self.do_handshake_on_connect = do_handshake_on_connect
95 self.suppress_ragged_eofs = suppress_ragged_eofs
96 self._makefile_refs = 0
98 def wrap_socket(sock, server_hostname=None, **kwargs):
99 # ignore server_hostname parameter, not supported
100 kwargs.pop('server_hostname', None)
101 return BackportSSLSocket(sock, **kwargs)
103 _wrap_socket = ssl.wrap_socket
105 def wrap_socket(sock, **kwargs):
106 # ignore server_hostname parameter, not supported
107 kwargs.pop('server_hostname', None)
108 return _wrap_socket(sock, **kwargs)
111 class SSLContext(object):
112 def __init__(self, protocol=ssl.PROTOCOL_SSLv23):
113 self.protocol = protocol
117 def load_cert_chain(self, certfile, keyfile):
118 self.certfile = certfile
119 self.keyfile = keyfile
121 def wrap_socket(self, sock, **kwargs):
122 return wrap_socket(sock,
123 ssl_version=self.protocol,
124 certfile=self.certfile,
125 keyfile=self.keyfile,
129 def verify_mode(self):
133 if BACKPORT_SSL_ERRORS:
135 ssl.SSL_ERROR_WANT_READ: SSLWantReadError,
136 ssl.SSL_ERROR_WANT_WRITE: SSLWantWriteError,
137 ssl.SSL_ERROR_EOF: SSLEOFError,
140 def wrap_ssl_error(func, *args, **kw):
142 return func(*args, **kw)
143 except ssl.SSLError as exc:
145 _wrap_error(exc, _MAP_ERRORS, exc.args[0])
148 def wrap_ssl_error(func, *args, **kw):
149 return func(*args, **kw)