Commit de24aad5 authored by David Woodhouse's avatar David Woodhouse

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: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 7ba530d8
......@@ -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;
......
......@@ -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;
......
......@@ -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>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment