Issue #8808: The IMAP4_SSL constructor now allows passing an SSLContext
parameter to control parameters of the secure channel. Patch by Sijin Joseph.
This commit is contained in:
parent
45fd0c9931
commit
0872816dc1
|
@ -64,14 +64,21 @@ Three exceptions are defined as attributes of the :class:`IMAP4` class:
|
|||
There's also a subclass for secure connections:
|
||||
|
||||
|
||||
.. class:: IMAP4_SSL(host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None)
|
||||
.. class:: IMAP4_SSL(host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ssl_context=None)
|
||||
|
||||
This is a subclass derived from :class:`IMAP4` that connects over an SSL
|
||||
encrypted socket (to use this class you need a socket module that was compiled
|
||||
with SSL support). If *host* is not specified, ``''`` (the local host) is used.
|
||||
If *port* is omitted, the standard IMAP4-over-SSL port (993) is used. *keyfile*
|
||||
and *certfile* are also optional - they can contain a PEM formatted private key
|
||||
and certificate chain file for the SSL connection.
|
||||
and certificate chain file for the SSL connection. *ssl_context* parameter is a
|
||||
:class:`ssl.SSLContext` object which allows bundling SSL configuration
|
||||
options, certificates and private keys into a single (potentially long-lived)
|
||||
structure. Note that the *keyfile*/*certfile* parameters are mutually exclusive with *ssl_context*,
|
||||
a :class:`ValueError` is thrown if *keyfile*/*certfile* is provided along with *ssl_context*.
|
||||
|
||||
.. versionchanged:: 3.3
|
||||
*ssl_context* parameter added.
|
||||
|
||||
|
||||
The second subclass allows for connections created by a child process:
|
||||
|
|
|
@ -1177,25 +1177,40 @@ if HAVE_SSL:
|
|||
|
||||
"""IMAP4 client class over SSL connection
|
||||
|
||||
Instantiate with: IMAP4_SSL([host[, port[, keyfile[, certfile]]]])
|
||||
Instantiate with: IMAP4_SSL([host[, port[, keyfile[, certfile[, ssl_context]]]]])
|
||||
|
||||
host - host's name (default: localhost);
|
||||
port - port number (default: standard IMAP4 SSL port).
|
||||
port - port number (default: standard IMAP4 SSL port);
|
||||
keyfile - PEM formatted file that contains your private key (default: None);
|
||||
certfile - PEM formatted certificate chain file (default: None);
|
||||
ssl_context - a SSLContext object that contains your certificate chain
|
||||
and private key (default: None)
|
||||
Note: if ssl_context is provided, then parameters keyfile or
|
||||
certfile should not be set otherwise ValueError is thrown.
|
||||
|
||||
for more documentation see the docstring of the parent class IMAP4.
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, host = '', port = IMAP4_SSL_PORT, keyfile = None, certfile = None):
|
||||
def __init__(self, host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ssl_context=None):
|
||||
if ssl_context is not None and keyfile is not None:
|
||||
raise ValueError("ssl_context and keyfile arguments are mutually "
|
||||
"exclusive")
|
||||
if ssl_context is not None and certfile is not None:
|
||||
raise ValueError("ssl_context and certfile arguments are mutually "
|
||||
"exclusive")
|
||||
|
||||
self.keyfile = keyfile
|
||||
self.certfile = certfile
|
||||
self.ssl_context = ssl_context
|
||||
IMAP4.__init__(self, host, port)
|
||||
|
||||
def _create_socket(self):
|
||||
sock = IMAP4._create_socket(self)
|
||||
return ssl.wrap_socket(sock, self.keyfile, self.certfile)
|
||||
if self.ssl_context:
|
||||
return self.ssl_context.wrap_socket(sock)
|
||||
else:
|
||||
return ssl.wrap_socket(sock, self.keyfile, self.certfile)
|
||||
|
||||
def open(self, host='', port=IMAP4_SSL_PORT):
|
||||
"""Setup connection to remote server on "host:port".
|
||||
|
|
|
@ -258,11 +258,58 @@ class RemoteIMAP_SSLTest(RemoteIMAPTest):
|
|||
port = 993
|
||||
imap_class = IMAP4_SSL
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def create_ssl_context(self):
|
||||
ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||
ssl_context.load_cert_chain(CERTFILE)
|
||||
return ssl_context
|
||||
|
||||
def check_logincapa(self, server):
|
||||
try:
|
||||
for cap in server.capabilities:
|
||||
self.assertIsInstance(cap, str)
|
||||
self.assertFalse('LOGINDISABLED' in server.capabilities)
|
||||
self.assertTrue('AUTH=PLAIN' in server.capabilities)
|
||||
rs = server.login(self.username, self.password)
|
||||
self.assertEqual(rs[0], 'OK')
|
||||
finally:
|
||||
server.logout()
|
||||
|
||||
def test_logincapa(self):
|
||||
for cap in self.server.capabilities:
|
||||
self.assertIsInstance(cap, str)
|
||||
self.assertFalse('LOGINDISABLED' in self.server.capabilities)
|
||||
self.assertTrue('AUTH=PLAIN' in self.server.capabilities)
|
||||
with transient_internet(self.host):
|
||||
_server = self.imap_class(self.host, self.port)
|
||||
self.check_logincapa(_server)
|
||||
|
||||
def test_logincapa_with_client_certfile(self):
|
||||
with transient_internet(self.host):
|
||||
_server = self.imap_class(self.host, self.port, certfile=CERTFILE)
|
||||
self.check_logincapa(_server)
|
||||
|
||||
def test_logincapa_with_client_ssl_context(self):
|
||||
with transient_internet(self.host):
|
||||
_server = self.imap_class(self.host, self.port, ssl_context=self.create_ssl_context())
|
||||
self.check_logincapa(_server)
|
||||
|
||||
def test_logout(self):
|
||||
with transient_internet(self.host):
|
||||
_server = self.imap_class(self.host, self.port)
|
||||
rs = _server.logout()
|
||||
self.assertEqual(rs[0], 'BYE')
|
||||
|
||||
def test_ssl_context_certfile_exclusive(self):
|
||||
with transient_internet(self.host):
|
||||
self.assertRaises(ValueError, self.imap_class, self.host, self.port,
|
||||
certfile=CERTFILE, ssl_context=self.create_ssl_context())
|
||||
|
||||
def test_ssl_context_keyfile_exclusive(self):
|
||||
with transient_internet(self.host):
|
||||
self.assertRaises(ValueError, self.imap_class, self.host, self.port,
|
||||
keyfile=CERTFILE, ssl_context=self.create_ssl_context())
|
||||
|
||||
|
||||
def test_main():
|
||||
|
|
|
@ -140,6 +140,10 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #8808: The IMAP4_SSL constructor now allows passing an SSLContext
|
||||
parameter to control parameters of the secure channel. Patch by Sijin
|
||||
Joseph.
|
||||
|
||||
- ntpath.samefile failed to notice that "a.txt" and "A.TXT" refer to the same
|
||||
file on Windows XP. As noticed in issue #10684.
|
||||
|
||||
|
|
Loading…
Reference in New Issue