Skip to content
Permalink
Browse files
Fix hostname canonicalisation to stop breaking certifcate checks
Commit b0b4b34 ('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 <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Feb 22, 2013
1 parent 7ba530d commit de24aad51ebf1c0b743a98977e313e5fe978723d
Showing with 13 additions and 4 deletions.
  1. +2 −0 http.c
  2. +6 −1 library.c
  3. +1 −1 main.c
  4. +1 −0 openconnect-internal.h
  5. +2 −2 ssl.c
  6. +1 −0 www/changelog.xml
2 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;
@@ -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;

2 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);
@@ -158,6 +158,7 @@ struct openconnect_info {

const char *localname;
char *hostname;
char *unique_hostname;
int port;
char *urlpath;
int cert_expire_warning;
4 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));
@@ -21,6 +21,7 @@
<li>Avoid using deprecated <tt>gnutls_pubkey_verify_data()</tt> function.</li>
<li>Fix compatibility issues with XML POST authentication.</li>
<li>Fix memory leaks on <tt>realloc()</tt> failure.</li>
<li>Fix certificate validation problem caused by hostname canonicalisation.</li>
</ul><br/>
</li>
<li><b><a href="ftp://ftp.infradead.org/pub/openconnect/openconnect-4.99.tar.gz">OpenConnect v4.99</a></b>

0 comments on commit de24aad

Please sign in to comment.