Use progress callback for output
authorDavid Woodhouse <David.Woodhouse@intel.com>
Sun, 5 Oct 2008 15:25:36 +0000 (16:25 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Sun, 5 Oct 2008 15:25:36 +0000 (16:25 +0100)
cstp.c
dtls.c
http.c
main.c
mainloop.c
nm-auth-dialog.c
openconnect.h
ssl.c
tun.c
xml.c

diff --git a/cstp.c b/cstp.c
index 19423a4..9956446 100644 (file)
--- a/cstp.c
+++ b/cstp.c
@@ -96,15 +96,16 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
        openconnect_SSL_printf(vpninfo->https_ssl, "\r\nX-DTLS-CipherSuite: AES256-SHA:AES128-SHA:DES-CBC3-SHA:DES-CBC-SHA\r\n\r\n");
 
        if (openconnect_SSL_gets(vpninfo->https_ssl, buf, 65536) < 0) {
-               fprintf(stderr, "Error fetching HTTPS response\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "Error fetching HTTPS response\n");
                if (!retried) {
                        retried = 1;
                        SSL_free(vpninfo->https_ssl);
                        close(vpninfo->ssl_fd);
                
                        if (openconnect_open_https(vpninfo)) {
-                               fprintf(stderr, "Failed to open HTTPS connection to %s\n",
-                                       vpninfo->hostname);
+                               vpninfo->progress(vpninfo, PRG_ERR,
+                                                 "Failed to open HTTPS connection to %s\n",
+                                                 vpninfo->hostname);
                                exit(1);
                        }
                        goto retry;
@@ -113,16 +114,17 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
        }
 
        if (strncmp(buf, "HTTP/1.1 200 ", 13)) {
-               fprintf(stderr, "Got inappropriate HTTP CONNECT response: %s\n",
-                       buf);
+               vpninfo->progress(vpninfo, PRG_ERR, 
+                                 "Got inappropriate HTTP CONNECT response: %s\n",
+                                 buf);
                if (!strncmp(buf, "HTTP/1.1 401 ", 13))
                        exit(2);
                openconnect_SSL_gets(vpninfo->https_ssl, buf, 65536);
                return -EINVAL;
        }
 
-       if (verbose)
-               printf("Got CONNECT response: %s\n", buf);
+       vpninfo->progress(vpninfo, PRG_INFO,
+                         "Got CONNECT response: %s\n", buf);
 
        /* We may have advertised it, but we only do it if the server agrees */
        vpninfo->deflate = 0;
@@ -144,7 +146,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
 
                new_option = malloc(sizeof(*new_option));
                if (!new_option) {
-                       fprintf(stderr, "No memory for options\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "No memory for options\n");
                        return -ENOMEM;
                }
                new_option->option = strdup(buf);
@@ -152,12 +154,11 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
                new_option->next = NULL;
 
                if (!new_option->option || !new_option->value) {
-                       fprintf(stderr, "No memory for options\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "No memory for options\n");
                        return -ENOMEM;
                }
 
-               if (verbose)
-                       printf("%s: %s\n", buf, colon);
+               vpninfo->progress(vpninfo, PRG_TRACE, "%s: %s\n", buf, colon);
 
                if (!strncmp(buf, "X-DTLS-", 7)) {
                        *next_dtls_option = new_option;
@@ -177,7 +178,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
                        if (!strcmp(colon, "deflate"))
                                vpninfo->deflate = 1;
                        else {
-                               fprintf(stderr
+                               vpninfo->progress(vpninfo, PRG_ERR
                                        "Unknown CSTP-Content-Encoding %s\n",
                                        colon);
                                return -EINVAL;
@@ -210,21 +211,21 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
        }
 
        if (!vpninfo->vpn_addr) {
-               fprintf(stderr, "No IP address received. Aborting\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "No IP address received. Aborting\n");
                return -EINVAL;
        }
        if (!vpninfo->vpn_netmask)
                vpninfo->vpn_netmask = "255.255.255.255";
        if (old_addr) {
                if (strcmp(old_addr, vpninfo->vpn_addr)) {
-                       fprintf(stderr, "Reconnect gave different IP address (%s != %s)\n",
+                       vpninfo->progress(vpninfo, PRG_ERR, "Reconnect gave different IP address (%s != %s)\n",
                                vpninfo->vpn_addr, old_addr);
                        return -EINVAL;
                }
        }
        if (old_netmask) {
                if (strcmp(old_netmask, vpninfo->vpn_netmask)) {
-                       fprintf(stderr, "Reconnect gave different netmask (%s != %s)\n",
+                       vpninfo->progress(vpninfo, PRG_ERR, "Reconnect gave different netmask (%s != %s)\n",
                                vpninfo->vpn_netmask, old_netmask);
                        return -EINVAL;
                }
@@ -244,9 +245,8 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
                free(tmp->option);
                free(tmp);
        }
-       if (verbose)
-               printf("CSTP connected. DPD %d, Keepalive %d\n",
-                      vpninfo->ssl_times.dpd, vpninfo->ssl_times.keepalive);
+       vpninfo->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);
        BIO_set_nbio(SSL_get_wbio(vpninfo->https_ssl),1);
@@ -271,14 +271,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)) {
-                       fprintf(stderr, "Compression setup failed\n");
+                       vpninfo->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) {
-                               fprintf(stderr, "Allocation of deflate buffer failed\n");
+                               vpninfo->progress(vpninfo, PRG_ERR, "Allocation of deflate buffer failed\n");
                                vpninfo->deflate = 0;
                        }
                        memset(vpninfo->deflate_pkt, 0, sizeof(struct pkt));
@@ -312,7 +312,7 @@ static int inflate_and_queue_packet(struct openconnect_info *vpninfo, int type,
        vpninfo->inflate_strm.total_out = 0;
 
        if (inflate(&vpninfo->inflate_strm, Z_SYNC_FLUSH)) {
-               fprintf(stderr, "inflate failed\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "inflate failed\n");
                free(new);
                return -EINVAL;
        }
@@ -326,10 +326,9 @@ static int inflate_and_queue_packet(struct openconnect_info *vpninfo, int type,
                vpninfo->quit_reason = "Compression (inflate) adler32 failure";
        }
 
-       if (verbose) {
-               printf("Received compressed data packet of %ld bytes\n",
-                      vpninfo->inflate_strm.total_out);
-       }
+       vpninfo->progress(vpninfo, PRG_TRACE,
+                         "Received compressed data packet of %ld bytes\n",
+                         vpninfo->inflate_strm.total_out);
 
        queue_packet(&vpninfo->incoming_queue, new);
        return 0;
@@ -356,36 +355,37 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
 
                payload_len = (buf[4] << 8) + buf[5];
                if (len != 8 + payload_len) {
-                       printf("Unexpected packet length. SSL_read returned %d but packet is\n",
-                              len);
-                       printf("%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]);
+                       vpninfo->progress(vpninfo, PRG_ERR,
+                                         "Unexpected packet length. SSL_read returned %d but packet is\n",
+                                         len);
+                       vpninfo->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]);
                        continue;
                }
                vpninfo->ssl_times.last_rx = time(NULL);
                switch(buf[6]) {
                case AC_PKT_DPD_OUT:
-                       if (verbose)
-                               printf("Got CSTP DPD request\n");
+                       vpninfo->progress(vpninfo, PRG_TRACE,
+                                         "Got CSTP DPD request\n");
                        vpninfo->owe_ssl_dpd_response = 1;
                        continue;
 
                case AC_PKT_DPD_RESP:
-                       if (verbose)
-                               printf("Got CSTP DPD response\n");
+                       vpninfo->progress(vpninfo, PRG_TRACE,
+                                         "Got CSTP DPD response\n");
                        continue;
 
                case AC_PKT_KEEPALIVE:
-                       if (verbose)
-                               printf("Got CSTP Keepalive\n");
+                       vpninfo->progress(vpninfo, PRG_TRACE,
+                                         "Got CSTP Keepalive\n");
                        continue;
 
                case AC_PKT_DATA:
-                       if (verbose) {
-                               printf("Received uncompressed data packet of %d bytes\n",
-                                      payload_len);
-                       }
+                       vpninfo->progress(vpninfo, PRG_TRACE,
+                                         "Received uncompressed data packet of %d bytes\n",
+                                         payload_len);
                        queue_new_packet(&vpninfo->incoming_queue, AF_INET, buf + 8,
                                         payload_len);
                        work_done = 1;
@@ -393,7 +393,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
 
                case AC_PKT_COMPRESSED:
                        if (!vpninfo->deflate) {
-                               fprintf(stderr, "Compressed packet received in !deflate mode\n");
+                               vpninfo->progress(vpninfo, PRG_ERR, "Compressed packet received in !deflate mode\n");
                                goto unknown_pkt;
                        }
                        inflate_and_queue_packet(vpninfo, AF_INET, buf + 8, payload_len);
@@ -401,15 +401,16 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
                        continue;
 
                case AC_PKT_TERM_SERVER:
-                       fprintf(stderr, "received server terminate packet\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "received server terminate packet\n");
                        vpninfo->quit_reason = "Server request";
                        return 1;
                }
 
        unknown_pkt:
-               printf("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]);
+               vpninfo->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]);
                vpninfo->quit_reason = "Unknown packet received";
                return 1;
        }
@@ -437,14 +438,14 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
                                        goto peer_dead;
                                return work_done;
                        default:
-                               fprintf(stderr, "SSL_write failed: %d", ret);
+                               vpninfo->progress(vpninfo, PRG_ERR, "SSL_write failed: %d", ret);
                                ERR_print_errors_fp(stderr);
                                vpninfo->quit_reason = "SSL write error";
                                return 1;
                        }
                }
                if (ret != vpninfo->current_ssl_pkt->len + 8) {
-                       fprintf(stderr, "SSL wrote too few bytes! Asked for %d, sent %d\n",
+                       vpninfo->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;
@@ -469,14 +470,14 @@ 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. */
-               fprintf(stderr, "CSTP rekey due but we don't know how\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "CSTP rekey due but we don't know how\n");
                time(&vpninfo->ssl_times.last_rekey);
                work_done = 1;
                break;
 
        case KA_DPD_DEAD:
        peer_dead:
-               fprintf(stderr, "CSTP Dead Peer Detection detected dead peer!\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "CSTP Dead Peer Detection detected dead peer!\n");
                SSL_free(vpninfo->https_ssl);
                vpninfo->https_ssl = NULL;
                close(vpninfo->ssl_fd);
@@ -487,7 +488,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
                        vpninfo->current_ssl_pkt = NULL;
 
                if (make_cstp_connection(vpninfo)) {
-                       fprintf(stderr, "Reconnect failed\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "Reconnect failed\n");
                        vpninfo->quit_reason = "SSL DPD detected dead peer; reconnect failed";
                        return 1;
                }
@@ -496,8 +497,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
                return 1;
 
        case KA_DPD:
-               if (verbose)
-                       printf("Send CSTP DPD\n");
+               vpninfo->progress(vpninfo, PRG_TRACE, "Send CSTP DPD\n");
 
                vpninfo->current_ssl_pkt = &dpd_pkt;
                goto handle_outgoing;
@@ -508,8 +508,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
                if (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue)
                        break;
 
-               if (verbose)
-                       printf("Send CSTP Keepalive\n");
+               vpninfo->progress(vpninfo, PRG_TRACE, "Send CSTP Keepalive\n");
 
                vpninfo->current_ssl_pkt = &keepalive_pkt;
                goto handle_outgoing;
@@ -535,7 +534,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
 
                        ret = deflate(&vpninfo->deflate_strm, Z_SYNC_FLUSH);
                        if (ret) {
-                               fprintf(stderr, "deflate failed %d\n", ret);
+                               vpninfo->progress(vpninfo, PRG_ERR, "deflate failed %d\n", ret);
                                goto uncompr;
                        }
 
@@ -554,10 +553,10 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
 
                        vpninfo->deflate_pkt->len = vpninfo->deflate_strm.total_out + 4;
 
-                       if (verbose) {
-                               printf("Sending compressed data packet of %d bytes\n",
-                                      this->len);
-                       }
+                       vpninfo->progress(vpninfo, PRG_TRACE,
+                                         "Sending compressed data packet of %d bytes\n",
+                                         this->len);
+
                        vpninfo->current_ssl_pkt = vpninfo->deflate_pkt;
                } else {
                uncompr:
@@ -565,10 +564,10 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
                        this->hdr[4] = this->len >> 8;
                        this->hdr[5] = this->len & 0xff;
 
-                       if (verbose) {
-                               printf("Sending uncompressed data packet of %d bytes\n",
-                                      this->len);
-                       }
+                       vpninfo->progress(vpninfo, PRG_TRACE,
+                                         "Sending uncompressed data packet of %d bytes\n",
+                                         this->len);
+
                        vpninfo->current_ssl_pkt = this;
                }
                goto handle_outgoing;
@@ -596,8 +595,8 @@ int cstp_bye(struct openconnect_info *vpninfo, char *reason)
        SSL_write(vpninfo->https_ssl, bye_pkt, reason_len + 8);
        free(bye_pkt);
 
-       if (verbose)
-               printf("Send BYE packet: %s\n", reason);
+       vpninfo->progress(vpninfo, PRG_TRACE,
+                         "Send BYE packet: %s\n", reason);
 
        return 0;
 }
diff --git a/dtls.c b/dtls.c
index 516a366..f1bd899 100644 (file)
--- a/dtls.c
+++ b/dtls.c
@@ -98,7 +98,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) {
-                       fprintf(stderr, "Initialise DTLSv1 CTX failed\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "Initialise DTLSv1 CTX failed\n");
                        return -EINVAL;
                }
 
@@ -111,7 +111,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) {
-                       fprintf(stderr, "Initialise DTLSv1 session failed\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "Initialise DTLSv1 session failed\n");
                        return -EINVAL;
                }                       
                vpninfo->dtls_session->ssl_version = 0x0100; // DTLS1_BAD_VER
@@ -134,11 +134,12 @@ int connect_dtls_socket(struct openconnect_info *vpninfo)
 
        /* Add the generated session to the SSL */
        if (!SSL_set_session(dtls_ssl, vpninfo->dtls_session)) {
-               printf("SSL_set_session() failed with old protocol version 0x%x\n",
-                      vpninfo->dtls_session->ssl_version);
-               printf("Your OpenSSL may lack Cisco compatibility support\n");
-               printf("See http://rt.openssl.org/Ticket/Display.html?id=1751\n");
-               printf("Use the --no-dtls command line option to avoid this message\n");
+               vpninfo->progress(vpninfo, PRG_ERR,
+                                 "SSL_set_session() failed with old protocol version 0x%x\n"
+                                 "Your OpenSSL may lack Cisco compatibility support\n"
+                                 "See http://rt.openssl.org/Ticket/Display.html?id=1751\n"
+                                 "Use the --no-dtls command line option to avoid this message\n",
+                                 vpninfo->dtls_session->ssl_version);
                return -EINVAL;
        }
 
@@ -174,7 +175,7 @@ int dtls_try_handshake(struct openconnect_info *vpninfo)
        int ret = SSL_do_handshake(vpninfo->new_dtls_ssl);
 
        if (ret == 1) {
-               printf("Established DTLS connection\n");
+               vpninfo->progress(vpninfo, PRG_INFO, "Established DTLS connection\n");
 
                vpninfo->dtls_state = DTLS_RUNNING;
 
@@ -201,13 +202,12 @@ 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;
-               if (verbose)
-                       printf("DTLS handshake timed out\n");
-       } else if (verbose) {
-               fprintf(stderr, "DTLS handshake failed: %d\n", ret);
-               ERR_print_errors_fp(stderr);
+               vpninfo->progress(vpninfo, PRG_TRACE, "DTLS handshake timed out\n");
        }
 
+       vpninfo->progress(vpninfo, PRG_ERR, "DTLS handshake failed: %d\n", ret);
+       ERR_print_errors_fp(stderr);
+
        /* Kill the new (failed) connection... */
        SSL_free(vpninfo->new_dtls_ssl);
        vpninfo->pfds[vpninfo->new_dtls_pfd].fd = -1;
@@ -252,13 +252,14 @@ int setup_dtls(struct openconnect_info *vpninfo)
        int i;
 
        while (dtls_opt) {
-               if (verbose)
-                       printf("DTLS option %s : %s\n", dtls_opt->option, dtls_opt->value);
+               vpninfo->progress(vpninfo, PRG_TRACE,
+                                 "DTLS option %s : %s\n",
+                                 dtls_opt->option, dtls_opt->value);
 
                if (!strcmp(dtls_opt->option, "X-DTLS-Session-ID")) {
                        if (strlen(dtls_opt->value) != 64) {
-                               fprintf(stderr, "X-DTLS-Session-ID not 64 characters\n");
-                               fprintf(stderr, "Is: %s\n", dtls_opt->value);
+                               vpninfo->progress(vpninfo, PRG_ERR, "X-DTLS-Session-ID not 64 characters\n");
+                               vpninfo->progress(vpninfo, PRG_ERR, "Is: %s\n", dtls_opt->value);
                                return -EINVAL;
                        }
                        for (i = 0; i < 64; i += 2)
@@ -286,7 +287,7 @@ int setup_dtls(struct openconnect_info *vpninfo)
                struct sockaddr_in6 *sin = (void *)vpninfo->peer_addr;
                sin->sin6_port = htons(dtls_port);
        } else {
-               fprintf(stderr, "Unknown protocol family %d. Cannot do DTLS\n",
+               vpninfo->progress(vpninfo, PRG_ERR, "Unknown protocol family %d. Cannot do DTLS\n",
                        vpninfo->peer_addr->sa_family);
                return -EINVAL;
        }
@@ -299,9 +300,9 @@ int setup_dtls(struct openconnect_info *vpninfo)
        if (connect_dtls_socket(vpninfo))
                return -EINVAL;
 
-       if (verbose)
-               printf("DTLS connected. DPD %d, Keepalive %d\n",
-                      vpninfo->dtls_times.dpd, vpninfo->dtls_times.keepalive);
+       vpninfo->progress(vpninfo, PRG_TRACE,
+                         "DTLS connected. DPD %d, Keepalive %d\n",
+                         vpninfo->dtls_times.dpd, vpninfo->dtls_times.keepalive);
 
        return 0;
 }
@@ -314,9 +315,10 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
        char magic_pkt;
 
        while ( (len = SSL_read(vpninfo->dtls_ssl, buf, sizeof(buf))) > 0 ) {
-               if (verbose)
-                       printf("Received DTLS packet 0x%02x of %d bytes\n",
-                              buf[0], len);
+
+               vpninfo->progress(vpninfo, PRG_TRACE,
+                                 "Received DTLS packet 0x%02x of %d bytes\n",
+                                 buf[0], len);
 
                vpninfo->dtls_times.last_rx = time(NULL);
 
@@ -327,23 +329,20 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
                        break;
 
                case AC_PKT_DPD_OUT:
-                       if (verbose)
-                               printf("Got DTLS DPD request\n");
+                       vpninfo->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)
-                               fprintf(stderr, "Failed to send DPD response. Expect disconnect\n");
+                               vpninfo->progress(vpninfo, PRG_ERR, "Failed to send DPD response. Expect disconnect\n");
                        continue;
 
                case AC_PKT_DPD_RESP:
-                       if (verbose)
-                               printf("Got DTLS DPD response\n");
+                       vpninfo->progress(vpninfo, PRG_TRACE, "Got DTLS DPD response\n");
                        break;
 
                case AC_PKT_KEEPALIVE:
-                       if (verbose)
-                               printf("Got DTLS Keepalive\n");
+                       vpninfo->progress(vpninfo, PRG_TRACE, "Got DTLS Keepalive\n");
                        break;
 
                default:
@@ -352,7 +351,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
                         * by downloading a reasonably-sized web page. Dropping the 
                         * offending packets doesn't even seem to stall the TCP 
                         * connection when it's the only traffic on the link. */
-                       fprintf(stderr, "Unknown DTLS packet type %02x, len %d\n", buf[0], len);
+                       vpninfo->progress(vpninfo, PRG_ERR, "Unknown DTLS packet type %02x, len %d\n", buf[0], len);
                        break;
 /*                     
                        vpninfo->quit_reason = "Unknown packet received";
@@ -364,10 +363,9 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
        switch (keepalive_action(&vpninfo->dtls_times, timeout)) {
        case KA_REKEY:
                time(&vpninfo->dtls_times.last_rekey);
-               if (verbose)
-                       printf("DTLS rekey due\n");
+               vpninfo->progress(vpninfo, PRG_TRACE, "DTLS rekey due\n");
                if (connect_dtls_socket(vpninfo)) {
-                       fprintf(stderr, "DTLS rekey failed\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "DTLS rekey failed\n");
                        return 1;
                }
                work_done = 1;
@@ -375,14 +373,13 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
 
 
        case KA_DPD_DEAD:
-               fprintf(stderr, "DTLS Dead Peer Detection detected dead peer!\n");
+               vpninfo->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:
-               if (verbose)
-                       printf("Send DTLS DPD\n");
+               vpninfo->progress(vpninfo, PRG_TRACE, "Send DTLS DPD\n");
 
                magic_pkt = AC_PKT_DPD_OUT;
                SSL_write(vpninfo->dtls_ssl, &magic_pkt, 1);
@@ -397,8 +394,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
                if (vpninfo->outgoing_queue)
                        break;
 
-               if (verbose)
-                       printf("Send DTLS Keepalive\n");
+               vpninfo->progress(vpninfo, PRG_TRACE, "Send DTLS Keepalive\n");
 
                magic_pkt = AC_PKT_KEEPALIVE;
                SSL_write(vpninfo->dtls_ssl, &magic_pkt, 1);
@@ -427,7 +423,8 @@ 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) {
-                               fprintf(stderr, "DTLS got write error %d. Falling back to SSL\n", ret);
+                               vpninfo->progress(vpninfo, PRG_ERR, 
+                                                 "DTLS got write error %d. Falling back to SSL\n", ret);
                                ERR_print_errors_fp(stderr);
                                dtls_restart(vpninfo);
                                vpninfo->outgoing_queue = this;
@@ -435,10 +432,9 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
                        return 1;
                }
                time(&vpninfo->dtls_times.last_tx);
-               if (verbose) {
-                       printf("Sent DTLS packet of %d bytes; SSL_write() returned %d\n",
-                              this->len, ret);
-               }
+               vpninfo->progress(vpninfo, PRG_TRACE,
+                                 "Sent DTLS packet of %d bytes; SSL_write() returned %d\n",
+                                 this->len, ret);
        }
 
        return work_done;
diff --git a/http.c b/http.c
index b49f2d5..dbf32c9 100644 (file)
--- a/http.c
+++ b/http.c
@@ -56,7 +56,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
        int i;
 
        if (openconnect_SSL_gets(vpninfo->https_ssl, buf, sizeof(buf)) < 0) {
-               fprintf(stderr, "Error fetching HTTPS response\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "Error fetching HTTPS response\n");
                exit(1);
        }
 
@@ -67,26 +67,25 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
        }
 
        if ((!http10 && strncmp(buf, "HTTP/1.1 ", 9)) || !(*result = atoi(buf+9))) {
-               fprintf(stderr, "Failed to parse HTTP response '%s'\n", buf);
+               vpninfo->progress(vpninfo, PRG_ERR, "Failed to parse HTTP response '%s'\n", buf);
                return -EINVAL;
        }
 
-       if (verbose || *result == 100)
-               printf("Got HTTP response: %s\n", buf);
+       vpninfo->progress(vpninfo, PRG_TRACE, "Got HTTP response: %s\n", buf);
 
        /* Eat headers... */
        while ((i=openconnect_SSL_gets(vpninfo->https_ssl, buf, sizeof(buf)))) {
                char *colon;
 
-               if (verbose)
-                       printf("%s\n", buf);
+               vpninfo->progress(vpninfo, PRG_TRACE, "%s\n", buf);
+
                if (i < 0) {
-                       fprintf(stderr, "Error processing HTTP response\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "Error processing HTTP response\n");
                        return -EINVAL;
                }
                colon = strchr(buf, ':');
                if (!colon) {
-                       fprintf(stderr, "Ignoring unknown HTTP response line '%s'\n", buf);
+                       vpninfo->progress(vpninfo, PRG_ERR, "Ignoring unknown HTTP response line '%s'\n", buf);
                        continue;
                }
                *(colon++) = 0;
@@ -104,7 +103,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
                if (!strcmp(buf, "Content-Length")) {
                        bodylen = atoi(colon);
                        if (bodylen < 0 || bodylen > buf_len) {
-                               fprintf(stderr, "Response body too large for buffer (%d > %d)\n",
+                               vpninfo->progress(vpninfo, PRG_ERR, "Response body too large for buffer (%d > %d)\n",
                                        bodylen, buf_len);
                                return -EINVAL;
                        }
@@ -118,7 +117,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
                                *semicolon = 0;
 
                        if (!equals) {
-                               fprintf(stderr, "Invalid cookie offered: %s\n", buf);
+                               vpninfo->progress(vpninfo, PRG_ERR, "Invalid cookie offered: %s\n", buf);
                                return -EINVAL;
                        }
                        *(equals++) = 0;
@@ -126,7 +125,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
                        if (*equals) {
                                new = malloc(sizeof(*new));
                                if (!new) {
-                                       fprintf(stderr, "No memory for allocating cookies\n");
+                                       vpninfo->progress(vpninfo, PRG_ERR, "No memory for allocating cookies\n");
                                        return -ENOMEM;
                                }
                                new->next = NULL;
@@ -160,7 +159,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
                        if (!strcmp(colon, "chunked"))
                                bodylen = -1;
                        else {
-                               fprintf(stderr, "Unknown Transfer-Encoding: %s\n", colon);
+                               vpninfo->progress(vpninfo, PRG_ERR, "Unknown Transfer-Encoding: %s\n", colon);
                                return -EINVAL;
                        }
                }
@@ -190,7 +189,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) {
-                               fprintf(stderr, "Error reading HTTP response body\n");
+                               vpninfo->progress(vpninfo, PRG_ERR, "Error reading HTTP response body\n");
                                return -EINVAL;
                        }
                        done += i;
@@ -203,7 +202,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
                int chunklen, lastchunk = 0;
 
                if (i < 0) {
-                       fprintf(stderr, "Error fetching chunk header\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "Error fetching chunk header\n");
                        exit(1);
                }
                chunklen = strtol(buf, NULL, 16);
@@ -212,14 +211,14 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
                        goto skip;
                }
                if (chunklen + done > buf_len) {
-                       fprintf(stderr, "Response body too large for buffer (%d > %d)\n",
+                       vpninfo->progress(vpninfo, PRG_ERR, "Response body too large for buffer (%d > %d)\n",
                                chunklen + done, buf_len);
                        return -EINVAL;
                }
                while (chunklen) {
                        i = SSL_read(vpninfo->https_ssl, body + done, chunklen);
                        if (i < 0) {
-                               fprintf(stderr, "Error reading HTTP response body\n");
+                               vpninfo->progress(vpninfo, PRG_ERR, "Error reading HTTP response body\n");
                                return -EINVAL;
                        }
                        chunklen -= i;
@@ -228,9 +227,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) {
-                               fprintf(stderr, "Error fetching HTTP response body\n");
+                               vpninfo->progress(vpninfo, PRG_ERR, "Error fetching HTTP response body\n");
                        } else {
-                               fprintf(stderr, "Error in chunked decoding. Expected '', got: '%s'",
+                               vpninfo->progress(vpninfo, PRG_ERR, "Error in chunked decoding. Expected '', got: '%s'",
                                        buf);
                        }
                        return -EINVAL;
@@ -350,7 +349,7 @@ static int parse_auth_choice(struct openconnect_info *vpninfo,
        char *form_name = (char *)xmlGetProp(xml_node, (unsigned char *)"name");
 
        if (!form_name) {
-               fprintf(stderr, "Form choice has no name\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "Form choice has no name\n");
                return -EINVAL;
        }
        
@@ -368,14 +367,13 @@ static int parse_auth_choice(struct openconnect_info *vpninfo,
                        continue;
                if (strcmp(authtype, "sdi-via-proxy")) {
                        char *content = (char *)xmlNodeGetContent(xml_node);
-                       fprintf(stderr, "Unrecognised auth type %s, label '%s'\n", authtype, content);
+                       vpninfo->progress(vpninfo, PRG_ERR, "Unrecognised auth type %s, label '%s'\n", authtype, content);
                }
-               if (verbose)
-                       printf("choosing %s %s\n", form_name, form_id);
+               vpninfo->progress(vpninfo, PRG_TRACE, "choosing %s %s\n", form_name, form_id);
                append_opt(body, bodylen, form_name, form_id);
                return 0;
        }
-       fprintf(stderr, "Didn't find appropriate auth-type choice\n");
+       vpninfo->progress(vpninfo, PRG_ERR, "Didn't find appropriate auth-type choice\n");
        return -EINVAL;
 }
 
@@ -394,7 +392,7 @@ static int parse_form(struct openconnect_info *vpninfo, char *form_message,
        token[0] = 0;
 
        if (!ui) {
-               fprintf(stderr, "Failed to create UI\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "Failed to create UI\n");
                return -EINVAL;
        }
        if (form_error) {
@@ -421,26 +419,28 @@ static int parse_form(struct openconnect_info *vpninfo, char *form_message,
                        continue;
                }
                if (strcmp((char *)xml_node->name, "input")) {
-                       printf("name %s not input\n", xml_node->name);
+                       vpninfo->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) {
-                       printf("No input type\n");
+                       vpninfo->progress(vpninfo, PRG_INFO, "No input type in form\n");
                        continue;
                }
 
                input_name = (char *)xmlGetProp(xml_node, (unsigned char *)"name");
                if (!input_name) {
-                       printf("No input name\n");
+                       vpninfo->progress(vpninfo, PRG_INFO, "No input name in form\n");
                        continue;
                }
 
                if (!strcmp(input_type, "hidden")) {
                        char *value = (char *)xmlGetProp(xml_node, (unsigned char *)"value");
                        if (!value) {
-                               printf("No value for hidden input %s\n", input_name);
+                               vpninfo->progress(vpninfo, PRG_INFO, 
+                                                 "No value for hidden input %s\n",
+                                                 input_name);
                                continue;
                        }
 
@@ -457,8 +457,7 @@ static int parse_form(struct openconnect_info *vpninfo, char *form_message,
                        pass_form_id = input_name;
        }
                         
-       if (verbose)
-               printf("Fixed options give %s\n", body);
+       vpninfo->progress(vpninfo, PRG_TRACE, "Fixed options give %s\n", body);
 
        if (user_form_id && !vpninfo->username)
                UI_add_input_string(ui, "Enter username: ", UI_INPUT_FLAG_ECHO, username, 1, 80);
@@ -466,7 +465,7 @@ static int parse_form(struct openconnect_info *vpninfo, char *form_message,
 
        ret = UI_process(ui);
        if (ret) {
-               fprintf(stderr, "Invalid inputs\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "Invalid inputs\n");
                return -EINVAL;
        }
        if (user_form_id)
@@ -489,16 +488,15 @@ static int parse_xml_response(struct openconnect_info *vpninfo, char *response,
 
        xml_doc = xmlReadMemory(response, strlen(response), "noname.xml", NULL, 0);
        if (!xml_doc) {
-               fprintf(stderr, "Failed to parse server response\n");
-               if (verbose)
-                       printf("Response was:%s\n", response);
+               vpninfo->progress(vpninfo, PRG_ERR, "Failed to parse server response\n");
+               vpninfo->progress(vpninfo, PRG_TRACE, "Response was:%s\n", response);
                return -EINVAL;
        }
 
        xml_node = xmlDocGetRootElement(xml_doc);
        if (xml_node->type != XML_ELEMENT_NODE ||
            strcmp((char *)xml_node->name, "auth")) {
-               fprintf(stderr, "XML response has no \"auth\" root node\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "XML response has no \"auth\" root node\n");
                xmlFreeDoc(xml_doc);
                return -EINVAL;
        }
@@ -517,7 +515,7 @@ static int parse_xml_response(struct openconnect_info *vpninfo, char *response,
                        form_method = (char *)xmlGetProp(xml_node, (unsigned char *)"method");
                        form_action = (char *)xmlGetProp(xml_node, (unsigned char *)"action");
                        if (strcasecmp(form_method, "POST")) {
-                               fprintf(stderr, "Cannot handle form method '%s'\n",
+                               vpninfo->progress(vpninfo, PRG_ERR, "Cannot handle form method '%s'\n",
                                        form_method);
                                xmlFreeDoc(xml_doc);
                                return -EINVAL;
@@ -542,8 +540,8 @@ static int parse_xml_response(struct openconnect_info *vpninfo, char *response,
        if (success)
                return 0;
 
-       fprintf(stderr, "Response neither indicated success nor requested input\n");
-       printf("Response was:\n%s\n", response);
+       vpninfo->progress(vpninfo, PRG_ERR, "Response neither indicated success nor requested input\n");
+       vpninfo->progress(vpninfo, PRG_ERR, "Response was:\n%s\n", response);
        return -EINVAL;
 }
 
@@ -592,7 +590,7 @@ 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)) {
-               fprintf(stderr, "Downloaded config file did not match intended SHA1\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "Downloaded config file did not match intended SHA1\n");
                return -EINVAL;
        }
 
@@ -610,7 +608,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
 
  retry:
        if (!vpninfo->https_ssl && openconnect_open_https(vpninfo)) {
-               fprintf(stderr, "Failed to open HTTPS connection to %s\n",
+               vpninfo->progress(vpninfo, PRG_ERR, "Failed to open HTTPS connection to %s\n",
                        vpninfo->hostname);
                exit(1);
        }
@@ -693,7 +691,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
                        vpninfo->redirect_url = NULL;
                        goto retry;
                } else {
-                       fprintf(stderr, "Relative redirect (to '%s') not supported\n",
+                       vpninfo->progress(vpninfo, PRG_ERR, "Relative redirect (to '%s') not supported\n",
                                vpninfo->redirect_url);
                        return -EINVAL;
                }
@@ -747,7 +745,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
        if (vpninfo->cookie)
                return 0;
 
-       fprintf(stderr, "Server claimed successful login, but no cookie!\n");
+       vpninfo->progress(vpninfo, PRG_ERR, "Server claimed successful login, but no cookie!\n");
        return -1;
 }
 
diff --git a/main.c b/main.c
index 526c82c..b4e287e 100644 (file)
--- a/main.c
+++ b/main.c
@@ -39,8 +39,9 @@
 #include "openconnect.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, ...);
 
-int verbose = 0;
+int verbose = PRG_INFO;
 
 static struct option long_options[] = {
        {"certificate", 1, 0, 'c'},
@@ -61,6 +62,7 @@ static struct option long_options[] = {
        {"no-dtls", 0, 0, '1'},
        {"cookieonly", 0, 0, '2'},
        {"printcookie", 0, 0, '3'},
+       {"quiet", 0, 0, 'q'},
        {"xmlconfig", 1, 0, 'x'},
        {NULL, 0, 0, 0},
 };
@@ -82,6 +84,7 @@ void usage(void)
        printf("  -t, --tpm                       Use TPM engine for private key\n");
        printf("  -u, --user=NAME                 Set login username\n");
        printf("  -V, --version                   Report version number\n");
+       printf("  -q, --quiet                     Less output\n");
        printf("  -v, --verbose                   More output\n");
        printf("  -x, --xmlconfig=CONFIG          XML config file\n");
        printf("      --cookieonly                Fetch webvpn cookie only; don't connect\n");
@@ -114,6 +117,7 @@ int main(int argc, char **argv)
        vpninfo->deflate = 1;
        vpninfo->dtls_attempt_period = 60;
        vpninfo->write_new_config = write_new_config;
+       vpninfo->progress = write_progress;
 
        if (RAND_bytes(vpninfo->dtls_secret, sizeof(vpninfo->dtls_secret)) != 1) {
                fprintf(stderr, "Failed to initialise DTLS secret\n");
@@ -124,7 +128,7 @@ int main(int argc, char **argv)
        else
                vpninfo->localname = "localhost";
 
-       while ((opt = getopt_long(argc, argv, "C:c:hvdDu:i:tk:p:s:hx:V",
+       while ((opt = getopt_long(argc, argv, "C:c:hvdDu:i:tk:p:qs:hx:V",
                                  long_options, NULL))) {
                if (opt < 0)
                        break;
@@ -181,8 +185,11 @@ int main(int argc, char **argv)
                case 'u':
                        vpninfo->username = optarg;
                        break;
+               case 'q':
+                       verbose = PRG_ERR;
+                       break;
                case 'v':
-                       verbose = 1;
+                       verbose = PRG_TRACE;
                        break;
                case 'V':
                        printf("OpenConnect version %s\n", openconnect_version);
@@ -257,3 +264,15 @@ static int write_new_config(struct openconnect_info *vpninfo, char *buf, int buf
        write(config_fd, buf, buflen);  
        return 0;
 }
+
+void write_progress(struct openconnect_info *info, int level, const char *fmt, ...)
+{
+       FILE *outf = level?stdout:stderr;
+       va_list args;
+
+       if (verbose >= level) {
+               va_start(args, fmt);
+               vfprintf(outf, fmt, args);
+               va_end(args);
+       }
+}
index c0225f1..efdce5e 100644 (file)
@@ -58,7 +58,7 @@ int vpn_add_pollfd(struct openconnect_info *vpninfo, int fd, short events)
        vpninfo->nfds++;
        vpninfo->pfds = realloc(vpninfo->pfds, sizeof(struct pollfd) * vpninfo->nfds);
        if (!vpninfo->pfds) {
-               fprintf(stderr, "Failed to reallocate pfds\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "Failed to reallocate pfds\n");
                exit(1);
        }
        vpninfo->pfds[vpninfo->nfds - 1].fd = fd;
@@ -92,8 +92,7 @@ int vpn_mainloop(struct openconnect_info *vpninfo)
 
                if (!vpninfo->dtls_ssl && !vpninfo->new_dtls_ssl &&
                    vpninfo->new_dtls_started + vpninfo->dtls_attempt_period < time(NULL)) {
-                       if (verbose)
-                               printf("Attempt new DTLS connection\n");
+                       vpninfo->progress(vpninfo, PRG_TRACE, "Attempt new DTLS connection\n");
                        connect_dtls_socket(vpninfo);
                }
                if (vpninfo->dtls_ssl)
@@ -123,19 +122,19 @@ int vpn_mainloop(struct openconnect_info *vpninfo)
                if (did_work)
                        continue;
 
-               if (verbose)
-                       printf("Did no work; sleeping for %d ms...\n", timeout);
+               vpninfo->progress(vpninfo, PRG_TRACE, 
+                                 "Did no work; sleeping for %d ms...\n", timeout);
 
                poll(vpninfo->pfds, vpninfo->nfds, timeout);
                if (vpninfo->pfds[vpninfo->ssl_pfd].revents & POLL_HUP) {
-                       fprintf(stderr, "Server closed connection!\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "Server closed connection!\n");
                        /* OpenSSL doesn't seem to cope properly with this... */
                        exit(1);
                }
        }
 
        cstp_bye(vpninfo, vpninfo->quit_reason);
-       printf("Sent quit message: %s\n", vpninfo->quit_reason);
+       vpninfo->progress(vpninfo, PRG_INFO, "Sent quit message: %s\n", vpninfo->quit_reason);
 
        if (vpninfo->vpnc_script) {
                setenv("TUNDEV", vpninfo->ifname, 1);
@@ -152,10 +151,8 @@ int ka_stalled_dpd_time(struct keepalive_info *ka, int *timeout)
 {
        time_t now, due;
 
-       if (!ka->dpd) {
-               printf("no dpd\n");
+       if (!ka->dpd)
                return 0;
-       }
 
        time(&now);
        due = ka->last_rx + (2 * ka->dpd);
@@ -163,7 +160,6 @@ int ka_stalled_dpd_time(struct keepalive_info *ka, int *timeout)
        if (now > due)
                return 1;
 
-       printf("ka_stalled in %d seconds\n", (int)(due - now));
        if (*timeout > (due - now) * 1000)
                *timeout = (due - now) * 1000;
 
index 4e5e92f..c29cb39 100644 (file)
@@ -297,7 +297,16 @@ int write_new_config(struct openconnect_info *vpninfo, char *buf, int buflen)
        return 0;
 }
 
-int verbose = 0;
+void write_progress(struct openconnect_info *info, int level, const char *fmt, ...)
+{
+       va_list args;
+
+       if (level <= PRG_INFO) {
+               va_start(args, fmt);
+               vfprintf(stderr, fmt, args);
+               va_end(args);
+       }
+}
 
 static struct option long_options[] = {
        {"reprompt", 0, 0, 'r'},
@@ -366,6 +375,7 @@ int main (int argc, char **argv)
        vpninfo->useragent = openconnect_create_useragent("OpenConnect VPN Agent (NetworkManager)");
        vpninfo->ssl_fd = -1;
        vpninfo->write_new_config = write_new_config;
+       vpninfo->progress = write_progress;
 
        set_openssl_ui();
 
index e605fab..b5b00c6 100644 (file)
@@ -139,9 +139,17 @@ struct openconnect_info {
 
        char *quit_reason;
 
-       int (*write_new_config) (struct openconnect_info *vpninfo, char *buf, int buflen);      
+       int (*write_new_config) (struct openconnect_info *vpninfo, char *buf, int buflen);
+
+       void __attribute__ ((format(printf, 3, 4)))
+       (*progress) (struct openconnect_info *vpninfo, int level, const char *fmt, ...);
 };
 
+#define PRG_ERR                0
+#define PRG_INFO       1
+#define PRG_DEBUG      2
+#define PRG_TRACE      3
+
 /* Packet types */
 
 #define AC_PKT_DATA            0       /* Uncompressed data */
diff --git a/ssl.c b/ssl.c
index 84bf464..7f34df3 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -45,8 +45,6 @@ int  __attribute__ ((format (printf, 2, 3)))
        va_start(args, fmt);
        vsnprintf(buf, 1023, fmt, args);
        va_end(args);
-       if (verbose)
-               printf("%s", buf);
        return SSL_write(ssl, buf, strlen(buf));
 
 }
@@ -85,11 +83,13 @@ int openconnect_SSL_gets(SSL *ssl, char *buf, size_t len)
 
 static int load_certificate(struct openconnect_info *vpninfo)
 {
-       if (verbose)
-               printf("Using Certificate file %s\n", vpninfo->cert);
+       vpninfo->progress(vpninfo, PRG_TRACE, 
+                         "Using certificate file %s\n", vpninfo->cert);
+
        if (!SSL_CTX_use_certificate_file(vpninfo->https_ctx, vpninfo->cert,
                                          SSL_FILETYPE_PEM)) {
-               fprintf(stderr, "Certificate failed\n");
+               vpninfo->progress(vpninfo, PRG_ERR,
+                                 "Load certificate failed\n");
                ERR_print_errors_fp(stderr);
                return -EINVAL;
        }
@@ -101,13 +101,13 @@ static int load_certificate(struct openconnect_info *vpninfo)
 
                e = ENGINE_by_id("tpm");
                if (!e) {
-                       fprintf(stderr, "Can't load TPM engine.\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "Can't load TPM engine.\n");
                        ERR_print_errors_fp(stderr);
                        return -EINVAL;
                }
                if (!ENGINE_init(e) || !ENGINE_set_default_RSA(e) ||
                    !ENGINE_set_default_RAND(e)) {
-                       fprintf(stderr, "Failed to init TPM engine\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "Failed to init TPM engine\n");
                        ERR_print_errors_fp(stderr);
                        ENGINE_free(e);
                        return -EINVAL;
@@ -116,13 +116,13 @@ static int load_certificate(struct openconnect_info *vpninfo)
                if (vpninfo->tpmpass) {
                        if (!ENGINE_ctrl_cmd(e, "PIN", strlen(vpninfo->tpmpass),
                                             vpninfo->tpmpass, NULL, 0)) {
-                               fprintf(stderr, "Failed to set TPM SRK password\n");
+                               vpninfo->progress(vpninfo, PRG_ERR, "Failed to set TPM SRK password\n");
                                ERR_print_errors_fp(stderr);
                        }
                }
                key = ENGINE_load_private_key(e, vpninfo->sslkey, NULL, NULL);
                if (!key) {
-                       fprintf(stderr
+                       vpninfo->progress(vpninfo, PRG_ERR
                                "Failed to load TPM private key\n");
                        ERR_print_errors_fp(stderr);
                        ENGINE_free(e);
@@ -130,7 +130,7 @@ static int load_certificate(struct openconnect_info *vpninfo)
                        return -EINVAL;
                }
                if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) {
-                       fprintf(stderr, "Add key from TPM failed\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "Add key from TPM failed\n");
                        ERR_print_errors_fp(stderr);
                        ENGINE_free(e);
                        ENGINE_finish(e);
@@ -140,7 +140,7 @@ static int load_certificate(struct openconnect_info *vpninfo)
                if (!SSL_CTX_use_RSAPrivateKey_file(vpninfo->https_ctx,
                                                    vpninfo->sslkey,
                                                    SSL_FILETYPE_PEM)) {
-                       fprintf(stderr, "Private key failed\n");
+                       vpninfo->progress(vpninfo, PRG_ERR, "Private key failed\n");
                        ERR_print_errors_fp(stderr);
                        return -EINVAL;
                }
@@ -168,22 +168,24 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
 
        err = getaddrinfo(vpninfo->hostname, "https", &hints, &result);
        if (err) {
-               fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(err));
+               vpninfo->progress(vpninfo, PRG_ERR, "getaddrinfo failed: %s\n", gai_strerror(err));
                return -EINVAL;
        }
 
+       vpninfo->progress(vpninfo, PRG_INFO,
+                         "Attempting to connect to %s\n", vpninfo->hostname);
+
        for (rp = result; rp ; rp = rp->ai_next) {
                ssl_sock = socket(rp->ai_family, rp->ai_socktype,
                                  rp->ai_protocol);
                if (ssl_sock < 0)
                        continue;
-
                if (connect(ssl_sock, rp->ai_addr, rp->ai_addrlen) >= 0) {
                        /* Store the peer address we actually used, so that DTLS can 
                           use it again later */
                        vpninfo->peer_addr = malloc(rp->ai_addrlen);
                        if (!vpninfo->peer_addr) {
-                               fprintf(stderr, "Failed to allocate sockaddr storage\n");
+                               vpninfo->progress(vpninfo, PRG_ERR, "Failed to allocate sockaddr storage\n");
                                close(ssl_sock);
                                return -ENOMEM;
                        }
@@ -196,7 +198,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
        freeaddrinfo(result);
 
        if (!rp) {
-               fprintf(stderr, "Failed to connect to host %s\n", vpninfo->hostname);
+               vpninfo->progress(vpninfo, PRG_ERR, "Failed to connect to host %s\n", vpninfo->hostname);
                return -EINVAL;
        }
        fcntl(ssl_sock, F_SETFD, FD_CLOEXEC);
@@ -218,8 +220,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,
+                         "SSL negotiation with %s\n", vpninfo->hostname);
+
        if (SSL_connect(https_ssl) <= 0) {
-               fprintf(stderr, "SSL connection failure\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "SSL connection failure\n");
                ERR_print_errors_fp(stderr);
                SSL_free(https_ssl);
                close(ssl_sock);
@@ -231,7 +236,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
 
                /* FIXME: Show cert details, allow user to accept (and store?) */
                if (vfy != X509_V_OK) {
-                       fprintf(stderr, "Server certificate verify failed: %s\n",
+                       vpninfo->progress(vpninfo, PRG_ERR, "Server certificate verify failed: %s\n",
                                X509_verify_cert_error_string(vfy));
                        SSL_free(https_ssl);
                        close(ssl_sock);
@@ -242,8 +247,8 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
        vpninfo->ssl_fd = ssl_sock;
        vpninfo->https_ssl = https_ssl;
 
-       if (verbose)
-               printf("Connected to HTTPS on %s\n", vpninfo->hostname);
+       vpninfo->progress(vpninfo, PRG_INFO, 
+                         "Connected to HTTPS on %s\n", vpninfo->hostname);
 
        return 0;
 }
diff --git a/tun.c b/tun.c
index bd07b05..6c4c5dc 100644 (file)
--- a/tun.c
+++ b/tun.c
@@ -103,7 +103,7 @@ static int script_config_tun(struct openconnect_info *vpninfo)
        struct sockaddr_in *sin = (void *)vpninfo->peer_addr;
 
        if (vpninfo->peer_addr->sa_family != AF_INET) {
-               fprintf(stderr, "Script cannot handle anything but Legacy IP\n");
+               vpninfo->progress(vpninfo, PRG_ERR, "Script cannot handle anything but Legacy IP\n");
                return -EINVAL;
        }
 
diff --git a/xml.c b/xml.c
index ca70779..3f31113 100644 (file)
--- a/xml.c
+++ b/xml.c
@@ -79,8 +79,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]);
 
-       if (verbose)
-               printf("XML config file SHA1: %s\n", vpninfo->xmlsha1);
+       vpninfo->progress(vpninfo, PRG_TRACE, "XML config file SHA1: %s\n", vpninfo->xmlsha1);
 
        xml_doc = xmlReadMemory(xmlfile, st.st_size, "noname.xml", NULL, 0);
        if (!xml_doc) {