From 423eee0b51a204562d6f2ec67893133ebcf200d6 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 27 Jun 2011 01:45:49 +0100 Subject: [PATCH] Add openconnect_vpninfo_new_with_cbdata() function to ease C++ integration C++ callers really want the 'self' object pointer to be the first argument of the callbacks. Give them the chance to get that, instead of the vpninfo pointer. Preserve the old openconnect_vpninfo_new() call, even with the same prototype for the callback functions, for compatibility with the existing GNOME auth-dialog. Signed-off-by: David Woodhouse --- auth.c | 36 +++++++------- cstp.c | 88 ++++++++++++++++----------------- dtls.c | 58 +++++++++++----------- http.c | 106 ++++++++++++++++++++-------------------- library.c | 25 ++++++++-- main.c | 30 +++++++----- mainloop.c | 4 +- openconnect-internal.h | 13 ++--- openconnect.h | 38 ++++++++++++--- ssl.c | 107 +++++++++++++++++++++-------------------- tun.c | 16 +++--- xml.c | 2 +- 12 files changed, 285 insertions(+), 238 deletions(-) diff --git a/auth.c b/auth.c index f2de327e..5fbdda49 100644 --- a/auth.c +++ b/auth.c @@ -121,7 +121,7 @@ static int parse_auth_choice(struct openconnect_info *vpninfo, struct oc_auth_fo opt->form.label = (char *)xmlGetProp(xml_node, (unsigned char *)"label"); if (!opt->form.name) { - vpninfo->progress(vpninfo, PRG_ERR, "Form choice has no name\n"); + vpn_progress(vpninfo, PRG_ERR, "Form choice has no name\n"); free(opt); return -EINVAL; } @@ -184,13 +184,13 @@ static int parse_form(struct openconnect_info *vpninfo, struct oc_auth_form *for continue; } if (strcmp((char *)xml_node->name, "input")) { - vpninfo->progress(vpninfo, PRG_TRACE, "name %s not input\n", xml_node->name); + vpn_progress(vpninfo, PRG_TRACE, "name %s not input\n", xml_node->name); continue; } input_type = (char *)xmlGetProp(xml_node, (unsigned char *)"type"); if (!input_type) { - vpninfo->progress(vpninfo, PRG_INFO, "No input type in form\n"); + vpn_progress(vpninfo, PRG_INFO, "No input type in form\n"); continue; } @@ -201,7 +201,7 @@ static int parse_form(struct openconnect_info *vpninfo, struct oc_auth_form *for input_name = (char *)xmlGetProp(xml_node, (unsigned char *)"name"); if (!input_name) { - vpninfo->progress(vpninfo, PRG_INFO, "No input name in form\n"); + vpn_progress(vpninfo, PRG_INFO, "No input name in form\n"); free(input_type); continue; } @@ -223,7 +223,7 @@ static int parse_form(struct openconnect_info *vpninfo, struct oc_auth_form *for else if (!strcmp(input_type, "password")) opt->type = OC_FORM_OPT_PASSWORD; else { - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "Unknown input type %s in form\n", input_type); free(input_type); @@ -244,7 +244,7 @@ static int parse_form(struct openconnect_info *vpninfo, struct oc_auth_form *for *p = opt; } - vpninfo->progress(vpninfo, PRG_TRACE, "Fixed options give %s\n", body); + vpn_progress(vpninfo, PRG_TRACE, "Fixed options give %s\n", body); return 0; } @@ -316,15 +316,15 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response, xml_doc = xmlReadMemory(response, strlen(response), "noname.xml", NULL, 0); if (!xml_doc) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to parse server response\n"); - vpninfo->progress(vpninfo, PRG_TRACE, "Response was:%s\n", response); + vpn_progress(vpninfo, PRG_ERR, "Failed to parse server response\n"); + vpn_progress(vpninfo, PRG_TRACE, "Response was:%s\n", response); free(form); return -EINVAL; } xml_node = xmlDocGetRootElement(xml_doc); if (xml_node->type != XML_ELEMENT_NODE || strcmp((char *)xml_node->name, "auth")) { - vpninfo->progress(vpninfo, PRG_ERR, "XML response has no \"auth\" root node\n"); + vpn_progress(vpninfo, PRG_ERR, "XML response has no \"auth\" root node\n"); ret = -EINVAL; goto out; } @@ -336,7 +336,7 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response, } if (vpninfo->nopasswd) { - vpninfo->progress(vpninfo, PRG_ERR, "Asked for password but '--no-passwd' set\n"); + vpn_progress(vpninfo, PRG_ERR, "Asked for password but '--no-passwd' set\n"); ret = -EPERM; goto out; } @@ -360,7 +360,7 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response, form->action = (char *)xmlGetProp(xml_node, (unsigned char *)"action"); if (!form->method || !form->action || strcasecmp(form->method, "POST") || !form->action[0]) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Cannot handle form method='%s', action='%s'\n", form->method, form->action); ret = -EINVAL; @@ -407,15 +407,15 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response, } if (!form->opts) { if (form->message) - vpninfo->progress(vpninfo, PRG_INFO, "%s\n", form->message); + vpn_progress(vpninfo, PRG_INFO, "%s\n", form->message); if (form->error) - vpninfo->progress(vpninfo, PRG_ERR, "%s\n", form->error); + vpn_progress(vpninfo, PRG_ERR, "%s\n", form->error); ret = -EPERM; goto out; } if (vpninfo->process_auth_form) - ret = vpninfo->process_auth_form(vpninfo, form); + ret = vpninfo->process_auth_form(vpninfo->cbdata, form); else ret = process_auth_form(vpninfo, form); if (ret) @@ -481,7 +481,7 @@ static int process_auth_form(struct openconnect_info *vpninfo, choice_resp[0] = 0; if (!ui) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to create UI\n"); + vpn_progress(vpninfo, PRG_ERR, "Failed to create UI\n"); return -EINVAL; } if (form->banner) { @@ -523,7 +523,7 @@ static int process_auth_form(struct openconnect_info *vpninfo, } } if (!opt->value) - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Auth choice \"%s\" not available\n", vpninfo->authgroup); } @@ -604,7 +604,7 @@ static int process_auth_form(struct openconnect_info *vpninfo, goto out_ui; case -1: /* error */ - vpninfo->progress(vpninfo, PRG_ERR, "Invalid inputs\n"); + vpn_progress(vpninfo, PRG_ERR, "Invalid inputs\n"); ret = -EINVAL; out_ui: UI_free(ui); @@ -626,7 +626,7 @@ static int process_auth_form(struct openconnect_info *vpninfo, } } if (!select_opt->form.value) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Auth choice \"%s\" not valid\n", choice_resp); return -EINVAL; diff --git a/cstp.c b/cstp.c index e29c817c..d8efbd94 100644 --- a/cstp.c +++ b/cstp.c @@ -129,13 +129,13 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) vpninfo->dtls_ciphers?:"AES256-SHA:AES128-SHA:DES-CBC3-SHA:DES-CBC-SHA"); if (openconnect_SSL_gets(vpninfo->https_ssl, buf, 65536) < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Error fetching HTTPS response\n"); + vpn_progress(vpninfo, PRG_ERR, "Error fetching HTTPS response\n"); if (!retried) { retried = 1; openconnect_close_https(vpninfo); if (openconnect_open_https(vpninfo)) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Failed to open HTTPS connection to %s\n", vpninfo->hostname); exit(1); @@ -155,11 +155,11 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) break; } } - vpninfo->progress(vpninfo, PRG_ERR, "VPN service unavailable; reason: %s\n", + vpn_progress(vpninfo, PRG_ERR, "VPN service unavailable; reason: %s\n", reason); return -EINVAL; } - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Got inappropriate HTTP CONNECT response: %s\n", buf); if (!strncmp(buf, "HTTP/1.1 401 ", 13)) @@ -167,7 +167,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) return -EINVAL; } - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "Got CONNECT response: %s\n", buf); /* We may have advertised it, but we only do it if the server agrees */ @@ -190,7 +190,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) new_option = malloc(sizeof(*new_option)); if (!new_option) { - vpninfo->progress(vpninfo, PRG_ERR, "No memory for options\n"); + vpn_progress(vpninfo, PRG_ERR, "No memory for options\n"); return -ENOMEM; } new_option->option = strdup(buf); @@ -198,11 +198,11 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) new_option->next = NULL; if (!new_option->option || !new_option->value) { - vpninfo->progress(vpninfo, PRG_ERR, "No memory for options\n"); + vpn_progress(vpninfo, PRG_ERR, "No memory for options\n"); return -ENOMEM; } - vpninfo->progress(vpninfo, PRG_TRACE, "%s: %s\n", buf, colon); + vpn_progress(vpninfo, PRG_TRACE, "%s: %s\n", buf, colon); if (!strncmp(buf, "X-DTLS-", 7)) { *next_dtls_option = new_option; @@ -210,8 +210,8 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) if (!strcmp(buf + 7, "Session-ID")) { if (strlen(colon) != 64) { - vpninfo->progress(vpninfo, PRG_ERR, "X-DTLS-Session-ID not 64 characters\n"); - vpninfo->progress(vpninfo, PRG_ERR, "Is: %s\n", colon); + vpn_progress(vpninfo, PRG_ERR, "X-DTLS-Session-ID not 64 characters\n"); + vpn_progress(vpninfo, PRG_ERR, "Is: %s\n", colon); vpninfo->dtls_attempt_period = 0; return -EINVAL; } @@ -239,7 +239,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) if (!strcmp(colon, "deflate")) vpninfo->deflate = 1; else { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Unknown CSTP-Content-Encoding %s\n", colon); return -EINVAL; @@ -296,33 +296,33 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) } if (!vpninfo->vpn_addr && !vpninfo->vpn_addr6) { - vpninfo->progress(vpninfo, PRG_ERR, "No IP address received. Aborting\n"); + vpn_progress(vpninfo, PRG_ERR, "No IP address received. Aborting\n"); return -EINVAL; } if (old_addr) { if (strcmp(old_addr, vpninfo->vpn_addr)) { - vpninfo->progress(vpninfo, PRG_ERR, "Reconnect gave different Legacy IP address (%s != %s)\n", + vpn_progress(vpninfo, PRG_ERR, "Reconnect gave different Legacy IP address (%s != %s)\n", vpninfo->vpn_addr, old_addr); return -EINVAL; } } if (old_netmask) { if (strcmp(old_netmask, vpninfo->vpn_netmask)) { - vpninfo->progress(vpninfo, PRG_ERR, "Reconnect gave different Legacy IP netmask (%s != %s)\n", + vpn_progress(vpninfo, PRG_ERR, "Reconnect gave different Legacy IP netmask (%s != %s)\n", vpninfo->vpn_netmask, old_netmask); return -EINVAL; } } if (old_addr6) { if (strcmp(old_addr6, vpninfo->vpn_addr6)) { - vpninfo->progress(vpninfo, PRG_ERR, "Reconnect gave different IPv6 address (%s != %s)\n", + vpn_progress(vpninfo, PRG_ERR, "Reconnect gave different IPv6 address (%s != %s)\n", vpninfo->vpn_addr6, old_addr6); return -EINVAL; } } if (old_netmask6) { if (strcmp(old_netmask6, vpninfo->vpn_netmask6)) { - vpninfo->progress(vpninfo, PRG_ERR, "Reconnect gave different IPv6 netmask (%s != %s)\n", + vpn_progress(vpninfo, PRG_ERR, "Reconnect gave different IPv6 netmask (%s != %s)\n", vpninfo->vpn_netmask6, old_netmask6); return -EINVAL; } @@ -342,7 +342,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) free(tmp->option); free(tmp); } - vpninfo->progress(vpninfo, PRG_INFO, "CSTP connected. DPD %d, Keepalive %d\n", + vpn_progress(vpninfo, PRG_INFO, "CSTP connected. DPD %d, Keepalive %d\n", vpninfo->ssl_times.dpd, vpninfo->ssl_times.keepalive); BIO_set_nbio(SSL_get_rbio(vpninfo->https_ssl), 1); @@ -378,14 +378,14 @@ int make_cstp_connection(struct openconnect_info *vpninfo) if (inflateInit2(&vpninfo->inflate_strm, -12) || deflateInit2(&vpninfo->deflate_strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -12, 9, Z_DEFAULT_STRATEGY)) { - vpninfo->progress(vpninfo, PRG_ERR, "Compression setup failed\n"); + vpn_progress(vpninfo, PRG_ERR, "Compression setup failed\n"); vpninfo->deflate = 0; } if (!vpninfo->deflate_pkt) { vpninfo->deflate_pkt = malloc(sizeof(struct pkt) + 2048); if (!vpninfo->deflate_pkt) { - vpninfo->progress(vpninfo, PRG_ERR, "Allocation of deflate buffer failed\n"); + vpn_progress(vpninfo, PRG_ERR, "Allocation of deflate buffer failed\n"); vpninfo->deflate = 0; } memset(vpninfo->deflate_pkt, 0, sizeof(struct pkt)); @@ -416,7 +416,7 @@ int cstp_reconnect(struct openconnect_info *vpninfo) while ((ret = make_cstp_connection(vpninfo))) { if (timeout <= 0) return ret; - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "sleep %ds, remaining timeout %ds\n", interval, timeout); sleep(interval); @@ -448,7 +448,7 @@ static int inflate_and_queue_packet(struct openconnect_info *vpninfo, void *buf, vpninfo->inflate_strm.total_out = 0; if (inflate(&vpninfo->inflate_strm, Z_SYNC_FLUSH)) { - vpninfo->progress(vpninfo, PRG_ERR, "inflate failed\n"); + vpn_progress(vpninfo, PRG_ERR, "inflate failed\n"); free(new); return -EINVAL; } @@ -462,7 +462,7 @@ static int inflate_and_queue_packet(struct openconnect_info *vpninfo, void *buf, vpninfo->quit_reason = "Compression (inflate) adler32 failure"; } - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Received compressed data packet of %ld bytes\n", vpninfo->inflate_strm.total_out); @@ -491,10 +491,10 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) payload_len = (buf[4] << 8) + buf[5]; if (len != 8 + payload_len) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Unexpected packet length. SSL_read returned %d but packet is\n", len); - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "%02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); @@ -503,23 +503,23 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) vpninfo->ssl_times.last_rx = time(NULL); switch(buf[6]) { case AC_PKT_DPD_OUT: - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Got CSTP DPD request\n"); vpninfo->owe_ssl_dpd_response = 1; continue; case AC_PKT_DPD_RESP: - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Got CSTP DPD response\n"); continue; case AC_PKT_KEEPALIVE: - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Got CSTP Keepalive\n"); continue; case AC_PKT_DATA: - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Received uncompressed data packet of %d bytes\n", payload_len); queue_new_packet(&vpninfo->incoming_queue, buf + 8, @@ -534,14 +534,14 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) buf[payload_len + 8 + i] = '.'; } buf[payload_len + 8] = 0; - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Received server disconnect: %02x '%s'\n", buf[8], buf + 9); vpninfo->quit_reason = "Server request"; return 1; } case AC_PKT_COMPRESSED: if (!vpninfo->deflate) { - vpninfo->progress(vpninfo, PRG_ERR, "Compressed packet received in !deflate mode\n"); + vpn_progress(vpninfo, PRG_ERR, "Compressed packet received in !deflate mode\n"); goto unknown_pkt; } inflate_and_queue_packet(vpninfo, buf + 8, payload_len); @@ -549,13 +549,13 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) continue; case AC_PKT_TERM_SERVER: - vpninfo->progress(vpninfo, PRG_ERR, "received server terminate packet\n"); + vpn_progress(vpninfo, PRG_ERR, "received server terminate packet\n"); vpninfo->quit_reason = "Server request"; return 1; } unknown_pkt: - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Unknown packet %02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); @@ -565,7 +565,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) ret = SSL_get_error(vpninfo->https_ssl, len); if (ret == SSL_ERROR_SYSCALL || ret == SSL_ERROR_ZERO_RETURN) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "SSL read error %d (server probably closed connection); reconnecting.\n", ret); goto do_reconnect; @@ -595,13 +595,13 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) goto peer_dead; return work_done; default: - vpninfo->progress(vpninfo, PRG_ERR, "SSL_write failed: %d\n", ret); + vpn_progress(vpninfo, PRG_ERR, "SSL_write failed: %d\n", ret); report_ssl_errors(vpninfo); goto do_reconnect; } } if (ret != vpninfo->current_ssl_pkt->len + 8) { - vpninfo->progress(vpninfo, PRG_ERR, "SSL wrote too few bytes! Asked for %d, sent %d\n", + vpn_progress(vpninfo, PRG_ERR, "SSL wrote too few bytes! Asked for %d, sent %d\n", vpninfo->current_ssl_pkt->len + 8, ret); vpninfo->quit_reason = "Internal error"; return 1; @@ -626,16 +626,16 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) case KA_REKEY: /* Not that this will ever happen; we don't even process the setting when we're asked for it. */ - vpninfo->progress(vpninfo, PRG_INFO, "CSTP rekey due\n"); + vpn_progress(vpninfo, PRG_INFO, "CSTP rekey due\n"); goto do_reconnect; break; case KA_DPD_DEAD: peer_dead: - vpninfo->progress(vpninfo, PRG_ERR, "CSTP Dead Peer Detection detected dead peer!\n"); + vpn_progress(vpninfo, PRG_ERR, "CSTP Dead Peer Detection detected dead peer!\n"); do_reconnect: if (cstp_reconnect(vpninfo)) { - vpninfo->progress(vpninfo, PRG_ERR, "Reconnect failed\n"); + vpn_progress(vpninfo, PRG_ERR, "Reconnect failed\n"); vpninfo->quit_reason = "CSTP reconnect failed"; return 1; } @@ -644,7 +644,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) return 1; case KA_DPD: - vpninfo->progress(vpninfo, PRG_TRACE, "Send CSTP DPD\n"); + vpn_progress(vpninfo, PRG_TRACE, "Send CSTP DPD\n"); vpninfo->current_ssl_pkt = &dpd_pkt; goto handle_outgoing; @@ -655,7 +655,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) if (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue) break; - vpninfo->progress(vpninfo, PRG_TRACE, "Send CSTP Keepalive\n"); + vpn_progress(vpninfo, PRG_TRACE, "Send CSTP Keepalive\n"); vpninfo->current_ssl_pkt = &keepalive_pkt; goto handle_outgoing; @@ -682,7 +682,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) ret = deflate(&vpninfo->deflate_strm, Z_SYNC_FLUSH); if (ret) { - vpninfo->progress(vpninfo, PRG_ERR, "deflate failed %d\n", ret); + vpn_progress(vpninfo, PRG_ERR, "deflate failed %d\n", ret); goto uncompr; } @@ -701,7 +701,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) vpninfo->deflate_pkt->len = vpninfo->deflate_strm.total_out + 4; - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Sending compressed data packet of %d bytes\n", this->len); @@ -712,7 +712,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) this->hdr[4] = this->len >> 8; this->hdr[5] = this->len & 0xff; - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Sending uncompressed data packet of %d bytes\n", this->len); @@ -750,7 +750,7 @@ int cstp_bye(struct openconnect_info *vpninfo, char *reason) SSL_write(vpninfo->https_ssl, bye_pkt, reason_len + 9); free(bye_pkt); - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "Send BYE packet: %s\n", reason); return 0; diff --git a/dtls.c b/dtls.c index 1f8e482b..cff6ef3c 100644 --- a/dtls.c +++ b/dtls.c @@ -113,21 +113,21 @@ int connect_dtls_socket(struct openconnect_info *vpninfo) int dtls_fd; if (!vpninfo->dtls_addr) { - vpninfo->progress(vpninfo, PRG_ERR, "No DTLS address\n"); + vpn_progress(vpninfo, PRG_ERR, "No DTLS address\n"); vpninfo->dtls_attempt_period = 0; return -EINVAL; } if (!vpninfo->dtls_cipher) { /* We probably didn't offer it any ciphers it liked */ - vpninfo->progress(vpninfo, PRG_ERR, "Server offered no DTLS cipher option\n"); + vpn_progress(vpninfo, PRG_ERR, "Server offered no DTLS cipher option\n"); vpninfo->dtls_attempt_period = 0; return -EINVAL; } if (vpninfo->proxy) { /* XXX: Theoretically, SOCKS5 proxies can do UDP too */ - vpninfo->progress(vpninfo, PRG_ERR, "No DTLS when connected via proxy\n"); + vpn_progress(vpninfo, PRG_ERR, "No DTLS when connected via proxy\n"); vpninfo->dtls_attempt_period = 0; return -EINVAL; } @@ -150,7 +150,7 @@ int connect_dtls_socket(struct openconnect_info *vpninfo) dtls_method = DTLSv1_client_method(); vpninfo->dtls_ctx = SSL_CTX_new(dtls_method); if (!vpninfo->dtls_ctx) { - vpninfo->progress(vpninfo, PRG_ERR, "Initialise DTLSv1 CTX failed\n"); + vpn_progress(vpninfo, PRG_ERR, "Initialise DTLSv1 CTX failed\n"); vpninfo->dtls_attempt_period = 0; return -EINVAL; } @@ -160,7 +160,7 @@ int connect_dtls_socket(struct openconnect_info *vpninfo) SSL_CTX_set_read_ahead(vpninfo->dtls_ctx, 1); if (!SSL_CTX_set_cipher_list(vpninfo->dtls_ctx, vpninfo->dtls_cipher)) { - vpninfo->progress(vpninfo, PRG_ERR, "Set DTLS cipher list failed\n"); + vpn_progress(vpninfo, PRG_ERR, "Set DTLS cipher list failed\n"); SSL_CTX_free(vpninfo->dtls_ctx); vpninfo->dtls_ctx = NULL; vpninfo->dtls_attempt_period = 0; @@ -172,7 +172,7 @@ int connect_dtls_socket(struct openconnect_info *vpninfo) /* We're going to "resume" a session which never existed. Fake it... */ vpninfo->dtls_session = SSL_SESSION_new(); if (!vpninfo->dtls_session) { - vpninfo->progress(vpninfo, PRG_ERR, "Initialise DTLSv1 session failed\n"); + vpn_progress(vpninfo, PRG_ERR, "Initialise DTLSv1 session failed\n"); vpninfo->dtls_attempt_period = 0; return -EINVAL; } @@ -193,7 +193,7 @@ int connect_dtls_socket(struct openconnect_info *vpninfo) ciphers = SSL_get_ciphers(dtls_ssl); if (sk_SSL_CIPHER_num(ciphers) != 1) { - vpninfo->progress(vpninfo, PRG_ERR, "Not precisely one DTLS cipher\n"); + vpn_progress(vpninfo, PRG_ERR, "Not precisely one DTLS cipher\n"); SSL_CTX_free(vpninfo->dtls_ctx); SSL_free(dtls_ssl); SSL_SESSION_free(vpninfo->dtls_session); @@ -210,7 +210,7 @@ int connect_dtls_socket(struct openconnect_info *vpninfo) /* Add the generated session to the SSL */ if (!SSL_set_session(dtls_ssl, vpninfo->dtls_session)) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "SSL_set_session() failed with old protocol version 0x%x\n" "Are you using a version of OpenSSL older than 0.9.8m?\n" "See http://rt.openssl.org/Ticket/Display.html?id=1751\n" @@ -254,7 +254,7 @@ int dtls_try_handshake(struct openconnect_info *vpninfo) int ret = SSL_do_handshake(vpninfo->new_dtls_ssl); if (ret == 1) { - vpninfo->progress(vpninfo, PRG_INFO, "Established DTLS connection\n"); + vpn_progress(vpninfo, PRG_INFO, "Established DTLS connection\n"); if (vpninfo->dtls_ssl) { /* We are replacing an old connection */ @@ -279,10 +279,10 @@ int dtls_try_handshake(struct openconnect_info *vpninfo) if (ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ) { if (time(NULL) < vpninfo->new_dtls_started + 5) return 0; - vpninfo->progress(vpninfo, PRG_TRACE, "DTLS handshake timed out\n"); + vpn_progress(vpninfo, PRG_TRACE, "DTLS handshake timed out\n"); } - vpninfo->progress(vpninfo, PRG_ERR, "DTLS handshake failed: %d\n", ret); + vpn_progress(vpninfo, PRG_ERR, "DTLS handshake failed: %d\n", ret); report_ssl_errors(vpninfo); /* Kill the new (failed) connection... */ @@ -332,7 +332,7 @@ int setup_dtls(struct openconnect_info *vpninfo) int dtls_port = 0; while (dtls_opt) { - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "DTLS option %s : %s\n", dtls_opt->option, dtls_opt->value); @@ -371,7 +371,7 @@ int setup_dtls(struct openconnect_info *vpninfo) struct sockaddr_in6 *sin = (void *)vpninfo->dtls_addr; sin->sin6_port = htons(dtls_port); } else { - vpninfo->progress(vpninfo, PRG_ERR, "Unknown protocol family %d. Cannot do DTLS\n", + vpn_progress(vpninfo, PRG_ERR, "Unknown protocol family %d. Cannot do DTLS\n", vpninfo->peer_addr->sa_family); vpninfo->dtls_attempt_period = 0; return -EINVAL; @@ -380,7 +380,7 @@ int setup_dtls(struct openconnect_info *vpninfo) if (connect_dtls_socket(vpninfo)) return -EINVAL; - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "DTLS connected. DPD %d, Keepalive %d\n", vpninfo->dtls_times.dpd, vpninfo->dtls_times.keepalive); @@ -396,7 +396,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) while ( (len = SSL_read(vpninfo->dtls_ssl, buf, sizeof(buf))) > 0 ) { - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Received DTLS packet 0x%02x of %d bytes\n", buf[0], len); @@ -409,24 +409,24 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) break; case AC_PKT_DPD_OUT: - vpninfo->progress(vpninfo, PRG_TRACE, "Got DTLS DPD request\n"); + vpn_progress(vpninfo, PRG_TRACE, "Got DTLS DPD request\n"); /* FIXME: What if the packet doesn't get through? */ magic_pkt = AC_PKT_DPD_RESP; if (SSL_write(vpninfo->dtls_ssl, &magic_pkt, 1) != 1) - vpninfo->progress(vpninfo, PRG_ERR, "Failed to send DPD response. Expect disconnect\n"); + vpn_progress(vpninfo, PRG_ERR, "Failed to send DPD response. Expect disconnect\n"); continue; case AC_PKT_DPD_RESP: - vpninfo->progress(vpninfo, PRG_TRACE, "Got DTLS DPD response\n"); + vpn_progress(vpninfo, PRG_TRACE, "Got DTLS DPD response\n"); break; case AC_PKT_KEEPALIVE: - vpninfo->progress(vpninfo, PRG_TRACE, "Got DTLS Keepalive\n"); + vpn_progress(vpninfo, PRG_TRACE, "Got DTLS Keepalive\n"); break; default: - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Unknown DTLS packet type %02x, len %d\n", buf[0], len); if (1) { /* Some versions of OpenSSL have bugs with receiving out-of-order @@ -445,18 +445,18 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) switch (keepalive_action(&vpninfo->dtls_times, timeout)) { case KA_REKEY: - vpninfo->progress(vpninfo, PRG_INFO, "DTLS rekey due\n"); + vpn_progress(vpninfo, PRG_INFO, "DTLS rekey due\n"); /* There ought to be a method of rekeying DTLS without tearing down the CSTP session and restarting, but we don't (yet) know it */ if (cstp_reconnect(vpninfo)) { - vpninfo->progress(vpninfo, PRG_ERR, "Reconnect failed\n"); + vpn_progress(vpninfo, PRG_ERR, "Reconnect failed\n"); vpninfo->quit_reason = "CSTP reconnect failed"; return 1; } if (dtls_restart(vpninfo)) { - vpninfo->progress(vpninfo, PRG_ERR, "DTLS rekey failed\n"); + vpn_progress(vpninfo, PRG_ERR, "DTLS rekey failed\n"); return 1; } work_done = 1; @@ -464,13 +464,13 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) case KA_DPD_DEAD: - vpninfo->progress(vpninfo, PRG_ERR, "DTLS Dead Peer Detection detected dead peer!\n"); + vpn_progress(vpninfo, PRG_ERR, "DTLS Dead Peer Detection detected dead peer!\n"); /* Fall back to SSL, and start a new DTLS connection */ dtls_restart(vpninfo); return 1; case KA_DPD: - vpninfo->progress(vpninfo, PRG_TRACE, "Send DTLS DPD\n"); + vpn_progress(vpninfo, PRG_TRACE, "Send DTLS DPD\n"); magic_pkt = AC_PKT_DPD_OUT; SSL_write(vpninfo->dtls_ssl, &magic_pkt, 1); @@ -485,7 +485,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) if (vpninfo->outgoing_queue) break; - vpninfo->progress(vpninfo, PRG_TRACE, "Send DTLS Keepalive\n"); + vpn_progress(vpninfo, PRG_TRACE, "Send DTLS Keepalive\n"); magic_pkt = AC_PKT_KEEPALIVE; SSL_write(vpninfo->dtls_ssl, &magic_pkt, 1); @@ -515,7 +515,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) /* If it's a real error, kill the DTLS connection and requeue the packet to be sent over SSL */ if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "DTLS got write error %d. Falling back to SSL\n", ret); report_ssl_errors(vpninfo); dtls_restart(vpninfo); @@ -525,7 +525,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) return 1; } time(&vpninfo->dtls_times.last_tx); - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Sent DTLS packet of %d bytes; SSL_write() returned %d\n", this->len, ret); free(this); @@ -536,7 +536,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) #else /* No DTLS support in OpenSSL */ int setup_dtls(struct openconnect_info *vpninfo) { - vpninfo->progress(vpninfo, PRG_ERR, "Built against OpenSSL with no DTLS support\n"); + vpn_progress(vpninfo, PRG_ERR, "Built against OpenSSL with no DTLS support\n"); return -EINVAL; } #endif diff --git a/http.c b/http.c index d04ef6c5..4802007a 100644 --- a/http.c +++ b/http.c @@ -59,7 +59,7 @@ static int http_add_cookie(struct openconnect_info *vpninfo, if (*value) { new = malloc(sizeof(*new)); if (!new) { - vpninfo->progress(vpninfo, PRG_ERR, "No memory for allocating cookies\n"); + vpn_progress(vpninfo, PRG_ERR, "No memory for allocating cookies\n"); return -ENOMEM; } new->next = NULL; @@ -113,7 +113,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, cont: if (openconnect_SSL_gets(vpninfo->https_ssl, buf, sizeof(buf)) < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Error fetching HTTPS response\n"); + vpn_progress(vpninfo, PRG_ERR, "Error fetching HTTPS response\n"); return -EINVAL; } @@ -121,11 +121,11 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, closeconn = 1; if ((!closeconn && strncmp(buf, "HTTP/1.1 ", 9)) || !(*result = atoi(buf+9))) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to parse HTTP response '%s'\n", buf); + vpn_progress(vpninfo, PRG_ERR, "Failed to parse HTTP response '%s'\n", buf); return -EINVAL; } - vpninfo->progress(vpninfo, (*result==200)?PRG_TRACE:PRG_INFO, + vpn_progress(vpninfo, (*result==200)?PRG_TRACE:PRG_INFO, "Got HTTP response: %s\n", buf); /* Eat headers... */ @@ -133,12 +133,12 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, char *colon; if (i < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Error processing HTTP response\n"); + vpn_progress(vpninfo, PRG_ERR, "Error processing HTTP response\n"); return -EINVAL; } colon = strchr(buf, ':'); if (!colon) { - vpninfo->progress(vpninfo, PRG_ERR, "Ignoring unknown HTTP response line '%s'\n", buf); + vpn_progress(vpninfo, PRG_ERR, "Ignoring unknown HTTP response line '%s'\n", buf); continue; } *(colon++) = 0; @@ -156,7 +156,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, *semicolon = 0; if (!equals) { - vpninfo->progress(vpninfo, PRG_ERR, "Invalid cookie offered: %s\n", buf); + vpn_progress(vpninfo, PRG_ERR, "Invalid cookie offered: %s\n", buf); return -EINVAL; } *(equals++) = 0; @@ -166,7 +166,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, want people posting it in public with debugging output */ if (!strcmp(colon, "webvpn") && *equals) print_equals = ""; - vpninfo->progress(vpninfo, PRG_TRACE, "%s: %s=%s%s%s\n", + vpn_progress(vpninfo, PRG_TRACE, "%s: %s=%s%s%s\n", buf, colon, print_equals, semicolon?";":"", semicolon?(semicolon+1):""); @@ -174,7 +174,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, if (ret) return ret; } else { - vpninfo->progress(vpninfo, PRG_TRACE, "%s: %s\n", buf, colon); + vpn_progress(vpninfo, PRG_TRACE, "%s: %s\n", buf, colon); } if (!strcasecmp(buf, "Connection")) { @@ -198,7 +198,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, if (!strcasecmp(buf, "Content-Length")) { bodylen = atoi(colon); if (bodylen < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Response body has negative size (%d)\n", + vpn_progress(vpninfo, PRG_ERR, "Response body has negative size (%d)\n", bodylen); return -EINVAL; } @@ -207,7 +207,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, if (!strcasecmp(colon, "chunked")) bodylen = BODY_CHUNKED; else { - vpninfo->progress(vpninfo, PRG_ERR, "Unknown Transfer-Encoding: %s\n", colon); + vpn_progress(vpninfo, PRG_ERR, "Unknown Transfer-Encoding: %s\n", colon); return -EINVAL; } } @@ -220,7 +220,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, goto cont; /* Now the body, if there is one */ - vpninfo->progress(vpninfo, PRG_TRACE, "HTTP body %s (%d)\n", + vpn_progress(vpninfo, PRG_TRACE, "HTTP body %s (%d)\n", bodylen==BODY_HTTP10?"http 1.0" : bodylen==BODY_CHUNKED?"chunked" : "length: ", bodylen); @@ -233,7 +233,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, while (done < bodylen) { i = SSL_read(vpninfo->https_ssl, body + done, bodylen - done); if (i < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Error reading HTTP response body\n"); + vpn_progress(vpninfo, PRG_ERR, "Error reading HTTP response body\n"); free(body); return -EINVAL; } @@ -245,7 +245,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, int chunklen, lastchunk = 0; if (i < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Error fetching chunk header\n"); + vpn_progress(vpninfo, PRG_ERR, "Error fetching chunk header\n"); exit(1); } chunklen = strtol(buf, NULL, 16); @@ -259,7 +259,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, while (chunklen) { i = SSL_read(vpninfo->https_ssl, body + done, chunklen); if (i < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Error reading HTTP response body\n"); + vpn_progress(vpninfo, PRG_ERR, "Error reading HTTP response body\n"); free(body); return -EINVAL; } @@ -269,9 +269,9 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, skip: if ((i = openconnect_SSL_gets(vpninfo->https_ssl, buf, sizeof(buf)))) { if (i < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Error fetching HTTP response body\n"); + vpn_progress(vpninfo, PRG_ERR, "Error fetching HTTP response body\n"); } else { - vpninfo->progress(vpninfo, PRG_ERR, "Error in chunked decoding. Expected '', got: '%s'", + vpn_progress(vpninfo, PRG_ERR, "Error in chunked decoding. Expected '', got: '%s'", buf); } free(body); @@ -283,7 +283,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result, } } else if (bodylen == BODY_HTTP10) { if (!closeconn) { - vpninfo->progress(vpninfo, PRG_ERR, "Cannot receive HTTP 1.0 body without closing connection\n"); + vpn_progress(vpninfo, PRG_ERR, "Cannot receive HTTP 1.0 body without closing connection\n"); return -EINVAL; } @@ -363,12 +363,12 @@ static int fetch_config(struct openconnect_info *vpninfo, char *fu, char *bu, sprintf(&local_sha1_ascii[i*2], "%02x", local_sha1_bin[i]); if (strcasecmp(server_sha1, local_sha1_ascii)) { - vpninfo->progress(vpninfo, PRG_ERR, "Downloaded config file did not match intended SHA1\n"); + vpn_progress(vpninfo, PRG_ERR, "Downloaded config file did not match intended SHA1\n"); free(config_buf); return -EINVAL; } - result = vpninfo->write_new_config(vpninfo, config_buf, buflen); + result = vpninfo->write_new_config(vpninfo->cbdata, config_buf, buflen); free(config_buf); return result; } @@ -379,14 +379,14 @@ static int run_csd_script(struct openconnect_info *vpninfo, char *buf, int bufle int fd, ret; if (!vpninfo->uid_csd_given && !vpninfo->csd_wrapper) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Error: Server asked us to download and run a 'Cisco Secure Desktop' trojan.\n" "This facility is disabled by default for security reasons, so you may wish to enable it."); return -EPERM; } #ifndef __linux__ - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "Trying to run Linux CSD trojan script."); #endif @@ -394,14 +394,14 @@ static int run_csd_script(struct openconnect_info *vpninfo, char *buf, int bufle fd = mkstemp(fname); if (fd < 0) { int err = -errno; - vpninfo->progress(vpninfo, PRG_ERR, "Failed to open temporary CSD script file: %s\n", + vpn_progress(vpninfo, PRG_ERR, "Failed to open temporary CSD script file: %s\n", strerror(errno)); return err; } ret = proxy_write(fd, (void *)buf, buflen); if (ret) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to write temporary CSD script file: %s\n", + vpn_progress(vpninfo, PRG_ERR, "Failed to write temporary CSD script file: %s\n", strerror(ret)); return ret; } @@ -483,7 +483,7 @@ static int run_csd_script(struct openconnect_info *vpninfo, char *buf, int bufle csd_argv[i++] = NULL; execv(csd_argv[0], csd_argv); - vpninfo->progress(vpninfo, PRG_ERR, "Failed to exec CSD script %s\n", csd_argv[0]); + vpn_progress(vpninfo, PRG_ERR, "Failed to exec CSD script %s\n", csd_argv[0]); exit(1); } @@ -604,7 +604,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo) form_buf = NULL; } if (!vpninfo->https_ssl && openconnect_open_https(vpninfo)) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to open HTTPS connection to %s\n", + vpn_progress(vpninfo, PRG_ERR, "Failed to open HTTPS connection to %s\n", vpninfo->hostname); return -EINVAL; } @@ -641,11 +641,11 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo) sprintf(buf + strlen(buf), "%s", request_body); if (vpninfo->port == 443) - vpninfo->progress(vpninfo, PRG_INFO, "%s https://%s/%s\n", + vpn_progress(vpninfo, PRG_INFO, "%s https://%s/%s\n", method, vpninfo->hostname, vpninfo->urlpath ?: ""); else - vpninfo->progress(vpninfo, PRG_INFO, "%s https://%s:%d/%s\n", + vpn_progress(vpninfo, PRG_INFO, "%s https://%s:%d/%s\n", method, vpninfo->hostname, vpninfo->port, vpninfo->urlpath ?: ""); @@ -670,7 +670,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo) ret = internal_parse_url(vpninfo->redirect_url, NULL, &host, &port, &vpninfo->urlpath, 0); if (ret) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to parse redirected URL '%s': %s\n", + vpn_progress(vpninfo, PRG_ERR, "Failed to parse redirected URL '%s': %s\n", vpninfo->redirect_url, strerror(-ret)); free(vpninfo->redirect_url); free(form_buf); @@ -729,7 +729,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo) if (asprintf(&vpninfo->urlpath, "%s/%s", oldurl, vpninfo->redirect_url) == -1) { int err = -errno; - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Allocating new path for relative redirect failed: %s\n", strerror(-err)); return err; @@ -742,7 +742,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo) } } if (!form_buf || result != 200) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Unexpected %d result from server\n", result); free(form_buf); @@ -762,12 +762,12 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo) if (strncmp(form_buf, "progress(vpninfo, PRG_INFO, "Refreshing %s after 1 second...\n", + vpn_progress(vpninfo, PRG_INFO, "Refreshing %s after 1 second...\n", vpninfo->urlpath); sleep(1); goto retry; } - vpninfo->progress(vpninfo, PRG_ERR, "Unknown response from server\n"); + vpn_progress(vpninfo, PRG_ERR, "Unknown response from server\n"); free(form_buf); return -EINVAL; } @@ -913,20 +913,20 @@ static int process_socks_proxy(struct openconnect_info *vpninfo, int ssl_sock) buf[2] = 0; /* No auth supported */ if ((i = proxy_write(ssl_sock, buf, 3))) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Error writing auth request to SOCKS proxy: %s\n", strerror(-i)); return i; } if ((i = proxy_read(ssl_sock, buf, 2))) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Error reading auth response from SOCKS proxy: %s\n", strerror(-i)); return i; } if (buf[0] != 5) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Unexpected auth response from SOCKS proxy: %02x %02x\n", buf[0], buf[1]); return -EIO; @@ -934,17 +934,17 @@ static int process_socks_proxy(struct openconnect_info *vpninfo, int ssl_sock) if (buf[1]) { socks_err: if (buf[1] < sizeof(socks_errors) / sizeof(socks_errors[0])) - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "SOCKS proxy error %02x: %s\n", buf[1], socks_errors[buf[1]]); else - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "SOCKS proxy error %02x\n", buf[1]); return -EIO; } - vpninfo->progress(vpninfo, PRG_INFO, "Requesting SOCKS proxy connection to %s:%d\n", + vpn_progress(vpninfo, PRG_INFO, "Requesting SOCKS proxy connection to %s:%d\n", vpninfo->hostname, vpninfo->port); buf[0] = 5; /* SOCKS version */ @@ -958,7 +958,7 @@ static int process_socks_proxy(struct openconnect_info *vpninfo, int ssl_sock) buf[i++] = vpninfo->port & 0xff; if ((i = proxy_write(ssl_sock, buf, i))) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Error writing connect request to SOCKS proxy: %s\n", strerror(-i)); return i; @@ -966,13 +966,13 @@ static int process_socks_proxy(struct openconnect_info *vpninfo, int ssl_sock) /* Read 5 bytes -- up to and including the first byte of the returned address (which might be the length byte of a domain name) */ if ((i = proxy_read(ssl_sock, buf, 5))) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Error reading connect response from SOCKS proxy: %s\n", strerror(-i)); return i; } if (buf[0] != 5) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Unexpected connect response from SOCKS proxy: %02x %02x...\n", buf[0], buf[1]); return -EIO; @@ -992,14 +992,14 @@ static int process_socks_proxy(struct openconnect_info *vpninfo, int ssl_sock) i = 17; break; default: - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Unexpected address type %02x in SOCKS connect response\n", buf[3]); return -EIO; } if ((i = proxy_read(ssl_sock, buf, i))) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Error reading connect response from SOCKS proxy: %s\n", strerror(-i)); return i; @@ -1020,40 +1020,40 @@ static int process_http_proxy(struct openconnect_info *vpninfo, int ssl_sock) sprintf(buf + strlen(buf), "Accept-Encoding: identity\r\n"); sprintf(buf + strlen(buf), "\r\n"); - vpninfo->progress(vpninfo, PRG_INFO, "Requesting HTTP proxy connection to %s:%d\n", + vpn_progress(vpninfo, PRG_INFO, "Requesting HTTP proxy connection to %s:%d\n", vpninfo->hostname, vpninfo->port); if (proxy_write(ssl_sock, (unsigned char *)buf, strlen(buf))) { result = -errno; - vpninfo->progress(vpninfo, PRG_ERR, "Sending proxy request failed: %s\n", + vpn_progress(vpninfo, PRG_ERR, "Sending proxy request failed: %s\n", strerror(errno)); return result; } if (proxy_gets(ssl_sock, buf, sizeof(buf)) < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Error fetching proxy response\n"); + vpn_progress(vpninfo, PRG_ERR, "Error fetching proxy response\n"); return -EIO; } if (strncmp(buf, "HTTP/1.", 7) || (buf[7] != '0' && buf[7] != '1') || buf[8] != ' ' || !(result = atoi(buf+9))) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to parse proxy response '%s'\n", + vpn_progress(vpninfo, PRG_ERR, "Failed to parse proxy response '%s'\n", buf); return -EINVAL; } if (result != 200) { - vpninfo->progress(vpninfo, PRG_ERR, "Proxy CONNECT request failed: %s\n", + vpn_progress(vpninfo, PRG_ERR, "Proxy CONNECT request failed: %s\n", buf); return -EIO; } while ((buflen = proxy_gets(ssl_sock, buf, sizeof(buf)))) { if (buflen < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to read proxy response\n"); + vpn_progress(vpninfo, PRG_ERR, "Failed to read proxy response\n"); return -EIO; } - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Unexpected continuation line after CONNECT response: '%s'\n", buf); } @@ -1070,7 +1070,7 @@ int process_proxy(struct openconnect_info *vpninfo, int ssl_sock) !strcmp(vpninfo->proxy_type, "socks5")) return process_socks_proxy(vpninfo, ssl_sock); - vpninfo->progress(vpninfo, PRG_ERR, "Unknown proxy type '%s'\n", + vpn_progress(vpninfo, PRG_ERR, "Unknown proxy type '%s'\n", vpninfo->proxy_type); return -EIO; } @@ -1097,7 +1097,7 @@ int openconnect_set_http_proxy(struct openconnect_info *vpninfo, char *proxy) strcmp(vpninfo->proxy_type, "http") && strcmp(vpninfo->proxy_type, "socks") && strcmp(vpninfo->proxy_type, "socks5")) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Only http or socks(5) proxies supported\n"); free(vpninfo->proxy_type); vpninfo->proxy_type = NULL; diff --git a/library.c b/library.c index 414ea3ad..0a1b76a2 100644 --- a/library.c +++ b/library.c @@ -24,11 +24,12 @@ #include "openconnect-internal.h" -struct openconnect_info *openconnect_vpninfo_new (char *useragent, - openconnect_validate_peer_cert_fn validate_peer_cert, - openconnect_write_new_config_fn write_new_config, - openconnect_process_auth_form_fn process_auth_form, - openconnect_progress_fn progress) +struct openconnect_info *openconnect_vpninfo_new_with_cbdata (char *useragent, + openconnect_validate_peer_cert_vfn validate_peer_cert, + openconnect_write_new_config_vfn write_new_config, + openconnect_process_auth_form_vfn process_auth_form, + openconnect_progress_vfn progress, + void *privdata) { struct openconnect_info *vpninfo = calloc (sizeof(*vpninfo), 1); @@ -39,10 +40,24 @@ struct openconnect_info *openconnect_vpninfo_new (char *useragent, vpninfo->write_new_config = write_new_config; vpninfo->process_auth_form = process_auth_form; vpninfo->progress = progress; + vpninfo->cbdata = privdata?:vpninfo; return vpninfo; } +struct openconnect_info *openconnect_vpninfo_new (char *useragent, + openconnect_validate_peer_cert_fn validate_peer_cert, + openconnect_write_new_config_fn write_new_config, + openconnect_process_auth_form_fn process_auth_form, + openconnect_progress_fn progress) +{ + return openconnect_vpninfo_new_with_cbdata (useragent, + (void *)validate_peer_cert, + (void *)write_new_config, + (void *)process_auth_form, + (void *)progress, NULL); +} + static void free_optlist (struct vpn_option *opt) { struct vpn_option *next; diff --git a/main.c b/main.c index 30b8bd52..38c51bf7 100644 --- a/main.c +++ b/main.c @@ -46,10 +46,14 @@ #include "openconnect-internal.h" -static int write_new_config(struct openconnect_info *vpninfo, char *buf, int buflen); -static void write_progress(struct openconnect_info *info, int level, const char *fmt, ...); -static void syslog_progress(struct openconnect_info *info, int level, const char *fmt, ...); -static int validate_peer_cert(struct openconnect_info *info, X509 *peer_cert, const char *reason); +static int write_new_config(void *_vpninfo, + char *buf, int buflen); +static void write_progress(void *_vpninfo, + int level, const char *fmt, ...); +static void syslog_progress(void *_vpninfo, + int level, const char *fmt, ...); +static int validate_peer_cert(void *_vpninfo, + X509 *peer_cert, const char *reason); int verbose = PRG_INFO; int background; @@ -245,6 +249,7 @@ int main(int argc, char **argv) vpninfo->uid_csd = 0; vpninfo->uid_csd_given = 0; vpninfo->validate_peer_cert = validate_peer_cert; + vpninfo->cbdata = vpninfo; if (!uname(&utsbuf)) vpninfo->localname = utsbuf.nodename; @@ -545,7 +550,7 @@ int main(int argc, char **argv) if (vpninfo->dtls_attempt_period && setup_dtls(vpninfo)) fprintf(stderr, "Set up DTLS failed; using SSL instead\n"); - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "Connected %s as %s%s%s, using %s\n", vpninfo->ifname, vpninfo->vpn_addr?:"", (vpninfo->vpn_addr6 && vpninfo->vpn_addr)?" + ":"", @@ -555,13 +560,13 @@ int main(int argc, char **argv) : "DTLS"); if (!vpninfo->vpnc_script) - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "No --script argument provided; DNS and routing are not configured\n"); if (background) { int pid; if ((pid = fork())) { - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "Continuing in background; pid %d\n", pid); exit(0); @@ -571,8 +576,9 @@ int main(int argc, char **argv) exit(1); } -static int write_new_config(struct openconnect_info *vpninfo, char *buf, int buflen) +static int write_new_config(void *_vpninfo, char *buf, int buflen) { + struct openconnect_info *vpninfo = _vpninfo; int config_fd; int err; @@ -596,7 +602,7 @@ static int write_new_config(struct openconnect_info *vpninfo, char *buf, int buf return 0; } -void write_progress(struct openconnect_info *info, int level, const char *fmt, ...) +void write_progress(void *_vpninfo, int level, const char *fmt, ...) { FILE *outf = level ? stdout : stderr; va_list args; @@ -608,8 +614,7 @@ void write_progress(struct openconnect_info *info, int level, const char *fmt, . } } -void syslog_progress(struct openconnect_info *info, int level, - const char *fmt, ...) +void syslog_progress(void *_vpninfo, int level, const char *fmt, ...) { int priority = level ? LOG_INFO : LOG_NOTICE; va_list args; @@ -628,9 +633,10 @@ struct accepted_cert { char host[0]; } *accepted_certs; -static int validate_peer_cert(struct openconnect_info *vpninfo, X509 *peer_cert, +static int validate_peer_cert(void *_vpninfo, X509 *peer_cert, const char *reason) { + struct openconnect_info *vpninfo = _vpninfo; char fingerprint[EVP_MAX_MD_SIZE * 2 + 1]; struct accepted_cert *this; int ret; diff --git a/mainloop.c b/mainloop.c index 55c472a1..c4baf468 100644 --- a/mainloop.c +++ b/mainloop.c @@ -86,7 +86,7 @@ int vpn_mainloop(struct openconnect_info *vpninfo) if (vpninfo->dtls_attempt_period && !vpninfo->dtls_ssl && !vpninfo->new_dtls_ssl && vpninfo->new_dtls_started + vpninfo->dtls_attempt_period < time(NULL)) { - vpninfo->progress(vpninfo, PRG_TRACE, "Attempt new DTLS connection\n"); + vpn_progress(vpninfo, PRG_TRACE, "Attempt new DTLS connection\n"); connect_dtls_socket(vpninfo); } if (vpninfo->dtls_ssl) @@ -118,7 +118,7 @@ int vpn_mainloop(struct openconnect_info *vpninfo) if (did_work) continue; - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "No work to do; sleeping for %d ms...\n", timeout); memcpy(&rfds, &vpninfo->select_rfds, sizeof(rfds)); memcpy(&wfds, &vpninfo->select_wfds, sizeof(wfds)); diff --git a/openconnect-internal.h b/openconnect-internal.h index 94cf4e58..bddc9a11 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -203,12 +203,11 @@ struct openconnect_info { char *quit_reason; - int (*validate_peer_cert) (struct openconnect_info *vpninfo, X509 *cert, const char *reason); - int (*write_new_config) (struct openconnect_info *vpninfo, char *buf, int buflen); - int (*process_auth_form) (struct openconnect_info *vpninfo, struct oc_auth_form *form); - - void __attribute__ ((format(printf, 3, 4))) - (*progress) (struct openconnect_info *vpninfo, int level, const char *fmt, ...); + void *cbdata; + openconnect_validate_peer_cert_vfn validate_peer_cert; + openconnect_write_new_config_vfn write_new_config; + openconnect_process_auth_form_vfn process_auth_form; + openconnect_progress_vfn progress; }; /* Packet types */ @@ -228,6 +227,8 @@ struct openconnect_info { #define method_const #endif +#define vpn_progress(vpninfo, ...) (vpninfo)->progress ((vpninfo)->cbdata, __VA_ARGS__) + /****************************************************************************/ /* tun.c */ diff --git a/openconnect.h b/openconnect.h index e5dc9f8b..d4930d1c 100644 --- a/openconnect.h +++ b/openconnect.h @@ -31,9 +31,12 @@ #include #define OPENCONNECT_API_VERSION_MAJOR 1 -#define OPENCONNECT_API_VERSION_MINOR 1 +#define OPENCONNECT_API_VERSION_MINOR 2 /* + * API version 1.2: + * - Add openconnect_vpninfo_new_with_cbdata() + * * API version 1.1: * - Add openconnect_vpninfo_free() * @@ -132,21 +135,42 @@ void openconnect_reset_ssl (struct openconnect_info *vpninfo); int openconnect_parse_url (struct openconnect_info *vpninfo, char *url); const char *openconnect_get_version(void); -typedef int (*openconnect_validate_peer_cert_fn) (struct openconnect_info *vpninfo, - struct x509_st *cert, const char *reason); -typedef int (*openconnect_write_new_config_fn) (struct openconnect_info *vpninfo, char *buf, +/* The first (privdata) argument to each of these functions is either + the privdata argument provided to openconnect_vpninfo_new(), or + if that argument was NULL then it'll be the vpninfo itself. */ +typedef int (*openconnect_validate_peer_cert_vfn) (void *privdata, + struct x509_st *cert, + const char *reason); +typedef int (*openconnect_write_new_config_vfn) (void *privdata, char *buf, + int buflen); +typedef int (*openconnect_process_auth_form_vfn) (void *privdata, + struct oc_auth_form *form); +typedef void __attribute__ ((format(printf, 3, 4))) + (*openconnect_progress_vfn) (void *privdata, int level, + const char *fmt, ...); + +typedef int (*openconnect_validate_peer_cert_fn) (struct openconnect_info *, + struct x509_st *cert, + const char *reason); +typedef int (*openconnect_write_new_config_fn) (struct openconnect_info *, char *buf, int buflen); -typedef int (*openconnect_process_auth_form_fn) (struct openconnect_info *vpninfo, +typedef int (*openconnect_process_auth_form_fn) (struct openconnect_info *, struct oc_auth_form *form); typedef void __attribute__ ((format(printf, 3, 4))) - (*openconnect_progress_fn) (struct openconnect_info *vpninfo, int level, - const char *fmt, ...); + (*openconnect_progress_fn) (struct openconnect_info *, int level, + const char *fmt, ...); struct openconnect_info *openconnect_vpninfo_new (char *useragent, openconnect_validate_peer_cert_fn, openconnect_write_new_config_fn, openconnect_process_auth_form_fn, openconnect_progress_fn); +struct openconnect_info *openconnect_vpninfo_new_with_cbdata (char *useragent, + openconnect_validate_peer_cert_vfn, + openconnect_write_new_config_vfn, + openconnect_process_auth_form_vfn, + openconnect_progress_vfn, + void *privdata); void openconnect_vpninfo_free (struct openconnect_info *vpninfo); #endif /* __OPENCONNECT_H__ */ diff --git a/ssl.c b/ssl.c index a173016f..f9bcc1c2 100644 --- a/ssl.c +++ b/ssl.c @@ -78,7 +78,7 @@ static int print_err(const char *str, size_t len, void *ptr) { struct openconnect_info *vpninfo = ptr; - vpninfo->progress(vpninfo, PRG_ERR, "%s", str); + vpn_progress(vpninfo, PRG_ERR, "%s", str); return 0; } @@ -127,7 +127,7 @@ static int pem_pw_cb(char *buf, int len, int w, void *v) SSL_CTX_set_default_passwd_cb_userdata(vpninfo->https_ctx, NULL); if (len <= strlen(vpninfo->cert_password)) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "PEM password too long (%zd >= %d)\n", strlen(vpninfo->cert_password), len); return -1; @@ -163,12 +163,12 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12 if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 && ERR_GET_FUNC(err) == PKCS12_F_PKCS12_PARSE && ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) { - vpninfo->progress(vpninfo, PRG_ERR, "Parse PKCS#12 failed (wrong passphrase?)\n"); + vpn_progress(vpninfo, PRG_ERR, "Parse PKCS#12 failed (wrong passphrase?)\n"); vpninfo->cert_password = NULL; goto retrypass; } - vpninfo->progress(vpninfo, PRG_ERR, "Parse PKCS#12 failed (see above errors)\n"); + vpn_progress(vpninfo, PRG_ERR, "Parse PKCS#12 failed (see above errors)\n"); PKCS12_free(p12); return -EINVAL; } @@ -176,7 +176,7 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12 vpninfo->cert_x509 = cert; SSL_CTX_use_certificate(vpninfo->https_ctx, cert); } else { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "PKCS#12 contained no certificate!"); ret = -EINVAL; } @@ -185,7 +185,7 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12 SSL_CTX_use_PrivateKey(vpninfo->https_ctx, pkey); EVP_PKEY_free(pkey); } else { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "PKCS#12 contained no private key!"); ret = -EINVAL; } @@ -204,7 +204,7 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12 X509_NAME_oneline(X509_get_subject_name(cert2), buf, sizeof(buf)); - vpninfo->progress(vpninfo, PRG_DEBUG, + vpn_progress(vpninfo, PRG_DEBUG, "Extra cert from PKCS#12: '%s'\n", buf); CRYPTO_add(&cert2->references, 1, CRYPTO_LOCK_X509); SSL_CTX_add_extra_chain_cert(vpninfo->https_ctx, cert2); @@ -227,13 +227,13 @@ static int load_tpm_certificate(struct openconnect_info *vpninfo) e = ENGINE_by_id("tpm"); if (!e) { - vpninfo->progress(vpninfo, PRG_ERR, "Can't load TPM engine.\n"); + vpn_progress(vpninfo, PRG_ERR, "Can't load TPM engine.\n"); report_ssl_errors(vpninfo); return -EINVAL; } if (!ENGINE_init(e) || !ENGINE_set_default_RSA(e) || !ENGINE_set_default_RAND(e)) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to init TPM engine\n"); + vpn_progress(vpninfo, PRG_ERR, "Failed to init TPM engine\n"); report_ssl_errors(vpninfo); ENGINE_free(e); return -EINVAL; @@ -242,13 +242,13 @@ static int load_tpm_certificate(struct openconnect_info *vpninfo) if (vpninfo->cert_password) { if (!ENGINE_ctrl_cmd(e, "PIN", strlen(vpninfo->cert_password), vpninfo->cert_password, NULL, 0)) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to set TPM SRK password\n"); + vpn_progress(vpninfo, PRG_ERR, "Failed to set TPM SRK password\n"); report_ssl_errors(vpninfo); } } key = ENGINE_load_private_key(e, vpninfo->sslkey, NULL, NULL); if (!key) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Failed to load TPM private key\n"); report_ssl_errors(vpninfo); ENGINE_free(e); @@ -256,7 +256,7 @@ static int load_tpm_certificate(struct openconnect_info *vpninfo) return -EINVAL; } if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) { - vpninfo->progress(vpninfo, PRG_ERR, "Add key from TPM failed\n"); + vpn_progress(vpninfo, PRG_ERR, "Add key from TPM failed\n"); report_ssl_errors(vpninfo); ENGINE_free(e); ENGINE_finish(e); @@ -275,7 +275,7 @@ static int reload_pem_cert(struct openconnect_info *vpninfo) if (BIO_read_filename(b, vpninfo->cert) <= 0) { err: BIO_free(b); - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Failed to reload X509 cert for expiry check\n"); report_ssl_errors(vpninfo); return -EIO; @@ -289,7 +289,7 @@ static int reload_pem_cert(struct openconnect_info *vpninfo) static int load_certificate(struct openconnect_info *vpninfo) { - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Using certificate file %s\n", vpninfo->cert); if (vpninfo->cert_type == CERT_TYPE_PKCS12 || @@ -299,7 +299,7 @@ static int load_certificate(struct openconnect_info *vpninfo) f = fopen(vpninfo->cert, "r"); if (!f) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Failed to open certificate file %s: %s\n", vpninfo->cert, strerror(errno)); return -ENOENT; @@ -311,7 +311,7 @@ static int load_certificate(struct openconnect_info *vpninfo) /* Not PKCS#12 */ if (vpninfo->cert_type == CERT_TYPE_PKCS12) { - vpninfo->progress(vpninfo, PRG_ERR, "Read PKCS#12 failed\n"); + vpn_progress(vpninfo, PRG_ERR, "Read PKCS#12 failed\n"); report_ssl_errors(vpninfo); return -EINVAL; } @@ -322,7 +322,7 @@ static int load_certificate(struct openconnect_info *vpninfo) /* It's PEM or TPM now, and either way we need to load the plain cert: */ if (!SSL_CTX_use_certificate_chain_file(vpninfo->https_ctx, vpninfo->cert)) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Loading certificate failed\n"); report_ssl_errors(vpninfo); return -EINVAL; @@ -336,7 +336,7 @@ static int load_certificate(struct openconnect_info *vpninfo) char buf[256]; if (!f) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Failed to open private key file %s: %s\n", vpninfo->cert, strerror(errno)); return -ENOENT; @@ -356,7 +356,7 @@ static int load_certificate(struct openconnect_info *vpninfo) } fclose(f); if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Failed to identify private key type in '%s'\n", vpninfo->sslkey); return -EINVAL; @@ -387,11 +387,11 @@ static int load_certificate(struct openconnect_info *vpninfo) if (ERR_GET_LIB(err) == ERR_LIB_EVP && ERR_GET_FUNC(err) == EVP_F_EVP_DECRYPTFINAL_EX && ERR_GET_REASON(err) == EVP_R_BAD_DECRYPT) { - vpninfo->progress(vpninfo, PRG_ERR, "Loading private key failed (wrong passphrase?)\n"); + vpn_progress(vpninfo, PRG_ERR, "Loading private key failed (wrong passphrase?)\n"); goto again; } - vpninfo->progress(vpninfo, PRG_ERR, "Loading private key failed (see above errors)\n"); + vpn_progress(vpninfo, PRG_ERR, "Loading private key failed (see above errors)\n"); return -EINVAL; } return 0; @@ -435,7 +435,7 @@ static int check_server_cert(struct openconnect_info *vpninfo, X509 *cert) return ret; if (strcasecmp(vpninfo->servercert, fingerprint)) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Server SSL certificate didn't match: %s\n", fingerprint); return -EINVAL; } @@ -548,14 +548,14 @@ int match_cert_hostname(struct openconnect_info *vpninfo, X509 *peer_cert) continue; if (!match_hostname(vpninfo->hostname, str)) { - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Matched DNS altname '%s'\n", str); GENERAL_NAMES_free(altnames); OPENSSL_free(str); return 0; } else { - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "No match for altname '%s'\n", str); } @@ -569,7 +569,7 @@ int match_cert_hostname(struct openconnect_info *vpninfo, X509 *peer_cert) } else if (this->d.ip->length == 16) { family = AF_INET6; } else { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Certificate has GEN_IPADD altname with bogus length %d\n", this->d.ip->length); continue; @@ -580,14 +580,14 @@ int match_cert_hostname(struct openconnect_info *vpninfo, X509 *peer_cert) if (this->d.ip->length == addrlen && !memcmp(addrbuf, this->d.ip->data, addrlen)) { - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Matched IP%s address '%s'\n", (family == AF_INET6)?"v6":"", host); GENERAL_NAMES_free(altnames); return 0; } else { - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "No match for IP%s address '%s'\n", (family == AF_INET6)?"v6":"", host); @@ -629,11 +629,11 @@ int match_cert_hostname(struct openconnect_info *vpninfo, X509 *peer_cert) goto no_uri_match; if (url_path) { - vpninfo->progress(vpninfo, PRG_TRACE, "URI '%s' has non-empty path; ignoring\n", + vpn_progress(vpninfo, PRG_TRACE, "URI '%s' has non-empty path; ignoring\n", str); goto no_uri_match_silent; } - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Matched URI '%s'\n", str); free(url_proto); @@ -644,7 +644,7 @@ int match_cert_hostname(struct openconnect_info *vpninfo, X509 *peer_cert) return 0; no_uri_match: - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "No match for URI '%s'\n", str); no_uri_match_silent: @@ -659,14 +659,14 @@ int match_cert_hostname(struct openconnect_info *vpninfo, X509 *peer_cert) /* According to RFC2818, we don't use the legacy subject name if there was an altname with DNS type. */ if (altdns) { - vpninfo->progress(vpninfo, PRG_ERR, "No altname in peer cert matched '%s'\n", + vpn_progress(vpninfo, PRG_ERR, "No altname in peer cert matched '%s'\n", vpninfo->hostname); return -EINVAL; } subjname = X509_get_subject_name(peer_cert); if (!subjname) { - vpninfo->progress(vpninfo, PRG_ERR, "No subject name in peer cert!\n"); + vpn_progress(vpninfo, PRG_ERR, "No subject name in peer cert!\n"); return -EINVAL; } @@ -685,18 +685,18 @@ int match_cert_hostname(struct openconnect_info *vpninfo, X509 *peer_cert) i = ASN1_STRING_to_UTF8((void *)&subjstr, subjasn1); if (!subjstr || strlen(subjstr) != i) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Failed to parse subject name in peer cert\n"); return -EINVAL; } ret = 0; if (match_hostname(vpninfo->hostname, subjstr)) { - vpninfo->progress(vpninfo, PRG_ERR, "Peer cert subject mismatch ('%s' != '%s')\n", + vpn_progress(vpninfo, PRG_ERR, "Peer cert subject mismatch ('%s' != '%s')\n", subjstr, vpninfo->hostname); ret = -EINVAL; } else { - vpninfo->progress(vpninfo, PRG_TRACE, + vpn_progress(vpninfo, PRG_TRACE, "Matched peer certificate subject name '%s'\n", subjstr); } @@ -726,12 +726,13 @@ static int verify_peer(struct openconnect_info *vpninfo, SSL *https_ssl) err_string = "certificate does not match hostname"; if (err_string) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Server certificate verify failed: %s\n", err_string); if (vpninfo->validate_peer_cert) - ret = vpninfo->validate_peer_cert(vpninfo, peer_cert, + ret = vpninfo->validate_peer_cert(vpninfo->cbdata, + peer_cert, err_string); else ret = -EINVAL; @@ -773,7 +774,7 @@ static void workaround_openssl_certchain_bug(struct openconnect_info *vpninfo, cert = cert2; X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); - vpninfo->progress(vpninfo, PRG_DEBUG, + vpn_progress(vpninfo, PRG_DEBUG, "Extra cert from cafile: '%s'\n", buf); SSL_CTX_add_extra_chain_cert(vpninfo->https_ctx, cert); } @@ -803,7 +804,7 @@ static int check_certificate_expiry(struct openconnect_info *vpninfo) notAfter = X509_get_notAfter(vpninfo->cert_x509); i = X509_cmp_time(notAfter, &t); if (!i) { - vpninfo->progress(vpninfo, PRG_ERR, "Error in client cert notAfter field\n"); + vpn_progress(vpninfo, PRG_ERR, "Error in client cert notAfter field\n"); return -EINVAL; } else if (i < 0) { reason = "has expired"; @@ -826,7 +827,7 @@ static int check_certificate_expiry(struct openconnect_info *vpninfo) BIO_get_mem_ptr(bp, &bm); expiry = bm->data; } - vpninfo->progress(vpninfo, PRG_ERR, "Client certificate %s at: %s\n", + vpn_progress(vpninfo, PRG_ERR, "Client certificate %s at: %s\n", reason, expiry); if (bp) BIO_free(bp); @@ -849,7 +850,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM, IPPROTO_IP); if (ssl_sock < 0) { reconn_err: - vpninfo->progress(vpninfo, PRG_ERR, "Failed to reconnect to %s %s\n", + vpn_progress(vpninfo, PRG_ERR, "Failed to reconnect to %s %s\n", vpninfo->proxy?"proxy":"host", vpninfo->proxy?:vpninfo->hostname); return -EINVAL; @@ -911,7 +912,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) free(url); free(proxies); if (vpninfo->proxy) - vpninfo->progress(vpninfo, PRG_TRACE, "Proxy from libproxy: %s://%s:%d/\n", + vpn_progress(vpninfo, PRG_TRACE, "Proxy from libproxy: %s://%s:%d/\n", vpninfo->proxy_type, vpninfo->proxy, vpninfo->port); } #endif @@ -941,7 +942,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) free(hostname); if (err) { - vpninfo->progress(vpninfo, PRG_ERR, "getaddrinfo failed for host '%s': %s\n", + vpn_progress(vpninfo, PRG_ERR, "getaddrinfo failed for host '%s': %s\n", hostname, gai_strerror(err)); return -EINVAL; } @@ -951,7 +952,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) if (!getnameinfo(rp->ai_addr, rp->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST)) - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "Attempting to connect to %s%s%s:%s\n", rp->ai_family == AF_INET6?"[":"", host, @@ -967,7 +968,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) use it again later */ vpninfo->peer_addr = malloc(rp->ai_addrlen); if (!vpninfo->peer_addr) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to allocate sockaddr storage\n"); + vpn_progress(vpninfo, PRG_ERR, "Failed to allocate sockaddr storage\n"); close(ssl_sock); return -ENOMEM; } @@ -981,7 +982,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) freeaddrinfo(result); if (ssl_sock < 0) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to connect to host %s\n", + vpn_progress(vpninfo, PRG_ERR, "Failed to connect to host %s\n", vpninfo->proxy?:vpninfo->hostname); return -EINVAL; } @@ -1003,7 +1004,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) if (vpninfo->cert) { err = load_certificate(vpninfo); if (err) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Loading certificate failed. Aborting.\n"); return err; } @@ -1026,7 +1027,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) if (vpninfo->cafile) { if (!SSL_CTX_load_verify_locations(vpninfo->https_ctx, vpninfo->cafile, NULL)) { - vpninfo->progress(vpninfo, PRG_ERR, "Failed to open CA file '%s'\n", + vpn_progress(vpninfo, PRG_ERR, "Failed to open CA file '%s'\n", vpninfo->cafile); report_ssl_errors(vpninfo); close(ssl_sock); @@ -1041,11 +1042,11 @@ int openconnect_open_https(struct openconnect_info *vpninfo) https_bio = BIO_new_socket(ssl_sock, BIO_NOCLOSE); SSL_set_bio(https_ssl, https_bio, https_bio); - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "SSL negotiation with %s\n", vpninfo->hostname); if (SSL_connect(https_ssl) <= 0) { - vpninfo->progress(vpninfo, PRG_ERR, "SSL connection failure\n"); + vpn_progress(vpninfo, PRG_ERR, "SSL connection failure\n"); report_ssl_errors(vpninfo); SSL_free(https_ssl); close(ssl_sock); @@ -1061,7 +1062,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) vpninfo->ssl_fd = ssl_sock; vpninfo->https_ssl = https_ssl; - vpninfo->progress(vpninfo, PRG_INFO, + vpn_progress(vpninfo, PRG_INFO, "Connected to HTTPS on %s\n", vpninfo->hostname); return 0; @@ -1093,7 +1094,7 @@ int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo) if (statvfs(vpninfo->sslkey, &buf)) { int err = errno; - vpninfo->progress(vpninfo, PRG_ERR, "statvfs: %s\n", strerror(errno)); + vpn_progress(vpninfo, PRG_ERR, "statvfs: %s\n", strerror(errno)); return -err; } if (asprintf(&vpninfo->cert_password, "%lx", buf.f_fsid)) @@ -1109,7 +1110,7 @@ int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo) if (statfs(vpninfo->sslkey, &buf)) { int err = errno; - vpninfo->progress(vpninfo, PRG_ERR, "statfs: %s\n", strerror(errno)); + vpn_progress(vpninfo, PRG_ERR, "statfs: %s\n", strerror(errno)); return -err; } fsid64 = ((unsigned long long)fsid[0] << 32) | fsid[1]; diff --git a/tun.c b/tun.c index 24747d8d..669b01fc 100644 --- a/tun.c +++ b/tun.c @@ -79,7 +79,7 @@ static int local_config_tun(struct openconnect_info *vpninfo, int mtu_only) { if (!mtu_only) - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "No vpnc-script configured. Need Solaris IP-setting code\n"); return 0; } @@ -153,7 +153,7 @@ static int process_split_xxclude(struct openconnect_info *vpninfo, slash = strchr(route, '/'); if (!slash) { badinc: - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Discard bad split %sclude: \"%s\"\n", in_ex, route); return -EINVAL; @@ -365,7 +365,7 @@ static int script_config_tun(struct openconnect_info *vpninfo) { if (system(vpninfo->vpnc_script)) { int e = errno; - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Failed to spawn script '%s': %s\n", vpninfo->vpnc_script, strerror(e)); return -e; @@ -428,7 +428,7 @@ int setup_tun(struct openconnect_info *vpninfo) if (errno != -ENOENT) tunerr = errno; - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Failed to open tun device: %s\n", strerror(tunerr)); exit(1); @@ -439,7 +439,7 @@ int setup_tun(struct openconnect_info *vpninfo) strncpy(ifr.ifr_name, vpninfo->ifname, sizeof(ifr.ifr_name) - 1); if (ioctl(tun_fd, TUNSETIFF, (void *) &ifr) < 0) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "TUNSETIFF failed: %s\n", strerror(errno)); exit(1); @@ -518,7 +518,7 @@ int setup_tun(struct openconnect_info *vpninfo) return -EIO; } /* Solaris tunctl needs this in order to tear it down */ - vpninfo->progress(vpninfo, PRG_DEBUG, "mux id is %d\n", mux_id); + vpn_progress(vpninfo, PRG_DEBUG, "mux id is %d\n", mux_id); vpninfo->tun_muxid = mux_id; vpninfo->ip_fd = ip_fd; @@ -618,7 +618,7 @@ int tun_mainloop(struct openconnect_info *vpninfo, int *timeout) static int complained = 0; if (!complained) { complained = 1; - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Unknown packet (len %d) received: %02x %02x %02x %02x...\n", len, data[0], data[1], data[2], data[3]); } @@ -651,7 +651,7 @@ void shutdown_tun(struct openconnect_info *vpninfo) if (vpninfo->vpnc_script) { setenv("reason", "disconnect", 1); if (system(vpninfo->vpnc_script) == -1) { - vpninfo->progress(vpninfo, PRG_ERR, + vpn_progress(vpninfo, PRG_ERR, "Failed to spawn script '%s': %s\n", vpninfo->vpnc_script, strerror(errno)); diff --git a/xml.c b/xml.c index 4819ff1b..c2acad92 100644 --- a/xml.c +++ b/xml.c @@ -75,7 +75,7 @@ int config_lookup_host(struct openconnect_info *vpninfo, const char *host) for (i = 0; i < SHA_DIGEST_LENGTH; i++) sprintf(&vpninfo->xmlsha1[i*2], "%02x", sha1[i]); - vpninfo->progress(vpninfo, PRG_TRACE, "XML config file SHA1: %s\n", vpninfo->xmlsha1); + vpn_progress(vpninfo, PRG_TRACE, "XML config file SHA1: %s\n", vpninfo->xmlsha1); xml_doc = xmlReadMemory(xmlfile, st.st_size, "noname.xml", NULL, 0); munmap(xmlfile, st.st_size);