diff -r 23f8a511050a Doc/library/ssl.rst --- a/Doc/library/ssl.rst Sat Nov 22 14:41:21 2014 -0800 +++ b/Doc/library/ssl.rst Sun Nov 23 17:39:01 2014 -0500 @@ -680,8 +680,7 @@ .. 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:: 3.2 @@ -1259,11 +1258,12 @@ 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.wrap_bio(incoming, outgoing, server_side=False, \ server_hostname=None) diff -r 23f8a511050a Lib/asyncio/selector_events.py --- a/Lib/asyncio/selector_events.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/asyncio/selector_events.py Sun Nov 23 17:39:01 2014 -0500 @@ -708,7 +708,7 @@ 'server_side': server_side, 'do_handshake_on_connect': False, } - if server_hostname and not server_side and ssl.HAS_SNI: + if server_hostname and not server_side: wrap_kwargs['server_hostname'] = server_hostname sslsock = sslcontext.wrap_socket(rawsock, **wrap_kwargs) diff -r 23f8a511050a Lib/ftplib.py --- a/Lib/ftplib.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/ftplib.py Sun Nov 23 17:39:01 2014 -0500 @@ -747,9 +747,8 @@ resp = self.voidcmd('AUTH TLS') else: resp = self.voidcmd('AUTH SSL') - server_hostname = self.host if ssl.HAS_SNI else None self.sock = self.context.wrap_socket(self.sock, - server_hostname=server_hostname) + server_hostname=self.host) self.file = self.sock.makefile(mode='r', encoding=self.encoding) return resp @@ -788,9 +787,8 @@ def ntransfercmd(self, cmd, rest=None): conn, size = FTP.ntransfercmd(self, cmd, rest) if self._prot_p: - server_hostname = self.host if ssl.HAS_SNI else None conn = self.context.wrap_socket(conn, - server_hostname=server_hostname) + server_hostname=self.host) return conn, size def abort(self): diff -r 23f8a511050a Lib/http/client.py --- a/Lib/http/client.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/http/client.py Sun Nov 23 17:39:01 2014 -0500 @@ -1288,10 +1288,9 @@ 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 -r 23f8a511050a Lib/imaplib.py --- a/Lib/imaplib.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/imaplib.py Sun Nov 23 17:39:01 2014 -0500 @@ -753,9 +753,8 @@ ssl_context = ssl._create_stdlib_context() typ, dat = self._simple_command(name) if typ == 'OK': - server_hostname = self.host if ssl.HAS_SNI else None self.sock = ssl_context.wrap_socket(self.sock, - server_hostname=server_hostname) + server_hostname=self.host) self.file = self.sock.makefile('rb') self._tls_established = True self._get_capabilities() @@ -1231,9 +1230,8 @@ def _create_socket(self): sock = IMAP4._create_socket(self) - server_hostname = self.host if ssl.HAS_SNI else None return self.ssl_context.wrap_socket(sock, - server_hostname=server_hostname) + server_hostname=self.host) def open(self, host='', port=IMAP4_SSL_PORT): """Setup connection to remote server on "host:port". diff -r 23f8a511050a Lib/nntplib.py --- a/Lib/nntplib.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/nntplib.py Sun Nov 23 17:39:01 2014 -0500 @@ -289,8 +289,7 @@ # Generate a default SSL context if none was passed. if context is None: context = ssl._create_stdlib_context() - server_hostname = hostname if ssl.HAS_SNI else None - return context.wrap_socket(sock, server_hostname=server_hostname) + return context.wrap_socket(sock, server_hostname=hostname) # The classes themselves diff -r 23f8a511050a Lib/poplib.py --- a/Lib/poplib.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/poplib.py Sun Nov 23 17:39:01 2014 -0500 @@ -387,9 +387,8 @@ if context is None: context = ssl._create_stdlib_context() resp = self._shortcmd('STLS') - server_hostname = self.host if ssl.HAS_SNI else None self.sock = context.wrap_socket(self.sock, - server_hostname=server_hostname) + server_hostname=self.host) self.file = self.sock.makefile('rb') self._tls_established = True return resp @@ -430,9 +429,8 @@ def _create_socket(self, timeout): sock = POP3._create_socket(self, timeout) - server_hostname = self.host if ssl.HAS_SNI else None sock = self.context.wrap_socket(sock, - server_hostname=server_hostname) + server_hostname=self.host) return sock def stls(self, keyfile=None, certfile=None, context=None): diff -r 23f8a511050a Lib/smtplib.py --- a/Lib/smtplib.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/smtplib.py Sun Nov 23 17:39:01 2014 -0500 @@ -709,9 +709,8 @@ if context is None: context = ssl._create_stdlib_context(certfile=certfile, keyfile=keyfile) - server_hostname = self._host if ssl.HAS_SNI else None self.sock = context.wrap_socket(self.sock, - server_hostname=server_hostname) + server_hostname=self._host) self.file = None # RFC 3207: # The client MUST discard any knowledge obtained from @@ -940,9 +939,8 @@ print('connect:', (host, port), file=stderr) new_socket = socket.create_connection((host, port), timeout, self.source_address) - server_hostname = self._host if ssl.HAS_SNI else None new_socket = self.context.wrap_socket(new_socket, - server_hostname=server_hostname) + server_hostname=self._host) return new_socket __all__.append("SMTP_SSL") diff -r 23f8a511050a Lib/ssl.py --- a/Lib/ssl.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/ssl.py Sun Nov 23 17:39:01 2014 -0500 @@ -655,12 +655,7 @@ 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 -r 23f8a511050a Lib/test/test_asyncio/test_events.py --- a/Lib/test/test_asyncio/test_events.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/test/test_asyncio/test_events.py Sun Nov 23 17:39:01 2014 -0500 @@ -12,9 +12,6 @@ import ssl except ImportError: ssl = None - HAS_SNI = False -else: - from ssl import HAS_SNI import subprocess import sys import threading @@ -857,7 +854,6 @@ server.close() @unittest.skipIf(ssl is None, 'No ssl module') - @unittest.skipUnless(HAS_SNI, 'No SNI support in ssl module') def test_create_server_ssl_verify_failed(self): proto = MyProto(loop=self.loop) server, host, port = self._make_ssl_server( @@ -882,7 +878,6 @@ server.close() @unittest.skipIf(ssl is None, 'No ssl module') - @unittest.skipUnless(HAS_SNI, 'No SNI support in ssl module') @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') def test_create_unix_server_ssl_verify_failed(self): proto = MyProto(loop=self.loop) @@ -909,7 +904,6 @@ server.close() @unittest.skipIf(ssl is None, 'No ssl module') - @unittest.skipUnless(HAS_SNI, 'No SNI support in ssl module') def test_create_server_ssl_match_failed(self): proto = MyProto(loop=self.loop) server, host, port = self._make_ssl_server( @@ -937,7 +931,6 @@ server.close() @unittest.skipIf(ssl is None, 'No ssl module') - @unittest.skipUnless(HAS_SNI, 'No SNI support in ssl module') @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') def test_create_unix_server_ssl_verified(self): proto = MyProto(loop=self.loop) @@ -963,7 +956,6 @@ server.close() @unittest.skipIf(ssl is None, 'No ssl module') - @unittest.skipUnless(HAS_SNI, 'No SNI support in ssl module') def test_create_server_ssl_verified(self): proto = MyProto(loop=self.loop) server, host, port = self._make_ssl_server( diff -r 23f8a511050a Lib/test/test_asyncio/test_selector_events.py --- a/Lib/test/test_asyncio/test_selector_events.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/test/test_asyncio/test_selector_events.py Sun Nov 23 17:39:01 2014 -0500 @@ -1408,7 +1408,7 @@ self.assertEqual(tr._conn_lost, 1) self.assertEqual(1, self.loop.remove_reader_count[1]) - @unittest.skipIf(ssl is None or not ssl.HAS_SNI, 'No SNI support') + @unittest.skipIf(ssl is None, 'No SSL support') def test_server_hostname(self): _SelectorSslTransport( self.loop, self.sock, self.protocol, self.sslcontext, diff -r 23f8a511050a Lib/test/test_ftplib.py --- a/Lib/test/test_ftplib.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/test/test_ftplib.py Sun Nov 23 17:39:01 2014 -0500 @@ -15,9 +15,6 @@ import ssl except ImportError: ssl = None - HAS_SNI = False -else: - from ssl import HAS_SNI from unittest import TestCase, skipUnless from test import support @@ -927,7 +924,6 @@ self.client.ccc() self.assertRaises(ValueError, self.client.sock.unwrap) - @skipUnless(HAS_SNI, 'No SNI support in ssl module') def test_check_hostname(self): self.client.quit() ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) diff -r 23f8a511050a Lib/test/test_imaplib.py --- a/Lib/test/test_imaplib.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/test/test_imaplib.py Sun Nov 23 17:39:01 2014 -0500 @@ -19,9 +19,6 @@ import ssl except ImportError: ssl = None - HAS_SNI = False -else: - from ssl import HAS_SNI CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert3.pem") CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "pycacert.pem") @@ -387,7 +384,6 @@ imap_class = IMAP4_SSL @reap_threads - @unittest.skipUnless(HAS_SNI, 'No SNI support in ssl module') def test_ssl_verified(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_context.verify_mode = ssl.CERT_REQUIRED diff -r 23f8a511050a Lib/test/test_poplib.py --- a/Lib/test/test_poplib.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/test/test_poplib.py Sun Nov 23 17:39:01 2014 -0500 @@ -21,13 +21,10 @@ SUPPORTS_SSL = False if hasattr(poplib, 'POP3_SSL'): import ssl - from ssl import HAS_SNI SUPPORTS_SSL = True CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert3.pem") CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "pycacert.pem") -else: - HAS_SNI = False requires_ssl = skipUnless(SUPPORTS_SSL, 'SSL not supported') @@ -334,7 +331,6 @@ self.assertEqual(resp, expected) @requires_ssl - @skipUnless(HAS_SNI, 'No SNI support in ssl module') def test_stls_context(self): expected = b'+OK Begin TLS negotiation' ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) diff -r 23f8a511050a Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py Sat Nov 22 14:41:21 2014 -0800 +++ b/Lib/test/test_ssl.py Sun Nov 23 17:39:01 2014 -0500 @@ -1428,11 +1428,8 @@ # 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)) @@ -1696,12 +1693,8 @@ ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ctx.verify_mode = ssl.CERT_REQUIRED ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT) - if ssl.HAS_SNI: - ctx.check_hostname = True - sslobj = ctx.wrap_bio(incoming, outgoing, False, 'svn.python.org') - else: - ctx.check_hostname = False - sslobj = ctx.wrap_bio(incoming, outgoing, False) + ctx.check_hostname = True + sslobj = ctx.wrap_bio(incoming, outgoing, False, 'svn.python.org') self.assertIs(sslobj._sslobj.owner, sslobj) self.assertIsNone(sslobj.cipher()) self.assertRaises(ValueError, sslobj.getpeercert) @@ -2283,7 +2276,6 @@ 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 -r 23f8a511050a Modules/_ssl.c --- a/Modules/_ssl.c Sat Nov 22 14:41:21 2014 -0800 +++ b/Modules/_ssl.c Sun Nov 23 17:39:01 2014 -0500 @@ -1542,7 +1542,7 @@ } PyDoc_STRVAR(PySSL_get_server_hostname_doc, -"The currently set server hostname (for SNI)."); +"The currently set server hostname."); static PyObject * PySSL_get_owner(PySSLSocket *self, void *c) @@ -2922,12 +2922,6 @@ &sock, &server_side, "idna", &hostname)) 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, hostname, @@ -2955,14 +2949,8 @@ &server_side, &hostname_obj)) return NULL; if (hostname_obj != Py_None) { -#if HAVE_SNI if (!PyArg_Parse(hostname_obj, "et", "idna", &hostname)) return NULL; -#else - PyErr_SetString(PyExc_ValueError, "server_hostname is not supported " - "by your OpenSSL library"); - return NULL; -#endif } res = (PyObject *) newPySSLSocket(self, NULL, server_side, hostname,