]> granicus.if.org Git - python/commitdiff
Issue #28022: Deprecate ssl-related arguments in favor of SSLContext.
authorChristian Heimes <christian@python.org>
Sat, 10 Sep 2016 21:23:33 +0000 (23:23 +0200)
committerChristian Heimes <christian@python.org>
Sat, 10 Sep 2016 21:23:33 +0000 (23:23 +0200)
The deprecation include manual creation of SSLSocket and certfile/keyfile
(or similar) in ftplib, httplib, imaplib, smtplib, poplib and urllib.

ssl.wrap_socket() is not marked as deprecated yet.

23 files changed:
Doc/library/ftplib.rst
Doc/library/http.client.rst
Doc/library/imaplib.rst
Doc/library/poplib.rst
Doc/library/smtplib.rst
Doc/library/ssl.rst
Doc/library/urllib.request.rst
Lib/asyncio/test_utils.py
Lib/ftplib.py
Lib/http/client.py
Lib/imaplib.py
Lib/poplib.py
Lib/smtplib.py
Lib/ssl.py
Lib/test/test_ftplib.py
Lib/test/test_imaplib.py
Lib/test/test_nntplib.py
Lib/test/test_poplib.py
Lib/test/test_ssl.py
Lib/test/test_urllib.py
Lib/test/test_urllib2_localnet.py
Lib/urllib/request.py
Misc/NEWS

index 1e35f37f448bcdab642ef3d5a26bf0a2c4ae66ab..b8c1dcfef2d98e5d71e309d0a91c71625c565c4a 100644 (file)
@@ -97,6 +97,13 @@ The module defines the following items:
       :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see
       :data:`ssl.HAS_SNI`).
 
+   .. deprecated:: 3.6
+
+       *keyfile* and *certfile* are deprecated in favor of *context*.
+       Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let
+       :func:`ssl.create_default_context` select the system's trusted CA
+       certificates for you.
+
    Here's a sample session using the :class:`FTP_TLS` class::
 
       >>> ftps = FTP_TLS('ftp.pureftpd.org')
index 90c0421f91baa4cf1547b0e85a571e95707fd7ba..17f289d84faea3aa2ff0426ecff6df184d2d6758 100644 (file)
@@ -69,13 +69,6 @@ The module provides the following classes:
    must be a :class:`ssl.SSLContext` instance describing the various SSL
    options.
 
-   *key_file* and *cert_file* are deprecated, please use
-   :meth:`ssl.SSLContext.load_cert_chain` instead, or let
-   :func:`ssl.create_default_context` select the system's trusted CA
-   certificates for you.  The *check_hostname* parameter is also deprecated; the
-   :attr:`ssl.SSLContext.check_hostname` attribute of *context* should be used
-   instead.
-
    Please read :ref:`ssl-security` for more information on best practices.
 
    .. versionchanged:: 3.2
@@ -95,6 +88,17 @@ The module provides the following classes:
       :func:`ssl._create_unverified_context` can be passed to the *context*
       parameter.
 
+   .. deprecated:: 3.6
+
+       *key_file* and *cert_file* are deprecated in favor of *context*.
+       Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let
+       :func:`ssl.create_default_context` select the system's trusted CA
+       certificates for you.
+
+       The *check_hostname* parameter is also deprecated; the
+       :attr:`ssl.SSLContext.check_hostname` attribute of *context* should
+       be used instead.
+
 
 .. class:: HTTPResponse(sock, debuglevel=0, method=None, url=None)
 
index b9b3b91518cb0424537eca718c42fdad35f01820..7024a1ba5ac15975581985688e1e34119686eef9 100644 (file)
@@ -103,6 +103,14 @@ There's also a subclass for secure connections:
       :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see
       :data:`ssl.HAS_SNI`).
 
+   .. deprecated:: 3.6
+
+       *keyfile* and *certfile* are deprecated in favor of *ssl_context*.
+       Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let
+       :func:`ssl.create_default_context` select the system's trusted CA
+       certificates for you.
+
+
 The second subclass allows for connections created by a child process:
 
 
index ffabc32b6eeb5d293f55125905c514bde8c43130..d72b660d6ea9f6e78d12d65c0d745c7dd99866c1 100644 (file)
@@ -62,6 +62,13 @@ The :mod:`poplib` module provides two classes:
       :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see
       :data:`ssl.HAS_SNI`).
 
