diff -r 0b2d4089180c Doc/library/ssl.rst --- a/Doc/library/ssl.rst Wed Apr 10 17:01:38 2013 -0400 +++ b/Doc/library/ssl.rst Thu Apr 11 18:52:51 2013 +0900 @@ -842,6 +842,7 @@ 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 ``None`` if the 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 -r 0b2d4089180c Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py Wed Apr 10 17:01:38 2013 -0400 +++ b/Lib/test/test_ssl.py Thu Apr 11 18:52:51 2013 +0900 @@ -2096,7 +2096,8 @@ 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 @@ # 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 -r 0b2d4089180c Modules/_ssl.c --- a/Modules/_ssl.c Wed Apr 10 17:01:38 2013 -0400 +++ b/Modules/_ssl.c Thu Apr 11 18:52:51 2013 +0900 @@ -2448,22 +2448,28 @@ 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);