From 227f6e0dc5415cac4dcec0c8b045d128b6b02915 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 7 Dec 2014 13:41:26 -0500 Subject: [PATCH] remove HTTPSConnection's check_hostname parameter (#22959) --- Doc/library/httplib.rst | 11 ++--------- Lib/httplib.py | 16 +--------------- Lib/test/data/README | 2 -- Lib/test/test_httplib.py | 13 +++++-------- Lib/urllib2.py | 9 ++++----- Misc/NEWS | 3 +++ 6 files changed, 15 insertions(+), 39 deletions(-) delete mode 100644 Lib/test/data/README diff --git a/Doc/library/httplib.rst b/Doc/library/httplib.rst index b659fd0970e..354edb234df 100644 --- a/Doc/library/httplib.rst +++ b/Doc/library/httplib.rst @@ -70,7 +70,7 @@ The module provides the following classes: *source_address* was added. -.. class:: HTTPSConnection(host[, port[, key_file[, cert_file[, strict[, timeout[, source_address, context, check_hostname]]]]]]) +.. class:: HTTPSConnection(host[, port[, key_file[, cert_file[, strict[, timeout[, source_address[, context]]]]]]]) A subclass of :class:`HTTPConnection` that uses SSL for communication with secure servers. Default port is ``443``. If *context* is specified, it must @@ -83,13 +83,6 @@ The module provides the following classes: Please read :ref:`ssl-security` for more information on best practices. - .. note:: - If *context* is specified and has a :attr:`~ssl.SSLContext.verify_mode` - of either :data:`~ssl.CERT_OPTIONAL` or :data:`~ssl.CERT_REQUIRED`, then - by default *host* is matched against the host name(s) allowed by the - server's certificate. If you want to change that behaviour, you can - explicitly set *check_hostname* to False. - .. versionadded:: 2.0 .. versionchanged:: 2.6 @@ -99,7 +92,7 @@ The module provides the following classes: *source_address* was added. .. versionchanged:: 2.7.9 - *context* and *check_hostname* was added. + *context* was added. This class now performs all the necessary certificate and hostname checks by default. To revert to the previous, unverified, behavior diff --git a/Lib/httplib.py b/Lib/httplib.py index 7c279068585..ec1dc8cd99f 100644 --- a/Lib/httplib.py +++ b/Lib/httplib.py @@ -1187,23 +1187,16 @@ else: def __init__(self, host, port=None, key_file=None, cert_file=None, strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, - source_address=None, context=None, check_hostname=None): + source_address=None, context=None): HTTPConnection.__init__(self, host, port, strict, timeout, source_address) self.key_file = key_file self.cert_file = cert_file if context is None: context = ssl._create_default_https_context() - will_verify = context.verify_mode != ssl.CERT_NONE - if check_hostname is None: - check_hostname = will_verify - elif check_hostname and not will_verify: - raise ValueError("check_hostname needs a SSL context with " - "either CERT_OPTIONAL or CERT_REQUIRED") if key_file or cert_file: context.load_cert_chain(cert_file, key_file) self._context = context - self._check_hostname = check_hostname def connect(self): "Connect to a host on a given (SSL) port." @@ -1217,13 +1210,6 @@ else: self.sock = self._context.wrap_socket(self.sock, server_hostname=server_hostname) - if not self._context.check_hostname and self._check_hostname: - try: - ssl.match_hostname(self.sock.getpeercert(), server_hostname) - except Exception: - self.sock.shutdown(socket.SHUT_RDWR) - self.sock.close() - raise __all__.append("HTTPSConnection") diff --git a/Lib/test/data/README b/Lib/test/data/README deleted file mode 100644 index 8bf8c9b31e0..00000000000 --- a/Lib/test/data/README +++ /dev/null @@ -1,2 +0,0 @@ -This empty directory serves as destination for temporary files -created by some tests. diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 3e7a57e7f09..d3e6fcedadd 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -616,18 +616,15 @@ class HTTPSTest(TestCase): server = self.make_server(CERT_fakehostname) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.verify_mode = ssl.CERT_REQUIRED + context.check_hostname = True context.load_verify_locations(CERT_fakehostname) h = httplib.HTTPSConnection('localhost', server.port, context=context) with self.assertRaises(ssl.CertificateError): h.request('GET', '/') - # Same with explicit check_hostname=True - h = httplib.HTTPSConnection('localhost', server.port, context=context, - check_hostname=True) - with self.assertRaises(ssl.CertificateError): - h.request('GET', '/') - # With check_hostname=False, the mismatching is ignored - h = httplib.HTTPSConnection('localhost', server.port, context=context, - check_hostname=False) + h.close() + # With context.check_hostname=False, the mismatching is ignored + context.check_hostname = False + h = httplib.HTTPSConnection('localhost', server.port, context=context) h.request('GET', '/nonexistent') resp = h.getresponse() self.assertEqual(resp.status, 404) diff --git a/Lib/urllib2.py b/Lib/urllib2.py index 78b08fc56d4..9277b1d1cdc 100644 --- a/Lib/urllib2.py +++ b/Lib/urllib2.py @@ -139,10 +139,10 @@ def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, ) if not _have_ssl: raise ValueError('SSL support not available') - context = ssl._create_stdlib_context(cert_reqs=ssl.CERT_REQUIRED, + context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH, cafile=cafile, capath=capath) - https_handler = HTTPSHandler(context=context, check_hostname=True) + https_handler = HTTPSHandler(context=context) opener = build_opener(https_handler) elif context: https_handler = HTTPSHandler(context=context) @@ -1231,14 +1231,13 @@ class HTTPHandler(AbstractHTTPHandler): if hasattr(httplib, 'HTTPS'): class HTTPSHandler(AbstractHTTPHandler): - def __init__(self, debuglevel=0, context=None, check_hostname=None): + def __init__(self, debuglevel=0, context=None): AbstractHTTPHandler.__init__(self, debuglevel) self._context = context - self._check_hostname = check_hostname def https_open(self, req): return self.do_open(httplib.HTTPSConnection, req, - context=self._context, check_hostname=self._check_hostname) + context=self._context) https_request = AbstractHTTPHandler.do_request_ diff --git a/Misc/NEWS b/Misc/NEWS index 5e7a7956417..f471ed32b20 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 2.7.9? Library ------- +- Issue #22959: Remove the *check_hostname* parameter of + httplib.HTTPSConnection. The *context* parameter should be used instead. + - Issue #16043: Add a default limit for the amount of data xmlrpclib.gzip_decode will return. This resolves CVE-2013-1753.