From 50b24d0d7cc7b787acc1f8481173e5e0d536fe28 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 11 Apr 2013 20:48:42 +0200 Subject: Fix a crash when setting a servername callback on a SSL server socket and the client doesn't send a server name. Patch by Kazuhiro Yoshida. (originally issue #8109) --- Doc/library/ssl.rst | 1 + Lib/test/test_ssl.py | 11 ++++++++++- Misc/ACKS | 1 + Modules/_ssl.c | 30 ++++++++++++++++++------------ 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index aa0b393..9ddaf46 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -842,6 +842,7 @@ to speed up repeated connections from the same clients. The callback function, *server_name_callback*, will be called with three arguments; the first being the :class:`ssl.SSLSocket`, the second is a string that represents the server name that the client is intending to communicate + (or :const:`None` if the TLS Client Hello does not contain a server name) and the third argument is the original :class:`SSLContext`. The server name argument is the IDNA decoded server name. diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 408033e..1f0f62a 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2096,7 +2096,8 @@ else: def servername_cb(ssl_sock, server_name, initial_context): calls.append((server_name, initial_context)) - ssl_sock.context = other_context + if server_name is not None: + ssl_sock.context = other_context server_context.set_servername_callback(servername_cb) stats = server_params_test(client_context, server_context, @@ -2108,6 +2109,14 @@ else: # CERTFILE4 was selected self.check_common_name(stats, 'fakehostname') + calls = [] + # The callback is called with server_name=None + stats = server_params_test(client_context, server_context, + chatty=True, + sni_name=None) + self.assertEqual(calls, [(None, server_context)]) + self.check_common_name(stats, 'localhost') + # Check disabling the callback calls = [] server_context.set_servername_callback(None) diff --git a/Misc/ACKS b/Misc/ACKS index 9a4cb52..b5084ee 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1361,6 +1361,7 @@ Bob Yodlowski Danny Yoo Rory Yorke George Yoshida +Kazuhiro Yoshida Masazumi Yoshikawa Arnaud Ysmal Bernard Yue diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 971dd05..c6493ba 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2448,22 +2448,28 @@ _servername_callback(SSL *s, int *al, void *args) goto error; } - servername_o = PyBytes_FromString(servername); - if (servername_o == NULL) { - PyErr_WriteUnraisable((PyObject *) ssl_ctx); - goto error; + if (servername == NULL) { + result = PyObject_CallFunctionObjArgs(ssl_ctx->set_hostname, ssl_socket, + Py_None, ssl_ctx, NULL); } - servername_idna = PyUnicode_FromEncodedObject(servername_o, "idna", NULL); - if (servername_idna == NULL) { - PyErr_WriteUnraisable(servername_o); + else { + servername_o = PyBytes_FromString(servername); + if (servername_o == NULL) { + PyErr_WriteUnraisable((PyObject *) ssl_ctx); + goto error; + } + servername_idna = PyUnicode_FromEncodedObject(servername_o, "idna", NULL); + if (servername_idna == NULL) { + PyErr_WriteUnraisable(servername_o); + Py_DECREF(servername_o); + goto error; + } Py_DECREF(servername_o); - goto error; + result = PyObject_CallFunctionObjArgs(ssl_ctx->set_hostname, ssl_socket, + servername_idna, ssl_ctx, NULL); + Py_DECREF(servername_idna); } - Py_DECREF(servername_o); - result = PyObject_CallFunctionObjArgs(ssl_ctx->set_hostname, ssl_socket, - servername_idna, ssl_ctx, NULL); Py_DECREF(ssl_socket); - Py_DECREF(servername_idna); if (result == NULL) { PyErr_WriteUnraisable(ssl_ctx->set_hostname); -- cgit v0.12