summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2014-11-23 20:13:31 -0600
committerBenjamin Peterson <benjamin@python.org>2014-11-23 20:13:31 -0600
commit4d14fa1870841a36b2effab760bbaa52ac072d2a (patch)
tree98c30ef6594af693d4fe7bac3e46421e07989ebb
parentd743aa6022082616462064b56606a282afe0efb6 (diff)
downloadcpython-4d14fa1870841a36b2effab760bbaa52ac072d2a.tar.gz
allow hostname to be passed to SSLContext even if OpenSSL doesn't support SNI (closes #22921)
Patch from Donald Stufft.
-rw-r--r--Doc/library/ssl.rst14
-rw-r--r--Lib/httplib.py3
-rw-r--r--Lib/ssl.py7
-rw-r--r--Lib/test/test_ssl.py8
-rw-r--r--Modules/_ssl.c6
5 files changed, 11 insertions, 27 deletions
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index c52b073ff7..0674cdfc56 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -645,8 +645,7 @@ Constants
.. data:: HAS_SNI
Whether the OpenSSL library has built-in support for the *Server Name
- Indication* extension (as defined in :rfc:`4366`). When true, you can
- use the *server_hostname* argument to :meth:`SSLContext.wrap_socket`.
+ Indication* extension (as defined in :rfc:`4366`).
.. versionadded:: 2.7.9
@@ -1136,11 +1135,12 @@ to speed up repeated connections from the same clients.
On client connections, the optional parameter *server_hostname* specifies
the hostname of the service which we are connecting to. This allows a
single server to host multiple SSL-based services with distinct certificates,
- quite similarly to HTTP virtual hosts. Specifying *server_hostname*
- will raise a :exc:`ValueError` if the OpenSSL library doesn't have support
- for it (that is, if :data:`HAS_SNI` is :const:`False`). Specifying
- *server_hostname* will also raise a :exc:`ValueError` if *server_side*
- is true.
+ quite similarly to HTTP virtual hosts. Specifying *server_hostname* will
+ raise a :exc:`ValueError` if *server_side* is true.
+
+ .. versionchanged:: 3.5
+ Always allow a server_hostname to be passed, even if OpenSSL does not
+ have SNI.
.. method:: SSLContext.session_stats()
diff --git a/Lib/httplib.py b/Lib/httplib.py
index db5fa373a7..6d2e38d83c 100644
--- a/Lib/httplib.py
+++ b/Lib/httplib.py
@@ -1214,10 +1214,9 @@ else:
server_hostname = self._tunnel_host
else:
server_hostname = self.host
- sni_hostname = server_hostname if ssl.HAS_SNI else None
self.sock = self._context.wrap_socket(self.sock,
- server_hostname=sni_hostname)
+ server_hostname=server_hostname)
if not self._context.check_hostname and self._check_hostname:
try:
ssl.match_hostname(self.sock.getpeercert(), server_hostname)
diff --git a/Lib/ssl.py b/Lib/ssl.py
index 4b682848e7..c9f25c0bf0 100644
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -527,12 +527,7 @@ class SSLSocket(socket):
raise ValueError("server_hostname can only be specified "
"in client mode")
if self._context.check_hostname and not server_hostname:
- if HAS_SNI:
- raise ValueError("check_hostname requires server_hostname")
- else:
- raise ValueError("check_hostname requires server_hostname, "
- "but it's not supported by your OpenSSL "
- "library")
+ raise ValueError("check_hostname requires server_hostname")
self.server_side = server_side
self.server_hostname = server_hostname
self.do_handshake_on_connect = do_handshake_on_connect
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 39aa17c09f..b023fbc8a8 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -1323,11 +1323,8 @@ class NetworkedTests(unittest.TestCase):
# Same with a server hostname
s = ctx.wrap_socket(socket.socket(socket.AF_INET),
server_hostname="svn.python.org")
- if ssl.HAS_SNI:
- s.connect(("svn.python.org", 443))
- s.close()
- else:
- self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
+ s.connect(("svn.python.org", 443))
+ s.close()
# This should fail because we have no verification certs
ctx.verify_mode = ssl.CERT_REQUIRED
s = ctx.wrap_socket(socket.socket(socket.AF_INET))
@@ -2089,7 +2086,6 @@ else:
cert = s.getpeercert()
self.assertTrue(cert, "Can't get peer certificate.")
- @needs_sni
def test_check_hostname(self):
if support.verbose:
sys.stdout.write("\n")
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 1638ebe3b6..8ee8c3d149 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -2824,12 +2824,6 @@ context_wrap_socket(PySSLContext *self, PyObject *args, PyObject *kwds)
&sock, &server_side,
"idna", &hostname, &ssl_sock))
return NULL;
-#if !HAVE_SNI
- PyMem_Free(hostname);
- PyErr_SetString(PyExc_ValueError, "server_hostname is not supported "
- "by your OpenSSL library");
- return NULL;
-#endif
}
res = (PyObject *) newPySSLSocket(self, sock, server_side,