diff --git a/main.c b/main.c index 4b02155..c613227 100644 --- a/main.c +++ b/main.c @@ -454,6 +454,7 @@ int main(int argc, char **argv) char *pidfile = NULL; FILE *fp = NULL; char *config_arg; + struct vpn_option *new_opt; #ifdef ENABLE_NLS bindtextdomain("openconnect", LOCALEDIR); @@ -525,7 +526,16 @@ int main(int argc, char **argv) pidfile = keep_config_arg(); break; case OPT_SERVERCERT: - vpninfo->servercert = keep_config_arg(); + new_opt = malloc (sizeof (*new_opt)); + if (!new_opt) { + fprintf(stderr, _("No memory for allocating server fingerprint\n")); + } else { + new_opt->option = NULL; + new_opt->value = keep_config_arg(); + new_opt->next = vpninfo->servercert; + + vpninfo->servercert = new_opt; + } break; case OPT_NO_DTLS: vpninfo->dtls_attempt_period = 0; diff --git a/openconnect-internal.h b/openconnect-internal.h index 2245e4a..d891af5 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -132,7 +132,7 @@ struct openconnect_info { int cert_type; char *cert_password; const char *cafile; - const char *servercert; + struct vpn_option *servercert; const char *xmlconfig; char xmlsha1[(SHA1_SIZE * 2) + 1]; char *username; diff --git a/openconnect.8 b/openconnect.8 index bb47b38..2042bd3 100644 --- a/openconnect.8 +++ b/openconnect.8 @@ -301,6 +301,8 @@ VPN connection after a temporary network down time of 300 seconds. .B \-\-servercert=SHA1 Accept server's SSL certificate only if its fingerprint matches .IR SHA1 . +This option may be used multiple times in order to allow +multiple certificates. .TP .B \-\-useragent=STRING Use diff --git a/openssl.c b/openssl.c index 9b617cf..4c7098b 100644 --- a/openssl.c +++ b/openssl.c @@ -572,17 +572,21 @@ static int check_server_cert(struct openconnect_info *vpninfo, X509 *cert) { char fingerprint[EVP_MAX_MD_SIZE * 2 + 1]; int ret; + struct vpn_option *opt; ret = openconnect_get_cert_sha1(vpninfo, cert, fingerprint); if (ret) return ret; - if (strcasecmp(vpninfo->servercert, fingerprint)) { - vpn_progress(vpninfo, PRG_ERR, - _("Server SSL certificate didn't match: %s\n"), fingerprint); - return -EINVAL; + for (opt=vpninfo->servercert ; opt ; opt=opt->next) + { + if (!strcasecmp(opt->value, fingerprint)) + return 0; } - return 0; + + vpn_progress(vpninfo, PRG_ERR, + _("Server SSL certificate didn't match: %s\n"), fingerprint); + return -EINVAL; } static int match_hostname_elem(const char *hostname, int helem_len,