From c62f95026e83ebe97a1130b2fd969fa614cb47a9 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye Date: Tue, 6 Dec 2022 08:47:28 -0600 Subject: [PATCH] warn for ssl --- Lib/socket.py | 10 +++++++--- Lib/ssl.py | 7 ++++++- Lib/test/test_socket.py | 10 ++++++++++ Lib/test/test_ssl.py | 31 +++++++++++++++++++++++++++++++ Lib/warnings.py | 2 +- Modules/_ssl.c | 18 ++++++++++++++++++ 6 files changed, 73 insertions(+), 5 deletions(-) diff --git a/Lib/socket.py b/Lib/socket.py index 437634cc3b58ce..50f345d83212ab 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -45,10 +45,14 @@ """ import _socket +import warnings from _socket import * from functools import partial from types import MethodType +warnings.warnpy3k_with_fix("socket.sslerror is not supported in 3.x", +"use from _ssl import SSLError as sslerror", stacklevel=2) + try: import _ssl except ImportError: @@ -59,8 +63,8 @@ def ssl(sock, keyfile=None, certfile=None): # we do an internal import here because the ssl # module imports the socket module import ssl as _realssl - warnings.warn("socket.ssl() is deprecated. Use ssl.wrap_socket() instead.", - DeprecationWarning, stacklevel=2) + warnings.warnpy3k_with_fix("socket.ssl() is removed in 3.x", "use ssl.wrap_socket() instead.", + stacklevel=2) return _realssl.sslwrap_simple(sock, keyfile, certfile) # we need to import the same constants we used to... @@ -83,7 +87,7 @@ def ssl(sock, keyfile=None, certfile=None): # LibreSSL does not provide RAND_egd pass -import os, sys, warnings +import os, sys try: from cStringIO import StringIO diff --git a/Lib/ssl.py b/Lib/ssl.py index 0bb43a4a4de11e..262406289b76b8 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -95,6 +95,10 @@ from collections import namedtuple from contextlib import closing +import warnings +warnings.warnpy3k_with_fix("ssl.textwrap, ssl.re, ssl.closing modules are not supported in 3.x", + "import textwrap, re and closing modules directly instead.", stacklevel=2) + import _ssl # if we can't import it, let the error propagate from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION @@ -145,7 +149,6 @@ def _import_symbols(prefix): from socket import SOL_SOCKET, SO_TYPE import base64 # for DER-to-PEM translation import errno -import warnings if _ssl.HAS_TLS_UNIQUE: CHANNEL_BINDING_TYPES = ['tls-unique'] @@ -1016,6 +1019,8 @@ def sslwrap_simple(sock, keyfile=None, certfile=None): """A replacement for the old socket.ssl function. Designed for compability with Python 2.5 and earlier. Will disappear in Python 3.0.""" + warnings.warnpy3k_with_fix("ssl.sslwrap_simple() is removed in 3.x", + "use ssl.wrap_socket() instead.", stacklevel=2) if hasattr(sock, "_sock"): sock = sock._sock diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 988e12a813d5fb..b4c99f18b73df8 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -773,6 +773,16 @@ def test_flowinfo(self): finally: s.close() + def _test_socket_sslerror(self): + expected = "socket.sslerror is not supported in 3.x: use from '_ssl import SSLError as sslerror'" + with test_support.check_py3k_warnings(expected, DeprecationWarning): + from socket import sslerror + + def _test_socket_ssl(self): + expected = "socket.ssl() is removed in 3.x: use ssl.wrap_socket() instead." + with test_support.check_py3k_warnings(expected, DeprecationWarning): + from socket import ssl + @unittest.skipUnless(thread, 'Threading required for this test.') class BasicTCPTest(SocketConnectedTest): diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index ef2e59c1d15d06..ea42d7e42cecb0 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -4,6 +4,7 @@ import sys import unittest from test import test_support as support +from test import test_support from test.script_helper import assert_python_ok import asyncore import socket @@ -111,6 +112,36 @@ def test_sslwrap_simple(self): else: raise + def test_py3k_removed_ssl_modules(self): + expected = "ssl.textwrap, ssl.re, ssl.closing modules are not supported in 3.x: import textwrap, re and closing modules directly instead." + with test_support.check_py3k_warnings(expected, DeprecationWarning): + import ssl + + def test_py3k_sslwrap_simple(self): + expected = "ssl.sslwrap_simple() is removed in 3.x: use ssl.wrap_socket() instead." + with test_support.check_py3k_warnings(expected, DeprecationWarning): + from ssl import sslwrap_simple + + def test_py3k_protocols_tlsv11(self): + expected = "ssl.PROTOCOL_TLSv1_1 is not supported in some 3.x versions: use ssl.PROTOCOL_TLS instead" + with test_support.check_py3k_warnings(expected, DeprecationWarning): + ssl.PROTOCOL_TLSv1_1 + + def test_py3k_protocols_tlsv12(self): + expected = "ssl.PROTOCOL_TLSv1_2 is not supported in some 3.x versions: use ssl.PROTOCOL_TLS instead" + with test_support.check_py3k_warnings(expected, DeprecationWarning): + ssl.PROTOCOL_TLSv1_2 + + def test_py3k_protocols_sslv3(self): + expected = "ssl.PROTOCOL_SSLv3 is not supported in some 3.x versions: use ssl.PROTOCOL_SSLv23 instead" + with test_support.check_py3k_warnings(expected, DeprecationWarning): + ssl.PROTOCOL_SSLv3 + + def test_py3k_protocols_sslv3(self): + expected = "ssl.PROTOCOL_SSLv2 is not supported in some 3.x versions: use ssl.PROTOCOL_SSLv23 instead" + with test_support.check_py3k_warnings(expected, DeprecationWarning): + ssl.PROTOCOL_SSLv2 + def can_clear_options(): # 0.9.8m or higher diff --git a/Lib/warnings.py b/Lib/warnings.py index 41bd2501d32891..074fe5bd6e2689 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -23,7 +23,7 @@ def warnpy3k(message, category=None, stacklevel=1): category = DeprecationWarning warn(message, category, stacklevel+1) -def warnpy3k_with_fix(message, category=None, stacklevel=1): +def warnpy3k_with_fix(message, fix, category=None, stacklevel=1): """Issue a deprecation warning for Python 3.x related changes and a fix. Warnings are omitted unless Python is started with the -3 option. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 98c8a5a4a95ca9..ff59cab857b770 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -565,6 +565,16 @@ _setSSLError (char *errstr, int errcode, char *filename, int lineno) { return NULL; } +static int +_ssl_incompatible(const char* msg, const char* fix, int stacklevel) { + return PyErr_WarnEx_WithFix( + PyExc_SyntaxWarning, msg, fix, stacklevel + ); +} + +#define PY_SSL_INCOMPATIBLE(name, fix, stacklevel, ret) \ + if (_ssl_incompatible((name), (fix), (stacklevel)) == -1) return (ret) + /* * SSL objects */ @@ -2193,16 +2203,24 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ctx = SSL_CTX_new(TLSv1_method()); #if HAVE_TLSv1_2 else if (proto_version == PY_SSL_VERSION_TLS1_1) + PY_SSL_INCOMPATIBLE("ssl.PROTOCOL_TLSv1_1 is not supported in some 3.x versions", + "use ssl.PROTOCOL_TLS instead", 2, NULL); ctx = SSL_CTX_new(TLSv1_1_method()); else if (proto_version == PY_SSL_VERSION_TLS1_2) + PY_SSL_INCOMPATIBLE("ssl.PROTOCOL_TLSv1_2 is not supported in some 3.x versions", + "use ssl.PROTOCOL_TLS instead", 2, NULL); ctx = SSL_CTX_new(TLSv1_2_method()); #endif #ifndef OPENSSL_NO_SSL3 else if (proto_version == PY_SSL_VERSION_SSL3) + PY_SSL_INCOMPATIBLE("ssl.PROTOCOL_SSLv3 is not supported in some 3.x versions", + "use ssl.PROTOCOL_SSLv23 instead", 2, NULL); ctx = SSL_CTX_new(SSLv3_method()); #endif #ifndef OPENSSL_NO_SSL2 else if (proto_version == PY_SSL_VERSION_SSL2) + PY_SSL_INCOMPATIBLE("ssl.PROTOCOL_SSLv2 is not supported in some 3.x versions", + "use ssl.PROTOCOL_SSLv23 instead", 2, NULL); ctx = SSL_CTX_new(SSLv2_method()); #endif else if (proto_version == PY_SSL_VERSION_TLS)