Commit 204a0eca authored by Benjamin Peterson's avatar Benjamin Peterson

merge 2.7.9 release branch

parents 542125e6 227f6e0d
...@@ -70,7 +70,7 @@ The module provides the following classes: ...@@ -70,7 +70,7 @@ The module provides the following classes:
*source_address* was added. *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 A subclass of :class:`HTTPConnection` that uses SSL for communication with
secure servers. Default port is ``443``. If *context* is specified, it must secure servers. Default port is ``443``. If *context* is specified, it must
...@@ -83,13 +83,6 @@ The module provides the following classes: ...@@ -83,13 +83,6 @@ The module provides the following classes:
Please read :ref:`ssl-security` for more information on best practices. 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 .. versionadded:: 2.0
.. versionchanged:: 2.6 .. versionchanged:: 2.6
...@@ -99,7 +92,7 @@ The module provides the following classes: ...@@ -99,7 +92,7 @@ The module provides the following classes:
*source_address* was added. *source_address* was added.
.. versionchanged:: 2.7.9 .. versionchanged:: 2.7.9
*context* and *check_hostname* was added. *context* was added.
This class now performs all the necessary certificate and hostname checks This class now performs all the necessary certificate and hostname checks
by default. To revert to the previous, unverified, behavior by default. To revert to the previous, unverified, behavior
......
...@@ -1191,23 +1191,16 @@ else: ...@@ -1191,23 +1191,16 @@ else:
def __init__(self, host, port=None, key_file=None, cert_file=None, def __init__(self, host, port=None, key_file=None, cert_file=None,
strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, 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, HTTPConnection.__init__(self, host, port, strict, timeout,
source_address) source_address)
self.key_file = key_file self.key_file = key_file
self.cert_file = cert_file self.cert_file = cert_file
if context is None: if context is None:
context = ssl._create_default_https_context() 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: if key_file or cert_file:
context.load_cert_chain(cert_file, key_file) context.load_cert_chain(cert_file, key_file)
self._context = context self._context = context
self._check_hostname = check_hostname
def connect(self): def connect(self):
"Connect to a host on a given (SSL) port." "Connect to a host on a given (SSL) port."
...@@ -1221,13 +1214,6 @@ else: ...@@ -1221,13 +1214,6 @@ else:
self.sock = self._context.wrap_socket(self.sock, self.sock = self._context.wrap_socket(self.sock,
server_hostname=server_hostname) 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") __all__.append("HTTPSConnection")
......
This empty directory serves as destination for temporary files
created by some tests.
...@@ -639,18 +639,15 @@ class HTTPSTest(TestCase): ...@@ -639,18 +639,15 @@ class HTTPSTest(TestCase):
server = self.make_server(CERT_fakehostname) server = self.make_server(CERT_fakehostname)
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
context.verify_mode = ssl.CERT_REQUIRED context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_verify_locations(CERT_fakehostname) context.load_verify_locations(CERT_fakehostname)
h = httplib.HTTPSConnection('localhost', server.port, context=context) h = httplib.HTTPSConnection('localhost', server.port, context=context)
with self.assertRaises(ssl.CertificateError): with self.assertRaises(ssl.CertificateError):
h.request('GET', '/') h.request('GET', '/')
# Same with explicit check_hostname=True h.close()
h = httplib.HTTPSConnection('localhost', server.port, context=context, # With context.check_hostname=False, the mismatching is ignored
check_hostname=True) context.check_hostname = False
with self.assertRaises(ssl.CertificateError): h = httplib.HTTPSConnection('localhost', server.port, context=context)
h.request('GET', '/')
# With check_hostname=False, the mismatching is ignored
h = httplib.HTTPSConnection('localhost', server.port, context=context,
check_hostname=False)
h.request('GET', '/nonexistent') h.request('GET', '/nonexistent')
resp = h.getresponse() resp = h.getresponse()
self.assertEqual(resp.status, 404) self.assertEqual(resp.status, 404)
......
...@@ -139,10 +139,10 @@ def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, ...@@ -139,10 +139,10 @@ def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
) )
if not _have_ssl: if not _have_ssl:
raise ValueError('SSL support not available') 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, cafile=cafile,
capath=capath) capath=capath)
https_handler = HTTPSHandler(context=context, check_hostname=True) https_handler = HTTPSHandler(context=context)
opener = build_opener(https_handler) opener = build_opener(https_handler)
elif context: elif context:
https_handler = HTTPSHandler(context=context) https_handler = HTTPSHandler(context=context)
...@@ -1231,14 +1231,13 @@ class HTTPHandler(AbstractHTTPHandler): ...@@ -1231,14 +1231,13 @@ class HTTPHandler(AbstractHTTPHandler):
if hasattr(httplib, 'HTTPS'): if hasattr(httplib, 'HTTPS'):
class HTTPSHandler(AbstractHTTPHandler): class HTTPSHandler(AbstractHTTPHandler):
def __init__(self, debuglevel=0, context=None, check_hostname=None): def __init__(self, debuglevel=0, context=None):
AbstractHTTPHandler.__init__(self, debuglevel) AbstractHTTPHandler.__init__(self, debuglevel)
self._context = context self._context = context
self._check_hostname = check_hostname
def https_open(self, req): def https_open(self, req):
return self.do_open(httplib.HTTPSConnection, req, return self.do_open(httplib.HTTPSConnection, req,
context=self._context, check_hostname=self._check_hostname) context=self._context)
https_request = AbstractHTTPHandler.do_request_ https_request = AbstractHTTPHandler.do_request_
......
...@@ -58,6 +58,9 @@ What's New in Python 2.7.9? ...@@ -58,6 +58,9 @@ What's New in Python 2.7.9?
Library 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 - Issue #16043: Add a default limit for the amount of data xmlrpclib.gzip_decode
will return. This resolves CVE-2013-1753. will return. This resolves CVE-2013-1753.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment