From 9f59e4723e1ab0b1e147e38f95525ee795e315df Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 30 Sep 2008 05:01:17 +0100 Subject: [PATCH] Add server cert verification --- anyconnect.h | 1 + main.c | 9 +++++++-- ssl.c | 20 ++++++++++++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/anyconnect.h b/anyconnect.h index 6f7c3f7..4a48fbd 100644 --- a/anyconnect.h +++ b/anyconnect.h @@ -42,6 +42,7 @@ struct anyconnect_info { const char *cert; const char *tpmkey; char *tpmpass; + const char *cafile; const char *cookie; struct vpn_option *cstp_options; diff --git a/main.c b/main.c index 192b68f..862ac46 100644 --- a/main.c +++ b/main.c @@ -50,16 +50,17 @@ static struct option long_options[] = { {"tpm-password", 1, 0, 'p'}, {"useragent", 1, 0, 'u'}, {"verbose", 1, 0, 'v'}, + {"cafile", 1, 0, '0'}, }; void usage(void) { printf("Usage: anyconnect [options] \n"); printf("Connect to Cisco AnyConnect server.\n\n"); - printf(" -C, --cookie=COOKIE Use WebVPN cookie COOKIE\n"); - printf(" -D, --no-deflate Disable compression\n"); printf(" -c, --certificate=CERT Use SSL client certificate CERT\n"); + printf(" -C, --cookie=COOKIE Use WebVPN cookie COOKIE\n"); printf(" -d, --deflate Enable compression (default)\n"); + printf(" -D, --no-deflate Disable compression\n"); printf(" -h, --help Display help text\n"); printf(" -i, --interface=IFNAME Use IFNAME for tunnel interface\n"); printf(" -m, --mtu=MTU Request MTU from server\n"); @@ -68,6 +69,7 @@ void usage(void) printf(" -t, --tpm-key=KEY Use KEY as private key, with TPM\n"); printf(" -u, --useragent=AGENT Set HTTP User-Agent AGENT\n"); printf(" -v, --verbose More output\n"); + printf(" --cafile=FILE Cert file for server verification\n"); exit(1); } @@ -106,6 +108,9 @@ int main(int argc, char **argv) break; switch (opt) { + case '0': + vpninfo->cafile = optarg; + break; case 'C': vpninfo->cookie = optarg; break; diff --git a/ssl.c b/ssl.c index 6515db0..752c4fb 100644 --- a/ssl.c +++ b/ssl.c @@ -245,9 +245,11 @@ static int open_https(struct anyconnect_info *vpninfo) if (vpninfo->cert) load_certificate(vpninfo, https_ctx); - + if (vpninfo->cafile) + SSL_CTX_load_verify_locations(https_ctx, vpninfo->cafile, NULL); + https_ssl = SSL_new(https_ctx); - + https_bio = BIO_new_socket(ssl_sock, BIO_NOCLOSE); SSL_set_bio(https_ssl, https_bio, https_bio); @@ -256,9 +258,23 @@ static int open_https(struct anyconnect_info *vpninfo) ERR_print_errors_fp(stderr); SSL_free(https_ssl); SSL_CTX_free(https_ctx); + close(ssl_sock); return -EINVAL; } + if (vpninfo->cafile) { + int vfy = SSL_get_verify_result(https_ssl); + + /* FIXME: Show cert details, allow user to accept (and store?) */ + if (vfy != X509_V_OK) { + fprintf(stderr, "Server certificate verify failed: %d\n", vfy); + SSL_free(https_ssl); + SSL_CTX_free(https_ctx); + close(ssl_sock); + return -EINVAL; + } + } + vpninfo->ssl_fd = ssl_sock; vpninfo->https_ssl = https_ssl; -- 2.7.4