+   .. deprecated:: 3.6
+
+       *keyfile* and *certfile* are deprecated in favor of *context*.
+       Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let
+       :func:`ssl.create_default_context` select the system's trusted CA
+       certificates for you.
+
 One exception is defined as an attribute of the :mod:`poplib` module:
 
 
index 83d5c2ddf4173db358cfa14049cc18ef054c5ae8..1cb3aafcf3826de3bd4b82d532d45502d67528f7 100644 (file)
@@ -95,6 +95,14 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
       :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see
       :data:`ssl.HAS_SNI`).
 
+   .. deprecated:: 3.6
+
+       *keyfile* and *certfile* are deprecated in favor of *context*.
+       Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let
+       :func:`ssl.create_default_context` select the system's trusted CA
+       certificates for you.
+
+
 .. class:: LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None)
 
    The LMTP protocol, which is very similar to ESMTP, is heavily based on the
index 98008fa70ae41e629b0425fc379d6085098d9e3d..af0c5ab30ff5bcdd7b5fd3f297040ae7290c190f 100644 (file)
@@ -230,7 +230,6 @@ instead.
    .. versionchanged:: 3.2
       New optional argument *ciphers*.
 
-
 Context creation
 ^^^^^^^^^^^^^^^^
 
@@ -925,7 +924,7 @@ SSL Sockets
    :ref:`notes on non-blocking sockets <ssl-nonblocking>`.
 
    Usually, :class:`SSLSocket` are not created directly, but using the
-   :func:`wrap_socket` function or the :meth:`SSLContext.wrap_socket` method.
+   the :meth:`SSLContext.wrap_socket` method.
 
    .. versionchanged:: 3.5
       The :meth:`sendfile` method was added.
@@ -935,6 +934,10 @@ SSL Sockets
       are received or sent. The socket timeout is now to maximum total duration
       of the shutdown.
 
+   .. deprecated:: 3.6
+      It is deprecated to create a :class:`SSLSocket` instance directly, use
+      :meth:`SSLContext.wrap_socket` to wrap a socket.
+
 
 SSL sockets also have the following additional methods and attributes:
 
@@ -955,6 +958,9 @@ SSL sockets also have the following additional methods and attributes:
       The socket timeout is now to maximum total duration to read up to *len*
       bytes.
 
+   .. deprecated:: 3.6
+      Use :meth:`~SSLSocket.recv` instead of :meth:`~SSLSocket.read`.
+
 .. method:: SSLSocket.write(buf)
 
    Write *buf* to the SSL socket and return the number of bytes written. The
@@ -970,6 +976,9 @@ SSL sockets also have the following additional methods and attributes:
       The socket timeout is no more reset each time bytes are received or sent.
       The socket timeout is now to maximum total duration to write *buf*.
 
+   .. deprecated:: 3.6
+      Use :meth:`~SSLSocket.send` instead of :meth:`~SSLSocket.write`.
+
 .. note::
 
    The :meth:`~SSLSocket.read` and :meth:`~SSLSocket.write` methods are the
index d288165a99db5bc3a4f2086371462614a6091ed7..491bded58baaebb0e95f63d2ba2661014696cffa 100644 (file)
@@ -111,6 +111,12 @@ The :mod:`urllib.request` module defines the following functions:
    .. versionchanged:: 3.4.3
       *context* was added.
 
+   .. deprecated:: 3.6
+
+       *cafile*, *capath* and *cadefault* are deprecated in favor of *context*.
+       Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let
+       :func:`ssl.create_default_context` select the system's trusted CA
+       certificates for you.
 
 .. function:: install_opener(opener)
 
index 396e6aed5673c4c6323ae7f8e091c0ff9ab0e3a9..ac8a8ef752ce943ccedfdb6d8436e34e5010b806 100644 (file)
@@ -117,10 +117,10 @@ class SSLWSGIServerMixin:
                                 'test', 'test_asyncio')
         keyfile = os.path.join(here, 'ssl_key.pem')
         certfile = os.path.join(here, 'ssl_cert.pem')
-        ssock = ssl.wrap_socket(request,
-                                keyfile=keyfile,
-                                certfile=certfile,
-                                server_side=True)
+        context = ssl.SSLContext()
+        context.load_cert_chain(certfile, keyfile)
+
+        ssock = context.wrap_socket(request, server_side=True)
         try:
             self.RequestHandlerClass(ssock, client_address, self)
             ssock.close()
