From de24aad51ebf1c0b743a98977e313e5fe978723d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 22 Feb 2013 12:42:07 +0000 Subject: [PATCH] Fix hostname canonicalisation to stop breaking certifcate checks Commit b0b4b34f ('Canonicalise hostname during authentication if necessary') replaces the hostname with a bare IP address if necessary, so that reconnecting is guaranteed to get the *same* host from a round-robin and comparing the SSL cert with its previous SHA1 fingerprint (which is how we do it for two-stage connection for example from NetworkManager) is guaranteed to work. However, this breaks certificate auth when invoked in one-stage mode from the command line to authenticate *and* actually make the connection. When vpninfo->hostname is replaced with a bare IP address, that might not actually be what's listed in the certificate's Subject or Altname fields. So users have reported a certificate validation failure on *reconnecting* to the server which was acceptable the first time round when we looked it up by name. So, don't actually replace vpninfo->hostname at all. Introduce a new field vpninfo->unique_hostname which is returned by openconnect_get_hostname(), and leave vpninfo->hostname as it was. Signed-off-by: David Woodhouse --- http.c | 2 ++ library.c | 7 ++++++- main.c | 2 +- openconnect-internal.h | 1 + ssl.c | 4 ++-- www/changelog.xml | 1 + 6 files changed, 13 insertions(+), 4 deletions(-) diff --git a/http.c b/http.c index 9b77be58..9bdc9d9d 100644 --- a/http.c +++ b/http.c @@ -738,6 +738,8 @@ static int handle_redirect(struct openconnect_info *vpninfo) } if (strcasecmp(vpninfo->hostname, host) || port != vpninfo->port) { + free(vpninfo->unique_hostname); + vpninfo->unique_hostname = NULL; free(vpninfo->hostname); vpninfo->hostname = host; vpninfo->port = port; diff --git a/library.c b/library.c index 73e7c541..be4b119d 100644 --- a/library.c +++ b/library.c @@ -151,12 +151,15 @@ void openconnect_vpninfo_free (struct openconnect_info *vpninfo) char *openconnect_get_hostname (struct openconnect_info *vpninfo) { - return vpninfo->hostname; + return vpninfo->unique_hostname?:vpninfo->hostname; } void openconnect_set_hostname (struct openconnect_info *vpninfo, char *hostname) { + free(vpninfo->hostname); vpninfo->hostname = hostname; + free(vpninfo->unique_hostname); + vpninfo->unique_hostname = NULL; } char *openconnect_get_urlpath (struct openconnect_info *vpninfo) @@ -240,6 +243,8 @@ int openconnect_parse_url (struct openconnect_info *vpninfo, char *url) free(vpninfo->hostname); vpninfo->hostname = NULL; + free(vpninfo->unique_hostname); + vpninfo->unique_hostname = NULL; free(vpninfo->urlpath); vpninfo->urlpath = NULL; diff --git a/main.c b/main.c index 258932fb..d40207bb 100644 --- a/main.c +++ b/main.c @@ -809,7 +809,7 @@ int main(int argc, char **argv) if (cookieonly == 3) { /* --authenticate */ printf("COOKIE='%s'\n", vpninfo->cookie); - printf("HOST='%s'\n", vpninfo->hostname); + printf("HOST='%s'\n", openconnect_get_hostname(vpninfo)); if (vpninfo->peer_cert) { char buf[41] = {0, }; openconnect_get_cert_sha1(vpninfo, vpninfo->peer_cert, buf); diff --git a/openconnect-internal.h b/openconnect-internal.h index ff1b80bf..a35e798b 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -158,6 +158,7 @@ struct openconnect_info { const char *localname; char *hostname; + char *unique_hostname; int port; char *urlpath; int cert_expire_warning; diff --git a/ssl.c b/ssl.c index d6a551a4..4d00d19f 100644 --- a/ssl.c +++ b/ssl.c @@ -253,8 +253,8 @@ int connect_https_socket(struct openconnect_info *vpninfo) if (!vpninfo->proxy && (rp != result || rp->ai_next) && host[0]) { char *p = malloc(strlen(host) + 3); if (p) { - free(vpninfo->hostname); - vpninfo->hostname = p; + free(vpninfo->unique_hostname); + vpninfo->unique_hostname = p; if (rp->ai_family == AF_INET6) *p++ = '['; memcpy(p, host, strlen(host)); diff --git a/www/changelog.xml b/www/changelog.xml index e8f99019..be07c95c 100644 --- a/www/changelog.xml +++ b/www/changelog.xml @@ -21,6 +21,7 @@
  • Avoid using deprecated gnutls_pubkey_verify_data() function.
  • Fix compatibility issues with XML POST authentication.
  • Fix memory leaks on realloc() failure.
  • +
  • Fix certificate validation problem caused by hostname canonicalisation.

  • OpenConnect v4.99