diff options
author | David Kalnischkies <david@kalnischkies.de> | 2017-06-30 13:10:03 +0200 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2017-07-03 15:06:26 +0200 |
commit | 405189f2a794ded622a4ae3a83a9b70917faf894 (patch) | |
tree | b013a4ba34c7c1239ab602eee9f2120b4ba852f7 | |
parent | f3b9e58cc5e6878daff9cf127bd00587d1f715d3 (diff) |
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]
-rw-r--r-- | methods/connect.cc | 14 |
1 files changed, 12 insertions, 2 deletions
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<MethodFd> &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); |