|
|
f63228 |
|
|
|
f63228 |
# HG changeset patch
|
|
|
f63228 |
# User Benjamin Peterson <benjamin@python.org>
|
|
|
f63228 |
# Date 1416798122 21600
|
|
|
f63228 |
# Node ID fb83916c3ea12899569e88a7505469a90ab1f674
|
|
|
f63228 |
# Parent c84f36a5f556867c2ec50453dc879a500032d377
|
|
|
f63228 |
pep 476: verify certificates by default (#22417)
|
|
|
f63228 |
|
|
|
f63228 |
diff --git a/Doc/library/httplib.rst b/Doc/library/httplib.rst
|
|
|
f63228 |
--- a/Doc/library/httplib.rst
|
|
|
f63228 |
+++ b/Doc/library/httplib.rst
|
|
|
f63228 |
@@ -90,9 +90,6 @@ The module provides the following classe
|
|
|
f63228 |
server's certificate. If you want to change that behaviour, you can
|
|
|
f63228 |
explicitly set *check_hostname* to False.
|
|
|
f63228 |
|
|
|
f63228 |
- .. warning::
|
|
|
f63228 |
- This does not do any verification of the server's certificate.
|
|
|
f63228 |
-
|
|
|
f63228 |
.. versionadded:: 2.0
|
|
|
f63228 |
|
|
|
f63228 |
.. versionchanged:: 2.6
|
|
|
f63228 |
@@ -104,6 +101,11 @@ The module provides the following classe
|
|
|
f63228 |
.. versionchanged:: 2.7.9
|
|
|
f63228 |
*context* and *check_hostname* was added.
|
|
|
f63228 |
|
|
|
f63228 |
+ This class now performs all the necessary certificate and hostname checks
|
|
|
f63228 |
+ by default. To revert to the previous, unverified, behavior
|
|
|
f63228 |
+ :func:`ssl._create_unverified_context` can be passed to the *context*
|
|
|
f63228 |
+ parameter.
|
|
|
f63228 |
+
|
|
|
f63228 |
|
|
|
f63228 |
.. class:: HTTPResponse(sock, debuglevel=0, strict=0)
|
|
|
f63228 |
|
|
|
f63228 |
diff --git a/Lib/httplib.py b/Lib/httplib.py
|
|
|
f63228 |
--- a/Lib/httplib.py
|
|
|
f63228 |
+++ b/Lib/httplib.py
|
|
|
f63228 |
@@ -1193,7 +1193,7 @@ else:
|
|
|
f63228 |
self.key_file = key_file
|
|
|
f63228 |
self.cert_file = cert_file
|
|
|
f63228 |
if context is None:
|
|
|
f63228 |
- context = ssl.create_default_context()
|
|
|
f63228 |
+ context = ssl._create_default_https_context()
|
|
|
f63228 |
will_verify = context.verify_mode != ssl.CERT_NONE
|
|
|
f63228 |
if check_hostname is None:
|
|
|
f63228 |
check_hostname = will_verify
|
|
|
f63228 |
diff --git a/Lib/ssl.py b/Lib/ssl.py
|
|
|
f63228 |
--- a/Lib/ssl.py
|
|
|
f63228 |
+++ b/Lib/ssl.py
|
|
|
f63228 |
@@ -427,8 +427,7 @@ def create_default_context(purpose=Purpo
|
|
|
f63228 |
context.load_default_certs(purpose)
|
|
|
f63228 |
return context
|
|
|
f63228 |
|
|
|
f63228 |
-
|
|
|
f63228 |
-def _create_stdlib_context(protocol=PROTOCOL_SSLv23, cert_reqs=None,
|
|
|
f63228 |
+def _create_unverified_context(protocol=PROTOCOL_SSLv23, cert_reqs=None,
|
|
|
f63228 |
check_hostname=False, purpose=Purpose.SERVER_AUTH,
|
|
|
f63228 |
certfile=None, keyfile=None,
|
|
|
f63228 |
cafile=None, capath=None, cadata=None):
|
|
|
f63228 |
@@ -469,6 +468,14 @@ def _create_stdlib_context(protocol=PROT
|
|
|
f63228 |
|
|
|
f63228 |
return context
|
|
|
f63228 |
|
|
|
f63228 |
+# Used by http.client if no context is explicitly passed.
|
|
|
f63228 |
+_create_default_https_context = create_default_context
|
|
|
f63228 |
+
|
|
|
f63228 |
+
|
|
|
f63228 |
+# Backwards compatibility alias, even though it's not a public name.
|
|
|
f63228 |
+_create_stdlib_context = _create_unverified_context
|
|
|
f63228 |
+
|
|
|
f63228 |
+
|
|
|
f63228 |
class SSLSocket(socket):
|
|
|
f63228 |
"""This class implements a subtype of socket.socket that wraps
|
|
|
f63228 |
the underlying OS socket in an SSL context when necessary, and
|
|
|
f63228 |
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
|
|
|
f63228 |
--- a/Lib/test/test_httplib.py
|
|
|
f63228 |
+++ b/Lib/test/test_httplib.py
|
|
|
f63228 |
@@ -1,10 +1,9 @@
|
|
|
f63228 |
import httplib
|
|
|
f63228 |
import array
|
|
|
f63228 |
-import httplib
|
|
|
f63228 |
-import os
|
|
|
f63228 |
import StringIO
|
|
|
f63228 |
import socket
|
|
|
f63228 |
import errno
|
|
|
f63228 |
+import os
|
|
|
f63228 |
|
|
|
f63228 |
import unittest
|
|
|
f63228 |
TestCase = unittest.TestCase
|
|
|
f63228 |
diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py
|
|
|
f63228 |
--- a/Lib/test/test_urllib2_localnet.py
|
|
|
f63228 |
+++ b/Lib/test/test_urllib2_localnet.py
|
|
|
f63228 |
@@ -5,6 +5,7 @@ import urllib2
|
|
|
f63228 |
import BaseHTTPServer
|
|
|
f63228 |
import unittest
|
|
|
f63228 |
import hashlib
|
|
|
f63228 |
+import ssl
|
|
|
f63228 |
|
|
|
f63228 |
from test import test_support
|
|
|
f63228 |
|
|
|
f63228 |
@@ -562,15 +563,37 @@ class TestUrlopen(BaseTestCase):
|
|
|
f63228 |
cafile=CERT_localhost)
|
|
|
f63228 |
self.assertEqual(data, b"we care a bit")
|
|
|
f63228 |
# Bad cert
|
|
|
f63228 |
- with self.assertRaises(urllib2.URLError) as cm:
|
|
|
f63228 |
+ with self.assertRaises(urllib2.URLError):
|
|
|
f63228 |
self.urlopen("https://localhost:%s/bizarre" % handler.port,
|
|
|
f63228 |
cafile=CERT_fakehostname)
|
|
|
f63228 |
# Good cert, but mismatching hostname
|
|
|
f63228 |
handler = self.start_https_server(certfile=CERT_fakehostname)
|
|
|
f63228 |
- with self.assertRaises(ssl.CertificateError) as cm:
|
|
|
f63228 |
+ with self.assertRaises(ssl.CertificateError):
|
|
|
f63228 |
self.urlopen("https://localhost:%s/bizarre" % handler.port,
|
|
|
f63228 |
cafile=CERT_fakehostname)
|
|
|
f63228 |
|
|
|
f63228 |
+ def test_https_with_cadefault(self):
|
|
|
f63228 |
+ handler = self.start_https_server(certfile=CERT_localhost)
|
|
|
f63228 |
+ # Self-signed cert should fail verification with system certificate store
|
|
|
f63228 |
+ with self.assertRaises(urllib2.URLError):
|
|
|
f63228 |
+ self.urlopen("https://localhost:%s/bizarre" % handler.port,
|
|
|
f63228 |
+ cadefault=True)
|
|
|
f63228 |
+
|
|
|
f63228 |
+ def test_https_sni(self):
|
|
|
f63228 |
+ if ssl is None:
|
|
|
f63228 |
+ self.skipTest("ssl module required")
|
|
|
f63228 |
+ if not ssl.HAS_SNI:
|
|
|
f63228 |
+ self.skipTest("SNI support required in OpenSSL")
|
|
|
f63228 |
+ sni_name = [None]
|
|
|
f63228 |
+ def cb_sni(ssl_sock, server_name, initial_context):
|
|
|
f63228 |
+ sni_name[0] = server_name
|
|
|
f63228 |
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
|
|
f63228 |
+ context.set_servername_callback(cb_sni)
|
|
|
f63228 |
+ handler = self.start_https_server(context=context, certfile=CERT_localhost)
|
|
|
f63228 |
+ context = ssl.create_default_context(cafile=CERT_localhost)
|
|
|
f63228 |
+ self.urlopen("https://localhost:%s" % handler.port, context=context)
|
|
|
f63228 |
+ self.assertEqual(sni_name[0], "localhost")
|
|
|
f63228 |
+
|
|
|
f63228 |
def test_sending_headers(self):
|
|
|
f63228 |
handler = self.start_server([(200, [], "we don't care")])
|
|
|
f63228 |
|
|
|
f63228 |
diff -up Python-2.7.5/Doc/library/xmlrpclib.rst.ver Python-2.7.5/Doc/library/xmlrpclib.rst
|
|
|
f63228 |
--- Python-2.7.5/Doc/library/xmlrpclib.rst.ver 2015-03-30 13:59:29.243493601 +0200
|
|
|
f63228 |
+++ Python-2.7.5/Doc/library/xmlrpclib.rst 2015-03-30 14:03:40.509532180 +0200
|
|
|
f63228 |
@@ -34,6 +34,10 @@ between conformable Python objects and X
|
|
|
f63228 |
constructed data. If you need to parse untrusted or unauthenticated data see
|
|
|
f63228 |
:ref:`xml-vulnerabilities`.
|
|
|
f63228 |
|
|
|
f63228 |
+.. versionchanged:: 2.7.9
|
|
|
f63228 |
+
|
|
|
f63228 |
+ For https URIs, :mod:`xmlrpclib` now performs all the necessary certificate
|
|
|
f63228 |
+ and hostname checks by default
|
|
|
f63228 |
|
|
|
f63228 |
.. class:: ServerProxy(uri[, transport[, encoding[, verbose[, allow_none[, use_datetime]]]]])
|
|
|
f63228 |
|