From 2ddc5ec4e5289b57901330f813c04994b66574b3 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Tue, 13 Mar 2018 09:48:37 +0100 Subject: [PATCH] bpo-33023: SSL pickle error message Improve error message when trying to serialize SSLContext, SSLObject, and SSLSocket objects. The classes can't be pickled or copied by the copy module. Signed-off-by: Christian Heimes --- Lib/ssl.py | 16 ++++++++++++-- Lib/test/test_ssl.py | 22 +++++++++++++++++++ .../2018-03-13-09-48-02.bpo-33023.Zlszr2.rst | 3 +++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-03-13-09-48-02.bpo-33023.Zlszr2.rst diff --git a/Lib/ssl.py b/Lib/ssl.py index 2db8873547147a..01c749b2e3dc95 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -388,6 +388,10 @@ def __new__(cls, protocol=PROTOCOL_TLS, *args, **kwargs): self = _SSLContext.__new__(cls, protocol) return self + def __getstate__(self): + raise TypeError("cannot serialize {} object".format( + self.__class__.__name__)) + def _encode_hostname(self, hostname): if hostname is None: return None @@ -695,6 +699,10 @@ def server_hostname(self): server hostame is set.""" return self._sslobj.server_hostname + def __getstate__(self): + raise TypeError("cannot serialize {} object".format( + self.__class__.__name__)) + def read(self, len=1024, buffer=None): """Read up to 'len' bytes from the SSL object and return them. @@ -880,9 +888,13 @@ def session_reused(self): if self._sslobj is not None: return self._sslobj.session_reused + def __getstate__(self): + raise TypeError("cannot serialize {} object".format( + self.__class__.__name__)) + def dup(self): - raise NotImplemented("Can't dup() %s instances" % - self.__class__.__name__) + raise NotImplementedError("Can't dup() {} instances".format( + self.__class__.__name__)) def _checkClosed(self, msg=None): # raise an exception here if you wish to check for spurious closes diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 8d98b805b49a66..e6caf01406ac5f 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -19,6 +19,8 @@ import platform import functools import sysconfig +import copy +import pickle try: import ctypes except ImportError: @@ -972,6 +974,17 @@ def test_connect_ex_error(self): ) self.assertIn(rc, errors) + def test_copy_pickle(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + with ctx.wrap_socket(socket.socket(), + server_hostname='localhost') as s: + with self.assertRaises(TypeError): + copy.copy(s) + with self.assertRaises(TypeError): + copy.deepcopy(s) + with self.assertRaises(TypeError): + pickle.dumps(s) + class ContextTests(unittest.TestCase): @@ -1608,6 +1621,15 @@ class MySSLObject(ssl.SSLObject): obj = ctx.wrap_bio(ssl.MemoryBIO(), ssl.MemoryBIO()) self.assertIsInstance(obj, MySSLObject) + def test_copy_pickle(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + with self.assertRaises(TypeError): + copy.copy(ctx) + with self.assertRaises(TypeError): + copy.deepcopy(ctx) + with self.assertRaises(TypeError): + pickle.dumps(ctx) + class SSLErrorTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2018-03-13-09-48-02.bpo-33023.Zlszr2.rst b/Misc/NEWS.d/next/Library/2018-03-13-09-48-02.bpo-33023.Zlszr2.rst new file mode 100644 index 00000000000000..efa1c895a52c90 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-13-09-48-02.bpo-33023.Zlszr2.rst @@ -0,0 +1,3 @@ +Improve error message when trying to serialize SSLContext, SSLObject, and +SSLSocket objects. The classes can't be pickled or copied by the copy +module.