Skip to content

Commit 9bbf7a4

Browse files
committed
Make msg_callback a private debug function
The msg_callback and related enums are now private members. The feature is designed for internal debugging and not for end users. Signed-off-by: Christian Heimes <[email protected]>
1 parent 16fa504 commit 9bbf7a4

File tree

4 files changed

+109
-155
lines changed

4 files changed

+109
-155
lines changed

Doc/library/ssl.rst

Lines changed: 1 addition & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,27 +1064,6 @@ Constants
10641064

10651065
SSL 3.0 to TLS 1.3.
10661066

1067-
.. class:: TLSContentType
1068-
1069-
:class:`enum.IntEnum` collection of SSL and TLS content types from
1070-
:rfc:`8443`, section B.1.
1071-
1072-
.. versionadded:: 3.8
1073-
1074-
.. class:: TLSMessageType
1075-
1076-
:class:`enum.IntEnum` collection of SSL and TLS message types from
1077-
:rfc:`8443`, section B.3.
1078-
1079-
.. versionadded:: 3.8
1080-
1081-
.. class:: TLSAlertType
1082-
1083-
:class:`enum.IntEnum` collection of SSL and TLS alert types from
1084-
:rfc:`8443`, section B.2.
1085-
1086-
.. versionadded:: 3.8
1087-
10881067

10891068
SSL Sockets
10901069
-----------
@@ -1936,7 +1915,7 @@ to speed up repeated connections from the same clients.
19361915
Write TLS keys to a keylog file, whenever key material is generated or
19371916
received. The keylog file is designed for debugging purposes only. The
19381917
file format is specified by NSS and used by many traffic analyzers such
1939-
as Wireshark. The log file is opened in append-only mode. Writes a
1918+
as Wireshark. The log file is opened in append-only mode. Writes are
19401919
synchronized between threads, but not between processes.
19411920

19421921
.. versionadded:: 3.8
@@ -1980,78 +1959,6 @@ to speed up repeated connections from the same clients.
19801959

19811960
.. versionadded:: 3.7
19821961

1983-
.. attribute:: SSLContext.msg_callback
1984-
1985-
The message callback provides a debugging hook to analyze TLS connections.
1986-
The callback is called for any TLS protocol message (header, handshake,
1987-
alert, and more), but not for application data. Due to technical
1988-
limitations, the callback can't be used to filter traffic or to abort a
1989-
connection. Any exception raised in the callback is delayed until the
1990-
handshake, read, or write operation has been performed.
1991-
1992-
Example::
1993-
1994-
def msg_cb(conn, direction, version, content_type, msg_type, data):
1995-
print(f"{direction:5} {version._name_:7} {content_type._name_:18} "
1996-
f"{msg_type._name_:20} {len(data):4}")
1997-
1998-
ctx = ssl.create_default_context()
1999-
ctx.msg_callback = msg_cb
2000-
host = 'tls13.crypto.mozilla.org'
2001-
with ctx.wrap_socket(socket.socket(), server_hostname=host) as s:
2002-
s.connect((host, 443))
2003-
s.sendall(b'HEAD / HTTP/1.1\r\n')
2004-
s.sendall(b'Host: %s\r\n\r\n' % host)
2005-
s.recv(4096)
2006-
s.unwrap()
2007-
2008-
Output::
2009-
2010-
write TLSv1 HEADER HANDSHAKE 5
2011-
write TLSv1_3 HANDSHAKE CLIENT_HELLO 512
2012-
read TLSv1_2 HEADER HANDSHAKE 5
2013-
read TLSv1_3 HANDSHAKE SERVER_HELLO 122
2014-
read TLSv1_2 HEADER CHANGE_CIPHER_SPEC 5
2015-
read TLSv1_2 HEADER APPLICATION_DATA 5
2016-
read TLSv1_3 INNER_CONTENT_TYPE CERTIFICATE_STATUS 1
2017-
read TLSv1_3 HANDSHAKE ENCRYPTED_EXTENSIONS 6
2018-
read TLSv1_3 HANDSHAKE CERTIFICATE 3226
2019-
read TLSv1_3 HANDSHAKE CERTIFICATE_VERIFY 79
2020-
read TLSv1_3 HANDSHAKE FINISHED 52
2021-
write TLSv1_2 HEADER CHANGE_CIPHER_SPEC 5
2022-
write TLSv1_3 CHANGE_CIPHER_SPEC CHANGE_CIPHER_SPEC 1
2023-
write TLSv1_2 HEADER APPLICATION_DATA 5
2024-
write TLSv1_3 INNER_CONTENT_TYPE CERTIFICATE_STATUS 1
2025-
write TLSv1_3 HANDSHAKE FINISHED 52
2026-
write TLSv1_2 HEADER APPLICATION_DATA 5
2027-
write TLSv1_3 INNER_CONTENT_TYPE SUPPLEMENTAL_DATA 1
2028-
write TLSv1_2 HEADER APPLICATION_DATA 5
2029-
write TLSv1_3 INNER_CONTENT_TYPE SUPPLEMENTAL_DATA 1
2030-
read TLSv1_2 HEADER APPLICATION_DATA 5
2031-
read TLSv1_3 INNER_CONTENT_TYPE CERTIFICATE_STATUS 1
2032-
read TLSv1_3 HANDSHAKE NEWSESSION_TICKET 238
2033-
read TLSv1_3 HANDSHAKE NEWSESSION_TICKET 238
2034-
2035-
2036-
conn
2037-
:class:`SSLSocket` or :class:`SSLObject` instance
2038-
direction
2039-
``read`` or ``write``
2040-
version
2041-
:class:`TLSVersion` enum member or int for unknown version. For a
2042-
frame header, it's the header version.
2043-
content_type
2044-
:class:`TLSContentType` enum member or int for unsupported content type.
2045-
msg_type
2046-
Either a :class:`TLSContentType` enum number for a header message,
2047-
a :class:`TLSAlertType` enum member for an alert message,
2048-
a :class:`TLSMessageType` enum member for other messages, or int for
2049-
unsupported message types.
2050-
data
2051-
Raw, decrypted message content as bytes
2052-
2053-
.. versionadded:: 3.8
2054-
20551962
.. attribute:: SSLContext.options
20561963

