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 <David.Woodhouse@intel.com>
}
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;
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)
free(vpninfo->hostname);
vpninfo->hostname = NULL;
+ free(vpninfo->unique_hostname);
+ vpninfo->unique_hostname = NULL;
free(vpninfo->urlpath);
vpninfo->urlpath = NULL;
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);
const char *localname;
char *hostname;
+ char *unique_hostname;
int port;
char *urlpath;
int cert_expire_warning;
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));
<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>