index ee2a137a5c472ec31293addaa63336be280b9c3e..8f36f537e8a54f550a4678a5afeb57aa070918bf 100644 (file)
@@ -728,6 +728,10 @@ else:
             if context is not None and certfile is not None:
                 raise ValueError("context and certfile arguments are mutually "
                                  "exclusive")
+            if keyfile is not None or certfile is not None:
+                import warnings
+                warnings.warn("keyfile and certfile are deprecated, use a"
+                              "custom context instead", DeprecationWarning, 2)
             self.keyfile = keyfile
             self.certfile = certfile
             if context is None:
index 6ee19135452c834f891d2b96bbce82d7a169da2a..a8e59b95616b4ce3863a03b61d1d618749eb7146 100644 (file)
@@ -1365,6 +1365,12 @@ else:
                      check_hostname=None):
             super(HTTPSConnection, self).__init__(host, port, timeout,
                                                   source_address)
+            if (key_file is not None or cert_file is not None or
+                        check_hostname is not None):
+                import warnings
+                warnings.warn("key_file, cert_file and check_hostname are "
+                              "deprecated, use a custom context instead.",
+                              DeprecationWarning, 2)
             self.key_file = key_file
             self.cert_file = cert_file
             if context is None:
index 965ed83f2b49a6fac5494f17e00d1f7b4d844788..cad508add8d697332de106d5057f7361320135c8 100644 (file)
@@ -1267,7 +1267,10 @@ if HAVE_SSL:
             if ssl_context is not None and certfile is not None:
                 raise ValueError("ssl_context and certfile arguments are mutually "
                                  "exclusive")
-
+            if keyfile is not None or certfile is not None:
+                import warnings
+                warnings.warn("keyfile and certfile are deprecated, use a"
+                              "custom ssl_context instead", DeprecationWarning, 2)
             self.keyfile = keyfile
             self.certfile = certfile
             if ssl_context is None:
index f6723904e859e12d871aa71c88a426e911372e95..cae6950eb6d2d6c980bbdf7f6aeb507a35e88b7e 100644 (file)
@@ -431,6 +431,10 @@ if HAVE_SSL:
             if context is not None and certfile is not None:
                 raise ValueError("context and certfile arguments are mutually "
                                  "exclusive")
+            if keyfile is not None or certfile is not None:
+                import warnings
+                warnings.warn("keyfile and certfile are deprecated, use a"
+                              "custom context instead", DeprecationWarning, 2)
             self.keyfile = keyfile
             self.certfile = certfile
             if context is None:
index 5b9e66536a899cce211b08520704068319edde0f..f7c2c77ab42075b7ba75fe74cbcf7f51324ff7dd 100755 (executable)
@@ -759,6 +759,10 @@ class SMTP:
             if context is not None and certfile is not None:
                 raise ValueError("context and certfile arguments are mutually "
                                  "exclusive")
+            if keyfile is not None or certfile is not None:
+                import warnings
+                warnings.warn("keyfile and certfile are deprecated, use a"
+                              "custom context instead", DeprecationWarning, 2)
             if context is None:
                 context = ssl._create_stdlib_context(certfile=certfile,
                                                      keyfile=keyfile)
@@ -1011,6 +1015,10 @@ if _have_ssl:
             if context is not None and certfile is not None:
                 raise ValueError("context and certfile arguments are mutually "
                                  "exclusive")
+            if keyfile is not None or certfile is not None:
+                import warnings
+                warnings.warn("keyfile and certfile are deprecated, use a"
+                              "custom context instead", DeprecationWarning, 2)
             self.keyfile = keyfile
             self.certfile = certfile
             if context is None:
index 3400b7f3f0b8d73d1c5809f6f5c652cadf3a9b4e..f3da4649861c449088ff8de126c874782a01a699 100644 (file)
@@ -1091,7 +1091,6 @@ def wrap_socket(sock, keyfile=None, certfile=None,
                 do_handshake_on_connect=True,
                 suppress_ragged_eofs=True,
                 ciphers=None):
