summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2016-09-10 21:23:33 (GMT)
committerChristian Heimes <christian@python.org>2016-09-10 21:23:33 (GMT)
commitd04863771b0c5bedeb1e4afe05dcba3adcc0fb58 (patch)
treefcd2630f24f426d5c1b084a9e16fe69ae4f5143a
parent130bbe5fd3d0bd0c494078aff19a5f8108707b89 (diff)
downloadcpython-d04863771b0c5bedeb1e4afe05dcba3adcc0fb58.zip
cpython-d04863771b0c5bedeb1e4afe05dcba3adcc0fb58.tar.gz
cpython-d04863771b0c5bedeb1e4afe05dcba3adcc0fb58.tar.bz2
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. ssl.wrap_socket() is not marked as deprecated yet.
-rw-r--r--Doc/library/ftplib.rst7
-rw-r--r--Doc/library/http.client.rst18
-rw-r--r--Doc/library/imaplib.rst8
-rw-r--r--Doc/library/poplib.rst7
-rw-r--r--Doc/library/smtplib.rst8
-rw-r--r--Doc/library/ssl.rst13
-rw-r--r--Doc/library/urllib.request.rst6
-rw-r--r--Lib/asyncio/test_utils.py8
-rw-r--r--Lib/ftplib.py4
-rw-r--r--Lib/http/client.py6
-rw-r--r--Lib/imaplib.py5
-rw-r--r--Lib/poplib.py4
-rwxr-xr-xLib/smtplib.py8
-rw-r--r--Lib/ssl.py1
-rw-r--r--Lib/test/test_ftplib.py10
-rw-r--r--Lib/test/test_imaplib.py6
-rw-r--r--Lib/test/test_nntplib.py6
-rw-r--r--Lib/test/test_poplib.py10
-rw-r--r--Lib/test/test_ssl.py87
-rw-r--r--Lib/test/test_urllib.py9
-rw-r--r--Lib/test/test_urllib2_localnet.py34
-rw-r--r--Lib/urllib/request.py3
-rw-r--r--Misc/NEWS6
23 files changed, 189 insertions, 85 deletions
diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst
index 1e35f37..b8c1dcf 100644
--- a/Doc/library/ftplib.rst
+++ b/Doc/library/ftplib.rst
@@ -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')
diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst
index 90c0421..17f289d 100644
--- a/Doc/library/http.client.rst
+++ b/Doc/library/http.client.rst
@@ -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)
diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst
index b9b3b91..7024a1b 100644
--- a/Doc/library/imaplib.rst
+++ b/Doc/library/imaplib.rst
@@ -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:
diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst
index ffabc32..d72b660 100644
--- a/Doc/library/poplib.rst
+++ b/Doc/library/poplib.rst
@@ -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:
diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst
index 83d5c2d..1cb3aaf 100644
--- a/Doc/library/smtplib.rst
+++ b/Doc/library/smtplib.rst
@@ -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
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index 98008fa..af0c5ab 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -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
diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst
index d288165..491bded 100644
--- a/Doc/library/urllib.request.rst
+++ b/Doc/library/urllib.request.rst
@@ -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)
diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py
index 396e6ae..ac8a8ef 100644
--- a/Lib/asyncio/test_utils.py
+++ b/Lib/asyncio/test_utils.py
@@ -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()
diff --git a/Lib/ftplib.py b/Lib/ftplib.py
index ee2a137..8f36f53 100644
--- a/Lib/ftplib.py
+++ b/Lib/ftplib.py
@@ -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:
diff --git a/Lib/http/client.py b/Lib/http/client.py
index 6ee1913..a8e59b9 100644
--- a/Lib/http/client.py
+++ b/Lib/http/client.py
@@ -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:
diff --git a/Lib/imaplib.py b/Lib/imaplib.py
index 965ed83..cad508a 100644
--- a/Lib/imaplib.py
+++ b/Lib/imaplib.py
@@ -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:
diff --git a/Lib/poplib.py b/Lib/poplib.py
index f672390..cae6950 100644
--- a/Lib/poplib.py
+++ b/Lib/poplib.py
@@ -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:
diff --git a/Lib/smtplib.py b/Lib/smtplib.py
index 5b9e665..f7c2c77 100755
--- a/Lib/smtplib.py
+++ b/Lib/smtplib.py
@@ -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:
diff --git a/Lib/ssl.py b/Lib/ssl.py
index 3400b7f..f3da464 100644
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -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,
diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py
index 9d8de21..12fabc5 100644
--- a/Lib/test/test_ftplib.py
+++ b/Lib/test/test_ftplib.py
@@ -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
diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py
index 8e4990b..f95ebf4 100644
--- a/Lib/test/test_imaplib.py
+++ b/Lib/test/test_imaplib.py
@@ -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
diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py
index 2ef6d02..feaba3c 100644
--- a/Lib/test/test_nntplib.py
+++ b/Lib/test/test_nntplib.py
@@ -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':
diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py
index 7b9606d..e5b16dc 100644
--- a/Lib/test/test_poplib.py
+++ b/Lib/test/test_poplib.py
@@ -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
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 7488dc7..aed226c 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -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,
diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
index 8f06b08..43ea6b8 100644
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -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."""
diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py
index e9564fd..e6a522c 100644
--- a/Lib/test/test_urllib2_localnet.py
+++ b/Lib/test/test_urllib2_localnet.py
@@ -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:
diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py
index cc4f0bf..5f15b74 100644
--- a/Lib/urllib/request.py
+++ b/Lib/urllib/request.py
@@ -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 "
diff --git a/Misc/NEWS b/Misc/NEWS
index 7ea7a5b..eaf452c 100644
--- 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.