diff -urp Python-2.6.1/Lib/ssl.py Python/Lib/ssl.py --- Lib/ssl.py 2008-09-29 11:56:38.000000000 -0700 +++ Lib/ssl.py 2009-03-31 22:55:22.000000000 -0700 @@ -87,6 +87,7 @@ class SSLSocket (socket): def __init__(self, sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version=PROTOCOL_SSLv23, ca_certs=None, + server_hostname=None, do_handshake_on_connect=True, suppress_ragged_eofs=True): socket.__init__(self, _sock=sock._sock) @@ -110,7 +111,8 @@ class SSLSocket (socket): # yes, create the SSL object self._sslobj = _ssl.sslwrap(self._sock, server_side, keyfile, certfile, - cert_reqs, ssl_version, ca_certs) + cert_reqs, ssl_version, ca_certs, + server_hostname) if do_handshake_on_connect: timeout = self.gettimeout() try: @@ -123,6 +125,7 @@ class SSLSocket (socket): self.cert_reqs = cert_reqs self.ssl_version = ssl_version self.ca_certs = ca_certs + self.server_hostname = server_hostname self.do_handshake_on_connect = do_handshake_on_connect self.suppress_ragged_eofs = suppress_ragged_eofs self._makefile_refs = 0 @@ -304,7 +307,7 @@ class SSLSocket (socket): socket.connect(self, addr) self._sslobj = _ssl.sslwrap(self._sock, False, self.keyfile, self.certfile, self.cert_reqs, self.ssl_version, - self.ca_certs) + self.ca_certs, self.server_hostname) if self.do_handshake_on_connect: self.do_handshake() @@ -322,6 +325,7 @@ class SSLSocket (socket): cert_reqs=self.cert_reqs, ssl_version=self.ssl_version, ca_certs=self.ca_certs, + server_hostname=None, do_handshake_on_connect=self.do_handshake_on_connect, suppress_ragged_eofs=self.suppress_ragged_eofs), addr) @@ -438,7 +442,7 @@ def sslwrap_simple (sock, keyfile=None, sock = sock._sock ssl_sock = _ssl.sslwrap(sock, 0, keyfile, certfile, CERT_NONE, - PROTOCOL_SSLv23, None) + PROTOCOL_SSLv23, None, None) try: sock.getpeername() except: diff -urp Python-2.6.1/Modules/_ssl.c Python/Modules/_ssl.c --- Modules/_ssl.c 2008-06-28 15:19:33.000000000 -0700 +++ Modules/_ssl.c 2009-03-31 22:58:39.000000000 -0700 @@ -261,7 +261,7 @@ newPySSLObject(PySocketSockObject *Sock, enum py_ssl_server_or_client socket_type, enum py_ssl_cert_requirements certreq, enum py_ssl_version proto_version, - char *cacerts_file) + char *cacerts_file, char *server_hostname) { PySSLObject *self; char *errstr = NULL; @@ -368,6 +368,13 @@ newPySSLObject(PySocketSockObject *Sock, PySSL_BEGIN_ALLOW_THREADS self->ssl = SSL_new(self->ctx); /* New ssl struct */ +#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) + /* If SNI isn't supported, we just don't call it and fail silently, + * as there's not much else we can do. + */ + if ((socket_type == PY_SSL_CLIENT) && server_hostname) + SSL_set_tlsext_host_name(self->ssl, server_hostname); +#endif PySSL_END_ALLOW_THREADS SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */ @@ -407,32 +414,34 @@ PySSL_sslwrap(PyObject *self, PyObject * char *key_file = NULL; char *cert_file = NULL; char *cacerts_file = NULL; + char *server_hostname = NULL; - if (!PyArg_ParseTuple(args, "O!i|zziiz:sslwrap", + if (!PyArg_ParseTuple(args, "O!i|zziizz:sslwrap", PySocketModule.Sock_Type, &Sock, &server_side, &key_file, &cert_file, &verification_mode, &protocol, - &cacerts_file)) + &cacerts_file, &server_hostname)) return NULL; /* fprintf(stderr, "server_side is %d, keyfile %p, certfile %p, verify_mode %d, " - "protocol %d, certs %p\n", + "protocol %d, certs %p, server_hostname %p\n", server_side, key_file, cert_file, verification_mode, - protocol, cacerts_file); + protocol, cacerts_file, server_hostname); */ return (PyObject *) newPySSLObject(Sock, key_file, cert_file, server_side, verification_mode, - protocol, cacerts_file); + protocol, cacerts_file, + server_hostname); } PyDoc_STRVAR(ssl_doc, "sslwrap(socket, server_side, [keyfile, certfile, certs_mode, protocol,\n" -" cacertsfile]) -> sslobject"); +" cacertsfile, server_hostname]) -> sslobject"); /* SSL object methods */