-
     return SSLSocket(sock=sock, keyfile=keyfile, certfile=certfile,
                      server_side=server_side, cert_reqs=cert_reqs,
                      ssl_version=ssl_version, ca_certs=ca_certs,
index 9d8de211df8662dc6e91d095bc5cd235dc5f39c8..12fabc5e8be3d69a28f7b2c13e6ee9fffb6a8db6 100644 (file)
@@ -311,10 +311,12 @@ if ssl is not None:
         _ssl_closing = False
 
         def secure_connection(self):
-            socket = ssl.wrap_socket(self.socket, suppress_ragged_eofs=False,
-                                     certfile=CERTFILE, server_side=True,
-                                     do_handshake_on_connect=False,
-                                     ssl_version=ssl.PROTOCOL_SSLv23)
+            context = ssl.SSLContext()
+            context.load_cert_chain(CERTFILE)
+            socket = context.wrap_socket(self.socket,
+                                         suppress_ragged_eofs=False,
+                                         server_side=True,
+                                         do_handshake_on_connect=False)
             self.del_channel()
             self.set_socket(socket)
             self._ssl_accepting = True
index 8e4990b3cf7080ee21425251a04ef2d4fefbb09a..f95ebf4757110a4346abbe9bf0f0e462490f170f 100644 (file)
@@ -77,9 +77,9 @@ if ssl:
 
         def get_request(self):
             newsocket, fromaddr = self.socket.accept()
-            connstream = ssl.wrap_socket(newsocket,
-                                         server_side=True,
-                                         certfile=CERTFILE)
+            context = ssl.SSLContext()
+            context.load_cert_chain(CERTFILE)
+            connstream = context.wrap_socket(newsocket, server_side=True)
             return connstream, fromaddr
 
     IMAP4_SSL = imaplib.IMAP4_SSL
index 2ef6d02c2bffbe5b25e72851e3d8fb33c4e9acf8..feaba3c3c014cc634c19a14ee81b7b542d5dacf0 100644 (file)
@@ -1542,8 +1542,10 @@ class LocalServerTests(unittest.TestCase):
                 elif cmd == b'STARTTLS\r\n':
                     reader.close()
                     client.sendall(b'382 Begin TLS negotiation now\r\n')
-                    client = ssl.wrap_socket(
-                        client, server_side=True, certfile=certfile)
+                    context = ssl.SSLContext()
+                    context.load_cert_chain(certfile)
+                    client = context.wrap_socket(
+                        client, server_side=True)
                     cleanup.enter_context(client)
                     reader = cleanup.enter_context(client.makefile('rb'))
                 elif cmd == b'QUIT\r\n':
index 7b9606d35933719ae105c203623b084d757c9bdb..e5b16dc98a41113d47e81c7ede3797cea5eb1f19 100644 (file)
@@ -152,10 +152,12 @@ class DummyPOP3Handler(asynchat.async_chat):
         def cmd_stls(self, arg):
             if self.tls_active is False:
                 self.push('+OK Begin TLS negotiation')
-                tls_sock = ssl.wrap_socket(self.socket, certfile=CERTFILE,
-                                           server_side=True,
-                                           do_handshake_on_connect=False,
-                                           suppress_ragged_eofs=False)
+                context = ssl.SSLContext()
+                context.load_cert_chain(CERTFILE)
+                tls_sock = context.wrap_socket(self.socket,
+                                               server_side=True,
+                                               do_handshake_on_connect=False,
+                                               suppress_ragged_eofs=False)
                 self.del_channel()
                 self.set_socket(tls_sock)
                 self.tls_active = True
index 7488dc7baa20d83fd5cb5cfbcd3f70f9c0e8cb12..aed226c7e1f27da183a0060c8d5b533c941d50d6 100644 (file)
@@ -143,6 +143,21 @@ def skip_if_broken_ubuntu_ssl(func):
 needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
 
 
+def test_wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLS, *,
+                     cert_reqs=ssl.CERT_NONE, ca_certs=None,
+                     ciphers=None, certfile=None, keyfile=None,
+                     **kwargs):
+    context = ssl.SSLContext(ssl_version)
+    if cert_reqs is not None:
+        context.verify_mode = cert_reqs
+    if ca_certs is not None:
+        context.load_verify_locations(ca_certs)
+    if certfile is not None or keyfile is not None:
+        context.load_cert_chain(certfile, keyfile)
+    if ciphers is not None:
+        context.set_ciphers(ciphers)
+    return context.wrap_socket(sock, **kwargs)
+
 class BasicSocketTests(unittest.TestCase):
 
     def test_constants(self):
@@ -363,7 +378,7 @@ class BasicSocketTests(unittest.TestCase):
         # Issue #7943: an SSL object doesn't create reference cycles with
         # itself.
         s = socket.socket(socket.AF_INET)
-        ss = ssl.wrap_socket(s)
+        ss = test_wrap_socket(s)
         wr = weakref.ref(ss)
         with support.check_warnings(("", ResourceWarning)):
             del ss
