]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Fix a crash when setting a servername callback on a SSL server socket and the client...
authorAntoine Pitrou <solipsis@pitrou.net>
Thu, 11 Apr 2013 18:48:42 +0000 (20:48 +0200)
committerAntoine Pitrou <solipsis@pitrou.net>
Thu, 11 Apr 2013 18:48:42 +0000 (20:48 +0200)
Patch by Kazuhiro Yoshida.
(originally issue #8109)

Doc/library/ssl.rst
Lib/test/test_ssl.py
Misc/ACKS
Modules/_ssl.c

index aa0b393a4fe1c9e06955c5bbc7b8e5305e2bb62a..9ddaf461e7200c405e509ebfd6bc57bcc770284e 100644 (file)
@@ -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.
 
index 408033e2420ab5739b80925f1f3671809567e94d..1f0f62ab80f4f8b94d52fb1e957224eee2627f0d 100644 (file)
@@ -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)
index 9a4cb521d3525910fe5113bc2769e589753979f1..b5084eedf47e499df851aa8e14b2c6edc0d01ff5 100644 (file)
--- 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
index 971dd05a0e7aeef4d8b44c8e402833bf92230a49..c6493ba833ff9bce3f6c55ec97fbf75e38177f12 100644 (file)
@@ -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);