From 405189f2a794ded622a4ae3a83a9b70917faf894 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 30 Jun 2017 13:10:03 +0200 Subject: don't set ip addresses as server names for SNI It is kinda unlikely that apt will ever encounter a certificate for an IP and a user actually using it, but the API documentation for gnutls_server_name_set explicitly says that "IPv4 or IPv6 addresses are not permitted to be set by this function.", so we should follow it. [jak@d.o: Slightly rebased] --- methods/connect.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'methods') diff --git a/methods/connect.cc b/methods/connect.cc index ce97fd97c..182af48ae 100644 --- a/methods/connect.cc +++ b/methods/connect.cc @@ -739,8 +739,18 @@ bool UnwrapTLS(std::string Host, std::unique_ptr &Fd, { gnutls_session_set_verify_cert(tlsFd->session, Owner->ConfigFindB("Verify-Host", true) ? tlsFd->hostname.c_str() : nullptr, 0); } - if ((err = gnutls_server_name_set(tlsFd->session, GNUTLS_NAME_DNS, tlsFd->hostname.c_str(), tlsFd->hostname.length())) < 0) - return _error->Error("Could not set host name %s to indicate to server: %s", tlsFd->hostname.c_str(), gnutls_strerror(err)); + + // set SNI only if the hostname is really a name and not an address + { + struct in_addr addr4; + struct in6_addr addr6; + + if (inet_pton(AF_INET, tlsFd->hostname.c_str(), &addr4) == 1 || + inet_pton(AF_INET6, tlsFd->hostname.c_str(), &addr6) == 1) + /* not a host name */; + else if ((err = gnutls_server_name_set(tlsFd->session, GNUTLS_NAME_DNS, tlsFd->hostname.c_str(), tlsFd->hostname.length())) < 0) + return _error->Error("Could not set host name %s to indicate to server: %s", tlsFd->hostname.c_str(), gnutls_strerror(err)); + } // Set the FD now, so closing it works reliably. tlsFd->UnderlyingFd = std::move(Fd); -- cgit v1.2.3