@@ -373,7 +388,7 @@ class BasicSocketTests(unittest.TestCase):
         # Methods on an unconnected SSLSocket propagate the original
         # OSError raise by the underlying socket object.
         s = socket.socket(socket.AF_INET)
-        with ssl.wrap_socket(s) as ss:
+        with test_wrap_socket(s) as ss:
             self.assertRaises(OSError, ss.recv, 1)
             self.assertRaises(OSError, ss.recv_into, bytearray(b'x'))
             self.assertRaises(OSError, ss.recvfrom, 1)
@@ -387,10 +402,10 @@ class BasicSocketTests(unittest.TestCase):
         for timeout in (None, 0.0, 5.0):
             s = socket.socket(socket.AF_INET)
             s.settimeout(timeout)
-            with ssl.wrap_socket(s) as ss:
+            with test_wrap_socket(s) as ss:
                 self.assertEqual(timeout, ss.gettimeout())
 
-    def test_errors(self):
+    def test_errors_sslwrap(self):
         sock = socket.socket()
         self.assertRaisesRegex(ValueError,
                         "certfile must be specified",
@@ -400,10 +415,10 @@ class BasicSocketTests(unittest.TestCase):
                         ssl.wrap_socket, sock, server_side=True)
         self.assertRaisesRegex(ValueError,
                         "certfile must be specified for server-side operations",
-                        ssl.wrap_socket, sock, server_side=True, certfile="")
+                         ssl.wrap_socket, sock, server_side=True, certfile="")
         with ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) as s:
             self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
-                                    s.connect, (HOST, 8080))
+                                     s.connect, (HOST, 8080))
         with self.assertRaises(OSError) as cm:
             with socket.socket() as sock:
                 ssl.wrap_socket(sock, certfile=NONEXISTINGCERT)
@@ -426,7 +441,7 @@ class BasicSocketTests(unittest.TestCase):
         sock = socket.socket()
         self.addCleanup(sock.close)
         with self.assertRaises(ssl.SSLError):