20571964
An integer representing the set of SSL options enabled on this context.

Lib/ssl.py

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class TLSVersion(_IntEnum):
165165
MAXIMUM_SUPPORTED = _ssl.PROTO_MAXIMUM_SUPPORTED
166166

167167

168-
class TLSContentType(_IntEnum):
168+
class _TLSContentType(_IntEnum):
169169
"""Content types (record layer)
170170
171171
See RFC 8446, section B.1
@@ -179,7 +179,7 @@ class TLSContentType(_IntEnum):
179179
INNER_CONTENT_TYPE = 0x101
180180

181181

182-
class TLSAlertType(_IntEnum):
182+
class _TLSAlertType(_IntEnum):
183183
"""Alert types for TLSContentType.ALERT messages
184184
185185
See RFC 8466, section B.2
@@ -220,7 +220,7 @@ class TLSAlertType(_IntEnum):
220220
NO_APPLICATION_PROTOCOL = 120
221221

222222

223-
class TLSMessageType(_IntEnum):
223+
class _TLSMessageType(_IntEnum):
224224
"""Message types (handshake protocol)
225225
226226
See RFC 8446, section B.3
@@ -608,13 +608,48 @@ def hostname_checks_common_name(self):
608608
return True
609609

610610
@property
611-
def msg_callback(self):
612-
return super().msg_callback.user_function
611+
def _msg_callback(self):
612+
"""TLS message callback
613+
614+
The message callback provides a debugging hook to analyze TLS
615+
connections. The callback is called for any TLS protocol message
616+
(header, handshake, alert, and more), but not for application data.
617+
Due to technical limitations, the callback can't be used to filter
618+
traffic or to abort a connection. Any exception raised in the
619+
callback is delayed until the handshake, read, or write operation
620+
has been performed.
621+
622+
def msg_cb(conn, direction, version, content_type, msg_type, data):
623+
pass
624+
625+
conn
626+
:class:`SSLSocket` or :class:`SSLObject` instance
627+
direction
628+
``read`` or ``write``
629+
version
630+
:class:`TLSVersion` enum member or int for unknown version. For a
631+
frame header, it's the header version.
632+
content_type
633+
:class:`_TLSContentType` enum member or int for unsupported
634+
content type.
635+
msg_type
636+
Either a :class:`_TLSContentType` enum number for a header
637+
message, a :class:`_TLSAlertType` enum member for an alert
638+
message, a :class:`_TLSMessageType` enum member for other
639+
messages, or int for unsupported message types.
640+
data
641+
Raw, decrypted message content as bytes
642+
"""
643+
inner = super()._msg_callback
644+
if inner is not None:
645+
return inner.user_function
646+
else:
647+
return None
613648

614-
@msg_callback.setter
615-
def msg_callback(self, callback):
649+
@_msg_callback.setter
650+
def _msg_callback(self, callback):
616651
if callback is None:
617-
super(SSLContext, SSLContext).msg_callback.__set__(self, None)
652+
super(SSLContext, SSLContext)._msg_callback.__set__(self, None)
618653
return
619654

620655
if not hasattr(callback, '__call__'):
@@ -627,16 +662,16 @@ def inner(conn, direction, version, content_type, msg_type, data):
627662
pass
628663

629664
try:
630-
content_type = TLSContentType(content_type)
665+
content_type = _TLSContentType(content_type)
631666
except TypeError:
632667
pass
633668

634-
if content_type == TLSContentType.HEADER:
635-
msg_enum = TLSContentType
636-
elif content_type == TLSContentType.ALERT:
637-
msg_enum = TLSAlertType
669+
if content_type == _TLSContentType.HEADER:
670+
msg_enum = _TLSContentType
671+
elif content_type == _TLSContentType.ALERT:
672+
msg_enum = _TLSAlertType
638673
else:
639-
msg_enum = TLSMessageType
674+
msg_enum = _TLSMessageType
640675
try:
641676
msg_type = msg_enum(msg_type)
642677
except TypeError:
@@ -647,7 +682,7 @@ def inner(conn, direction, version, content_type, msg_type, data):
647682

648683
inner.user_function = callback
649684

650-
super(SSLContext, SSLContext).msg_callback.__set__(self, inner)
685+
super(SSLContext, SSLContext)._msg_callback.__set__(self, inner)
651686

652687
@property
653688
def protocol(self):

Lib/test/test_ssl.py

Lines changed: 56 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
ssl = support.import_module("ssl")
2828

29-
from ssl import TLSVersion, TLSContentType, TLSMessageType, TLSAlertType
29+
from ssl import TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType
3030

3131
PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
3232
HOST = support.HOST
@@ -4493,6 +4493,18 @@ def test_keylog_env(self):
44934493
ctx = ssl._create_stdlib_context()
44944494
self.assertEqual(ctx.keylog_filename, support.TESTFN)
44954495

4496+
def test_msg_callback(self):
4497+
client_context, server_context, hostname = testing_context()
4498+
4499+
def msg_cb(conn, direction, version, content_type, msg_type, data):
4500+
pass
4501+
4502+
self.assertIs(client_context._msg_callback, None)
4503+
client_context._msg_callback = msg_cb
4504+
self.assertIs(client_context._msg_callback, msg_cb)
4505+
with self.assertRaises(TypeError):
4506+
client_context._msg_callback = object()
4507+
44964508
def test_msg_callback_tls12(self):
44974509
client_context, server_context, hostname = testing_context()
44984510
client_context.options |= ssl.OP_NO_TLSv1_3
@@ -4505,7 +4517,7 @@ def msg_cb(conn, direction, version, content_type, msg_type, data):
45054517
self.assertIn(direction, {'read', 'write'})
45064518
msg.append((direction, version, content_type, msg_type))
45074519

4508-
client_context.msg_callback = msg_cb
4520+
client_context._msg_callback = msg_cb
45094521

45104522
server = ThreadedEchoServer(context=server_context, chatty=False)
45114523
with server:
@@ -4514,48 +4526,48 @@ def msg_cb(conn, direction, version, content_type, msg_type, data):
45144526
s.connect((HOST, server.port))
45154527

45164528
self.assertEqual(msg, [
4517-
("write", TLSVersion.TLSv1, TLSContentType.HEADER,
4518-
TLSMessageType.CERTIFICATE_STATUS),
4519-
("write", TLSVersion.TLSv1_2, TLSContentType.HANDSHAKE,
4520-
TLSMessageType.CLIENT_HELLO),
4521-
("read", TLSVersion.TLSv1_2, TLSContentType.HEADER,
4522-
TLSMessageType.CERTIFICATE_STATUS),
4523-
("read", TLSVersion.TLSv1_2, TLSContentType.HANDSHAKE,
4524-
TLSMessageType.SERVER_HELLO),
4525-
("read", TLSVersion.TLSv1_2, TLSContentType.HEADER,
4526-
TLSMessageType.CERTIFICATE_STATUS),
4527-
("read", TLSVersion.TLSv1_2, TLSContentType.HANDSHAKE,
4528-
TLSMessageType.CERTIFICATE),
4529-
("read", TLSVersion.TLSv1_2, TLSContentType.HEADER,
4530-
TLSMessageType.CERTIFICATE_STATUS),
4531-
("read", TLSVersion.TLSv1_2, TLSContentType.HANDSHAKE,
4532-
TLSMessageType.SERVER_KEY_EXCHANGE),
4533-
("read", TLSVersion.TLSv1_2, TLSContentType.HEADER,
4534-
TLSMessageType.CERTIFICATE_STATUS),
4535-
("read", TLSVersion.TLSv1_2, TLSContentType.HANDSHAKE,
4536-
TLSMessageType.SERVER_DONE),
4537-
("write", TLSVersion.TLSv1_2, TLSContentType.HEADER,
4538-
TLSMessageType.CERTIFICATE_STATUS),
4539-
("write", TLSVersion.TLSv1_2, TLSContentType.HANDSHAKE,
4540-
TLSMessageType.CLIENT_KEY_EXCHANGE),
4541-
("write", TLSVersion.TLSv1_2, TLSContentType.HEADER,
4542-
TLSMessageType.FINISHED),
4543-
("write", TLSVersion.TLSv1_2, TLSContentType.CHANGE_CIPHER_SPEC,
4544-
TLSMessageType.CHANGE_CIPHER_SPEC),
4545-
("write", TLSVersion.TLSv1_2, TLSContentType.HEADER,
4546-
TLSMessageType.CERTIFICATE_STATUS),
4547-
("write", TLSVersion.TLSv1_2, TLSContentType.HANDSHAKE,
4548-
TLSMessageType.FINISHED),
4549-
("read", TLSVersion.TLSv1_2, TLSContentType.HEADER,
4550-
TLSMessageType.CERTIFICATE_STATUS),
4551-
("read", TLSVersion.TLSv1_2, TLSContentType.HANDSHAKE,
4552-
TLSMessageType.NEWSESSION_TICKET),
4553-
("read", TLSVersion.TLSv1_2, TLSContentType.HEADER,
4554-
TLSMessageType.FINISHED),
4555-
("read", TLSVersion.TLSv1_2, TLSContentType.HEADER,
4556-
TLSMessageType.CERTIFICATE_STATUS),
4557-
("read", TLSVersion.TLSv1_2, TLSContentType.HANDSHAKE,
4558-
TLSMessageType.FINISHED),
4529+
("write", TLSVersion.TLSv1, _TLSContentType.HEADER,
4530+
_TLSMessageType.CERTIFICATE_STATUS),
4531+
("write", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE,
4532+
_TLSMessageType.CLIENT_HELLO),
4533+
("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER,
4534+
_TLSMessageType.CERTIFICATE_STATUS),
4535+
("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE,
4536+
_TLSMessageType.SERVER_HELLO),
4537+
("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER,
4538+
_TLSMessageType.CERTIFICATE_STATUS),
4539+
("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE,
4540+
_TLSMessageType.CERTIFICATE),
4541+
("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER,
4542+
_TLSMessageType.CERTIFICATE_STATUS),
4543+
("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE,
4544+
_TLSMessageType.SERVER_KEY_EXCHANGE),
4545+
("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER,
4546+
_TLSMessageType.CERTIFICATE_STATUS),
4547+
("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE,
4548+
_TLSMessageType.SERVER_DONE),
4549+
("write", TLSVersion.TLSv1_2, _TLSContentType.HEADER,
4550+
_TLSMessageType.CERTIFICATE_STATUS),
4551+
("write", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE,
4552+
_TLSMessageType.CLIENT_KEY_EXCHANGE),
4553+
("write", TLSVersion.TLSv1_2, _TLSContentType.HEADER,
4554+
_TLSMessageType.FINISHED),
4555+
("write", TLSVersion.TLSv1_2, _TLSContentType.CHANGE_CIPHER_SPEC,
4556+
_TLSMessageType.CHANGE_CIPHER_SPEC),
4557+
("write", TLSVersion.TLSv1_2, _TLSContentType.HEADER,
4558+
_TLSMessageType.CERTIFICATE_STATUS),
4559+
("write", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE,
4560+
_TLSMessageType.FINISHED),
4561+
("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER,
4562+
_TLSMessageType.CERTIFICATE_STATUS),
4563+
("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE,
4564+
_TLSMessageType.NEWSESSION_TICKET),
4565+
("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER,
4566+
_TLSMessageType.FINISHED),
4567+
("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER,
4568+
_TLSMessageType.CERTIFICATE_STATUS),
4569+
("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE,
4570+
_TLSMessageType.FINISHED),
45594571
])
45604572

45614573

Modules/_ssl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4650,8 +4650,8 @@ static PyGetSetDef context_getsetlist[] = {
46504650
{"keylog_filename", (getter) _PySSLContext_get_keylog_filename,
46514651
(setter) _PySSLContext_set_keylog_filename, NULL},
46524652
#endif
4653-
{"msg_callback", (getter) _PySSLContext_get_msg_callback,
4654-
(setter) _PySSLContext_set_msg_callback, NULL},
4653+
{"_msg_callback", (getter) _PySSLContext_get_msg_callback,
4654+
(setter) _PySSLContext_set_msg_callback, NULL},
46554655
{"sni_callback", (getter) get_sni_callback,
46564656
(setter) set_sni_callback, PySSLContext_sni_callback_doc},
46574657
{"options", (getter) get_options,

0 commit comments

Comments
 (0)