[Python-checkins] [2.7] bpo-32185: Don't send IP in SNI TLS extension (GH-5865) (#5871)

Christian Heimes webhook-mailer at python.org
Sun Feb 25 04:16:40 EST 2018


https://github.com/python/cpython/commit/a5c9112300ecd492ed6cc9759dc8028766401f61
commit: a5c9112300ecd492ed6cc9759dc8028766401f61
branch: 2.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Christian Heimes <christian at python.org>
date: 2018-02-25T10:16:37+01:00
summary:

[2.7] bpo-32185: Don't send IP in SNI TLS extension (GH-5865) (#5871)

The SSL module no longer sends IP addresses in SNI TLS extension on
platforms with OpenSSL 1.0.2+ or inet_pton.

Signed-off-by: Christian Heimes <christian at python.org>
(cherry picked from commit e9370a47389903bb72badc95032ec84a0ebbf8cc)

Co-authored-by: Christian Heimes <christian at python.org>

files:
A Misc/NEWS.d/next/Library/2017-12-20-09-25-10.bpo-32185.IL0cMt.rst
M Modules/_ssl.c

diff --git a/Misc/NEWS.d/next/Library/2017-12-20-09-25-10.bpo-32185.IL0cMt.rst b/Misc/NEWS.d/next/Library/2017-12-20-09-25-10.bpo-32185.IL0cMt.rst
new file mode 100644
index 000000000000..bfb2533b5dcf
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-12-20-09-25-10.bpo-32185.IL0cMt.rst
@@ -0,0 +1,2 @@
+The SSL module no longer sends IP addresses in SNI TLS extension on
+platforms with OpenSSL 1.0.2+ or inet_pton.
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index ec61a700b042..f09f9c9ea2f2 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -52,6 +52,11 @@
 #include <sys/poll.h>
 #endif
 
+#ifndef MS_WINDOWS
+/* inet_pton */
+#include <arpa/inet.h>
+#endif
+
 /* Don't warn about deprecated functions */
 #ifdef __GNUC__
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -575,8 +580,41 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
     SSL_set_mode(self->ssl, mode);
 
 #if HAVE_SNI
-    if (server_hostname != NULL)
-        SSL_set_tlsext_host_name(self->ssl, server_hostname);
+    if (server_hostname != NULL) {
+/* Don't send SNI for IP addresses. We cannot simply use inet_aton() and
+ * inet_pton() here. inet_aton() may be linked weakly and inet_pton() isn't
+ * available on all platforms. Use OpenSSL's IP address parser. It's
+ * available since 1.0.2 and LibreSSL since at least 2.3.0. */
+        int send_sni = 1;
+#if OPENSSL_VERSION_NUMBER >= 0x10200000L
+        ASN1_OCTET_STRING *ip = a2i_IPADDRESS(server_hostname);
+        if (ip == NULL) {
+            send_sni = 1;
+            ERR_clear_error();
+        } else {
+            send_sni = 0;
+            ASN1_OCTET_STRING_free(ip);
+        }
+#elif defined(HAVE_INET_PTON)
+#ifdef ENABLE_IPV6
+        char packed[Py_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))];
+#else
+        char packed[sizeof(struct in_addr)];
+#endif /* ENABLE_IPV6 */
+        if (inet_pton(AF_INET, server_hostname, packed)) {
+            send_sni = 0;
+#ifdef ENABLE_IPV6
+        } else if(inet_pton(AF_INET6, server_hostname, packed)) {
+            send_sni = 0;
+#endif /* ENABLE_IPV6 */
+        } else {
+            send_sni = 1;
+        }
+#endif /* HAVE_INET_PTON */
+        if (send_sni) {
+            SSL_set_tlsext_host_name(self->ssl, server_hostname);
+        }
+    }
 #endif
 
     /* If the socket is in non-blocking mode or timeout mode, set the BIO



More information about the Python-checkins mailing list