| 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_ipv6_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 */ |