Issue #19784: poplib now supports SSLContext.check_hostname and server name

indication for TLS/SSL connections.
This commit is contained in:
Christian Heimes 2013-12-02 20:10:50 +01:00
parent b8a3f58158
commit 1bc7068d7f
4 changed files with 26 additions and 3 deletions

View File

@ -53,6 +53,10 @@ The :mod:`poplib` module provides two classes:
.. versionchanged:: 3.2 .. versionchanged:: 3.2
*context* parameter added. *context* parameter added.
.. versionchanged:: 3.4
The class now supports hostname check with
:attr:`SSLContext.check_hostname` and *Server Name Indicator* (see
:data:`~ssl.HAS_SNI`).
One exception is defined as an attribute of the :mod:`poplib` module: One exception is defined as an attribute of the :mod:`poplib` module:
@ -198,6 +202,11 @@ An :class:`POP3` instance has the following methods:
.. versionadded:: 3.4 .. versionadded:: 3.4
.. versionchanged:: 3.4
The method now supports hostname check with
:attr:`SSLContext.check_hostname` and *Server Name Indicator* (see
:data:`~ssl.HAS_SNI`).
Instances of :class:`POP3_SSL` have no additional methods. The interface of this Instances of :class:`POP3_SSL` have no additional methods. The interface of this
subclass is identical to its parent. subclass is identical to its parent.

View File

@ -387,7 +387,9 @@ class POP3:
if context is None: if context is None:
context = ssl._create_stdlib_context() context = ssl._create_stdlib_context()
resp = self._shortcmd('STLS') resp = self._shortcmd('STLS')
self.sock = context.wrap_socket(self.sock) server_hostname = self.host if ssl.HAS_SNI else None
self.sock = context.wrap_socket(self.sock,
server_hostname=server_hostname)
self.file = self.sock.makefile('rb') self.file = self.sock.makefile('rb')
self._tls_established = True self._tls_established = True
return resp return resp
@ -428,7 +430,9 @@ if HAVE_SSL:
def _create_socket(self, timeout): def _create_socket(self, timeout):
sock = POP3._create_socket(self, timeout) sock = POP3._create_socket(self, timeout)
sock = self.context.wrap_socket(sock) server_hostname = self.host if ssl.HAS_SNI else None
sock = self.context.wrap_socket(sock,
server_hostname=server_hostname)
return sock return sock
def stls(self, keyfile=None, certfile=None, context=None): def stls(self, keyfile=None, certfile=None, context=None):

View File

@ -23,7 +23,8 @@ if hasattr(poplib, 'POP3_SSL'):
import ssl import ssl
SUPPORTS_SSL = True SUPPORTS_SSL = True
CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert.pem") CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert3.pem")
CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "pycacert.pem")
requires_ssl = skipUnless(SUPPORTS_SSL, 'SSL not supported') requires_ssl = skipUnless(SUPPORTS_SSL, 'SSL not supported')
# the dummy data returned by server when LIST and RETR commands are issued # the dummy data returned by server when LIST and RETR commands are issued
@ -332,6 +333,12 @@ class TestPOP3Class(TestCase):
def test_stls_context(self): def test_stls_context(self):
expected = b'+OK Begin TLS negotiation' expected = b'+OK Begin TLS negotiation'
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
ctx.load_verify_locations(CAFILE)
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.check_hostname = True
with self.assertRaises(ssl.CertificateError):
resp = self.client.stls(context=ctx)
self.client = poplib.POP3("localhost", self.server.port, timeout=3)
resp = self.client.stls(context=ctx) resp = self.client.stls(context=ctx)
self.assertEqual(resp, expected) self.assertEqual(resp, expected)

View File

@ -18,6 +18,9 @@ Core and Builtins
Library Library
------- -------
- Issue #19784: poplib now supports SSLContext.check_hostname and server name
indication for TLS/SSL connections.
- Issue #19782: imaplib now supports SSLContext.check_hostname and server name - Issue #19782: imaplib now supports SSLContext.check_hostname and server name
indication for TLS/SSL connections. indication for TLS/SSL connections.