-            ssl.wrap_socket(sock,
+            test_wrap_socket(sock,
                             certfile=certfile,
                             ssl_version=ssl.PROTOCOL_TLSv1)
 
@@ -613,7 +628,7 @@ class BasicSocketTests(unittest.TestCase):
         s.listen()
         c = socket.socket(socket.AF_INET)
         c.connect(s.getsockname())
-        with ssl.wrap_socket(c, do_handshake_on_connect=False) as ss:
+        with test_wrap_socket(c, do_handshake_on_connect=False) as ss:
             with self.assertRaises(ValueError):
                 ss.get_channel_binding("unknown-type")
         s.close()
@@ -623,15 +638,15 @@ class BasicSocketTests(unittest.TestCase):
     def test_tls_unique_channel_binding(self):
         # unconnected should return None for known type
         s = socket.socket(socket.AF_INET)
-        with ssl.wrap_socket(s) as ss:
+        with test_wrap_socket(s) as ss:
             self.assertIsNone(ss.get_channel_binding("tls-unique"))
         # the same for server-side
         s = socket.socket(socket.AF_INET)
-        with ssl.wrap_socket(s, server_side=True, certfile=CERTFILE) as ss:
+        with test_wrap_socket(s, server_side=True, certfile=CERTFILE) as ss:
             self.assertIsNone(ss.get_channel_binding("tls-unique"))
 
     def test_dealloc_warn(self):
-        ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
+        ss = test_wrap_socket(socket.socket(socket.AF_INET))
         r = repr(ss)
         with self.assertWarns(ResourceWarning) as cm:
             ss = None
@@ -750,7 +765,7 @@ class BasicSocketTests(unittest.TestCase):
         s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
         self.addCleanup(s.close)
         with self.assertRaises(NotImplementedError) as cx:
-            ssl.wrap_socket(s, cert_reqs=ssl.CERT_NONE)
+            test_wrap_socket(s, cert_reqs=ssl.CERT_NONE)
         self.assertEqual(str(cx.exception), "only stream sockets are supported")
         ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
         with self.assertRaises(NotImplementedError) as cx:
@@ -826,7 +841,7 @@ class BasicSocketTests(unittest.TestCase):
         server = socket.socket(socket.AF_INET)
         self.addCleanup(server.close)
         port = support.bind_port(server)  # Reserve port but don't listen
-        s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+        s = test_wrap_socket(socket.socket(socket.AF_INET),
                             cert_reqs=ssl.CERT_REQUIRED)
         self.addCleanup(s.close)
         rc = s.connect_ex((HOST, port))
@@ -1444,13 +1459,13 @@ class SimpleBackgroundTests(unittest.TestCase):
         self.addCleanup(server.__exit__, None, None, None)
 
     def test_connect(self):
-        with ssl.wrap_socket(socket.socket(socket.AF_INET),
+        with test_wrap_socket(socket.socket(socket.AF_INET),
                             cert_reqs=ssl.CERT_NONE) as s:
             s.connect(self.server_addr)
             self.assertEqual({}, s.getpeercert())
 
         # this should succeed because we specify the root cert
-        with ssl.wrap_socket(socket.socket(socket.AF_INET),
+        with test_wrap_socket(socket.socket(socket.AF_INET),
                             cert_reqs=ssl.CERT_REQUIRED,
                             ca_certs=SIGNING_CA) as s:
             s.connect(self.server_addr)
@@ -1460,7 +1475,7 @@ class SimpleBackgroundTests(unittest.TestCase):
         # This should fail because we have no verification certs. Connection
         # failure crashes ThreadedEchoServer, so run this in an independent
         # test method.
-        s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+        s = test_wrap_socket(socket.socket(socket.AF_INET),
                             cert_reqs=ssl.CERT_REQUIRED)
         self.addCleanup(s.close)
         self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
@@ -1468,7 +1483,7 @@ class SimpleBackgroundTests(unittest.TestCase):
 
     def test_connect_ex(self):
         # Issue #11326: check connect_ex() implementation
-        s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+        s = test_wrap_socket(socket.socket(socket.AF_INET),
                             cert_reqs=ssl.CERT_REQUIRED,
                             ca_certs=SIGNING_CA)
         self.addCleanup(s.close)
@@ -1478,7 +1493,7 @@ class SimpleBackgroundTests(unittest.TestCase):
     def test_non_blocking_connect_ex(self):
         # Issue #11326: non-blocking connect_ex() should allow handshake
         # to proceed after the socket gets ready.
-        s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+        s = test_wrap_socket(socket.socket(socket.AF_INET),
                             cert_reqs=ssl.CERT_REQUIRED,
                             ca_certs=SIGNING_CA,
                             do_handshake_on_connect=False)
@@ -1578,7 +1593,7 @@ class SimpleBackgroundTests(unittest.TestCase):
         # Issue #5238: creating a file-like object with makefile() shouldn't
         # delay closing the underlying "real socket" (here tested with its
         # file descriptor, hence skipping the test under Windows).
-        ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
+        ss = test_wrap_socket(socket.socket(socket.AF_INET))
         ss.connect(self.server_addr)
         fd = ss.fileno()
         f = ss.makefile()
@@ -1596,7 +1611,7 @@ class SimpleBackgroundTests(unittest.TestCase):
         s = socket.socket(socket.AF_INET)
         s.connect(self.server_addr)
         s.setblocking(False)
-        s = ssl.wrap_socket(s,
+        s = test_wrap_socket(s,
                             cert_reqs=ssl.CERT_NONE,
                             do_handshake_on_connect=False)
         self.addCleanup(s.close)
@@ -1622,16 +1637,16 @@ class SimpleBackgroundTests(unittest.TestCase):
         _test_get_server_certificate_fail(self, *self.server_addr)
 
     def test_ciphers(self):
-        with ssl.wrap_socket(socket.socket(socket.AF_INET),
+        with test_wrap_socket(socket.socket(socket.AF_INET),
                              cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s:
             s.connect(self.server_addr)
-        with ssl.wrap_socket(socket.socket(socket.AF_INET),
+        with test_wrap_socket(socket.socket(socket.AF_INET),
                              cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") as s:
             s.connect(self.server_addr)
         # Error checking can happen at instantiation or when connecting
         with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
             with socket.socket(socket.AF_INET) as sock:
-                s = ssl.wrap_socket(sock,
+                s = test_wrap_socket(sock,
                                     cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
                 s.connect(self.server_addr)
 
@@ -1749,7 +1764,7 @@ class NetworkedTests(unittest.TestCase):
         # Issue #12065: on a timeout, connect_ex() should return the original
         # errno (mimicking the behaviour of non-SSL sockets).
         with support.transient_internet(REMOTE_HOST):
-            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+            s = test_wrap_socket(socket.socket(socket.AF_INET),
                                 cert_reqs=ssl.CERT_REQUIRED,
                                 do_handshake_on_connect=False)
             self.addCleanup(s.close)
@@ -2040,7 +2055,7 @@ if _have_threads:
             class ConnectionHandler (asyncore.dispatcher_with_send):
 
                 def __init__(self, conn, certfile):
-                    self.socket = ssl.wrap_socket(conn, server_side=True,
+                    self.socket = test_wrap_socket(conn, server_side=True,
                                                   certfile=certfile,
                                                   do_handshake_on_connect=False)
                     asyncore.dispatcher_with_send.__init__(self, self.socket)
@@ -2401,7 +2416,7 @@ if _have_threads:
                                         connectionchatty=False)
             with server, \
                     socket.socket() as sock, \
-                    ssl.wrap_socket(sock,
+                    test_wrap_socket(sock,
                                         certfile=certfile,
                                         ssl_version=ssl.PROTOCOL_TLSv1) as s:
                 try:
@@ -2448,7 +2463,7 @@ if _have_threads:
                     c.connect((HOST, port))
                     listener_gone.wait()
                     try:
-                        ssl_sock = ssl.wrap_socket(c)
+                        ssl_sock = test_wrap_socket(c)
                     except OSError:
                         pass
                     else:
@@ -2638,7 +2653,7 @@ if _have_threads:
                             sys.stdout.write(
                                 " client:  read %r from server, starting TLS...\n"
                                 % msg)
-                        conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
+                        conn = test_wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
                         wrapped = True
                     elif indata == b"ENDTLS" and msg.startswith(b"ok"):
                         # ENDTLS ok, switch back to clear text
@@ -2699,7 +2714,7 @@ if _have_threads:
             indata = b"FOO\n"
             server = AsyncoreEchoServer(CERTFILE)
             with server:
-                s = ssl.wrap_socket(socket.socket())
+                s = test_wrap_socket(socket.socket())
                 s.connect(('127.0.0.1', server.port))
                 if support.verbose:
                     sys.stdout.write(
@@ -2732,7 +2747,7 @@ if _have_threads:
                                         chatty=True,
                                         connectionchatty=False)
             with server:
-                s = ssl.wrap_socket(socket.socket(),
+                s = test_wrap_socket(socket.socket(),
                                     server_side=False,
                                     certfile=CERTFILE,
                                     ca_certs=CERTFILE,
@@ -2856,7 +2871,7 @@ if _have_threads:
             self.addCleanup(server.__exit__, None, None)
             s = socket.create_connection((HOST, server.port))
             self.addCleanup(s.close)
-            s = ssl.wrap_socket(s, suppress_ragged_eofs=False)
+            s = test_wrap_socket(s, suppress_ragged_eofs=False)
             self.addCleanup(s.close)
 
             # recv/read(0) should return no data
@@ -2878,7 +2893,7 @@ if _have_threads:
                                         chatty=True,
                                         connectionchatty=False)
             with server:
-                s = ssl.wrap_socket(socket.socket(),
+                s = test_wrap_socket(socket.socket(),
                                     server_side=False,
                                     certfile=CERTFILE,
                                     ca_certs=CERTFILE,
@@ -2932,12 +2947,12 @@ if _have_threads:
                     c.connect((host, port))
                     # Will attempt handshake and time out
                     self.assertRaisesRegex(socket.timeout, "timed out",
-                                           ssl.wrap_socket, c)
+                                           test_wrap_socket, c)
                 finally:
                     c.close()
                 try:
                     c = socket.socket(socket.AF_INET)
-                    c = ssl.wrap_socket(c)
+                    c = test_wrap_socket(c)
                     c.settimeout(0.2)
                     # Will attempt handshake and time out
                     self.assertRaisesRegex(socket.timeout, "timed out",
@@ -3062,7 +3077,7 @@ if _have_threads:
                                         chatty=True,
                                         connectionchatty=False)
             with server:
-                s = ssl.wrap_socket(socket.socket(),
+                s = test_wrap_socket(socket.socket(),
                                     server_side=False,
                                     certfile=CERTFILE,
                                     ca_certs=CERTFILE,
@@ -3087,7 +3102,7 @@ if _have_threads:
                 s.close()
 
                 # now, again
-                s = ssl.wrap_socket(socket.socket(),
+                s = test_wrap_socket(socket.socket(),
                                     server_side=False,
                                     certfile=CERTFILE,
                                     ca_certs=CERTFILE,
index 8f06b08afa0ee7bcf0f1cc564512e1817fc8372a..43ea6b8b57e5b442ad226a65dc3f100aca201ee2 100644 (file)
@@ -469,10 +469,11 @@ Connection: close
     @unittest.skipUnless(ssl, "ssl module required")
     def test_cafile_and_context(self):
         context = ssl.create_default_context()
-        with self.assertRaises(ValueError):
-            urllib.request.urlopen(
-                "https://localhost", cafile="/nonexistent/path", context=context
-            )
+        with support.check_warnings(('', DeprecationWarning)):
+            with self.assertRaises(ValueError):
+                urllib.request.urlopen(
+                    "https://localhost", cafile="/nonexistent/path", context=context
+                )
 
 class urlopen_DataTests(unittest.TestCase):
     """Test urlopen() opening a data URL."""
index e9564fde621a07c30d6e1808b29f207e3a3d781a..e6a522c6c5e93e0b5dc869adea77cf033c1da826 100644 (file)
@@ -548,26 +548,28 @@ class TestUrlopen(unittest.TestCase):
 
     def test_https_with_cafile(self):
         handler = self.start_https_server(certfile=CERT_localhost)
-        # Good cert
-        data = self.urlopen("https://localhost:%s/bizarre" % handler.port,
-                            cafile=CERT_localhost)
-        self.assertEqual(data, b"we care a bit")
-        # Bad cert
-        with self.assertRaises(urllib.error.URLError) as cm:
-            self.urlopen("https://localhost:%s/bizarre" % handler.port,
-                         cafile=CERT_fakehostname)
-        # Good cert, but mismatching hostname
-        handler = self.start_https_server(certfile=CERT_fakehostname)
-        with self.assertRaises(ssl.CertificateError) as cm:
-            self.urlopen("https://localhost:%s/bizarre" % handler.port,
-                         cafile=CERT_fakehostname)
+        with support.check_warnings(('', DeprecationWarning)):
+            # Good cert
+            data = self.urlopen("https://localhost:%s/bizarre" % handler.port,
+                                cafile=CERT_localhost)
+            self.assertEqual(data, b"we care a bit")
+            # Bad cert
+            with self.assertRaises(urllib.error.URLError) as cm:
+                self.urlopen("https://localhost:%s/bizarre" % handler.port,
+                             cafile=CERT_fakehostname)
+            # Good cert, but mismatching hostname
+            handler = self.start_https_server(certfile=CERT_fakehostname)
+            with self.assertRaises(ssl.CertificateError) as cm:
+                self.urlopen("https://localhost:%s/bizarre" % handler.port,
+                             cafile=CERT_fakehostname)
 
     def test_https_with_cadefault(self):
         handler = self.start_https_server(certfile=CERT_localhost)
         # Self-signed cert should fail verification with system certificate store
-        with self.assertRaises(urllib.error.URLError) as cm:
-            self.urlopen("https://localhost:%s/bizarre" % handler.port,
-                         cadefault=True)
+        with support.check_warnings(('', DeprecationWarning)):
+            with self.assertRaises(urllib.error.URLError) as cm:
+                self.urlopen("https://localhost:%s/bizarre" % handler.port,
+                             cadefault=True)
 
     def test_https_sni(self):
         if ssl is None:
index cc4f0bf089568b394e9c8fc0b7b357e414a99598..5f15b74f4dec076dd859e41543bdd2f7e3866c52 100644 (file)
@@ -198,6 +198,9 @@ def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
     '''
     global _opener
     if cafile or capath or cadefault:
+        import warnings
+        warnings.warn("cafile, cpath and cadefault are deprecated, use a "
+                      "custom context instead.", DeprecationWarning, 2)
         if context is not None:
             raise ValueError(
                 "You can't pass both context and any of cafile, capath, and "
index 7ea7a5b5c087efb94997f2060e12541f289a512b..eaf452c7983ba518d38d9cb91f07c0099d4aa7b6 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -138,7 +138,11 @@ Core and Builtins
 Library
 -------
 
-- Issue 28043: SSLContext has improved default settings: OP_NO_SSLv2,
+- Issue #28022: Deprecate ssl-related arguments in favor of SSLContext. The
+  deprecation include manual creation of SSLSocket and certfile/keyfile
+  (or similar) in ftplib, httplib, imaplib, smtplib, poplib and urllib.
+
+- Issue #28043: SSLContext has improved default settings: OP_NO_SSLv2,
   OP_NO_SSLv3, OP_NO_COMPRESSION, OP_CIPHER_SERVER_PREFERENCE,
   OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE and HIGH ciphers without MD5.