http://bugs.gentoo.org/301312 http://savannah.gnu.org/bugs/index.php?26786 http://lists.gnu.org/archive/html/bug-wget/2009-03/msg00033.html --- src/gnutls.c +++ src/gnutls.c @@ -45,6 +45,7 @@ as that of the covered work. */ #include "connect.h" #include "url.h" #include "ssl.h" +#include "host.h" /* Note: some of the functions private to this file have names that begin with "wgnutls_" (e.g. wgnutls_read) so that they wouldn't be @@ -181,7 +182,7 @@ static struct transport_implementation w }; bool -ssl_connect (int fd) +ssl_connect (int fd, const char *hostname) { static const int cert_type_priority[] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 @@ -189,8 +190,17 @@ ssl_connect (int fd) struct wgnutls_transport_context *ctx; gnutls_session session; int err; + gnutls_init (&session, GNUTLS_CLIENT); gnutls_set_default_priority (session); + + /* We set the server name but only if it's not an IP address. */ + if (!is_ip_address(hostname)) + { + gnutls_server_name_set (session, GNUTLS_NAME_DNS, + hostname, strlen(hostname)); + } + gnutls_certificate_type_set_priority (session, cert_type_priority); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, credentials); gnutls_transport_set_ptr (session, (gnutls_transport_ptr) fd); --- src/host.c +++ src/host.c @@ -904,3 +904,19 @@ host_cleanup (void) host_name_addresses_map = NULL; } } + +/* Determine whether or not a hostname is an IP address that we recognise. */ +bool +is_ip_address (const char *name) +{ + const char *endp; + + endp = name + strlen(name); + if (is_valid_ipv4_address(name, endp)) + return true; +#ifdef ENABLE_IPV6 + if (is_valid_ipv4_address(name, endp)) + return true; +#endif + return false; +} --- src/host.h +++ src/host.h @@ -102,4 +102,6 @@ bool sufmatch (const char **, const char void host_cleanup (void); +bool is_ip_address(const char *); + #endif /* HOST_H */ --- src/http.c +++ src/http.c @@ -1762,7 +1762,7 @@ gethttp (struct url *u, struct http_stat if (conn->scheme == SCHEME_HTTPS) { - if (!ssl_connect_wget (sock)) + if (!ssl_connect_wget (sock, u->host)) { fd_close (sock); return CONSSLERR; --- src/openssl.c +++ src/openssl.c @@ -47,6 +47,7 @@ as that of the covered work. */ #include "connect.h" #include "url.h" #include "ssl.h" +#include "host.h" /* Application-wide SSL context. This is common to all SSL connections. */ @@ -390,7 +391,7 @@ static struct transport_implementation o Returns true on success, false on failure. */ bool -ssl_connect_wget (int fd) +ssl_connect_wget (int fd, const char *hostname) { SSL *conn; struct openssl_transport_context *ctx; @@ -401,6 +402,19 @@ ssl_connect (int fd) conn = SSL_new (ssl_ctx); if (!conn) goto error; + +#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) + /* If the SSL library was build with support for ServerNameIndication + then use it whenever we have a hostname. If not, don't, ever. */ + if (!is_ip_address(hostname)) + { + if (!SSL_set_tlsext_host_name(conn, hostname)) { + DEBUGP (("Failed to set TLS server-name indication.")); + goto error; + } + } +#endif + if (!SSL_set_fd (conn, fd)) goto error; SSL_set_connect_state (conn); --- src/ssl.h +++ src/ssl.h @@ -33,7 +33,7 @@ as that of the covered work. */ #define GEN_SSLFUNC_H bool ssl_init (void); -bool ssl_connect_wget (int); +bool ssl_connect_wget (int, const char *); bool ssl_check_certificate (int, const char *); #endif /* GEN_SSLFUNC_H */