2 * OpenConnect (SSL + DTLS) VPN client
4 * Copyright © 2008-2012 Intel Corporation.
5 * Copyright © 2008 Nick Andrew <nick@nick-andrew.net>
7 * Author: David Woodhouse <dwmw2@infradead.org>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * version 2.1, as published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to:
21 * Free Software Foundation, Inc.
22 * 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301 USA
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <netinet/tcp.h>
41 #include "openconnect-internal.h"
44 * Data packets are encapsulated in the SSL stream as follows:
46 * 0000: Magic "STF\x1"
47 * 0004: Big-endian 16-bit length (not including 8-byte header)
48 * 0006: Byte packet type (see openconnect-internal.h)
52 static char data_hdr[8] = {
55 AC_PKT_DATA, /* Type */
59 static struct pkt keepalive_pkt = {
60 .hdr = { 'S', 'T', 'F', 1, 0, 0, AC_PKT_KEEPALIVE, 0 },
63 static struct pkt dpd_pkt = {
64 .hdr = { 'S', 'T', 'F', 1, 0, 0, AC_PKT_DPD_OUT, 0 },
67 static struct pkt dpd_resp_pkt = {
68 .hdr = { 'S', 'T', 'F', 1, 0, 0, AC_PKT_DPD_RESP, 0 },
71 static int __attribute__ ((format (printf, 3, 4)))
72 buf_append(char *buf, int len, const char *fmt, ...)
74 int start = strlen(buf);
82 ret = vsnprintf(buf + start, len - start, fmt, args);
91 /* Calculate MTU to request. Old servers simply use the X-CSTP-MTU: header,
92 * which represents the tunnel MTU, while new servers do calculations on the
93 * X-CSTP-Base-MTU: header which represents the cleartext MTU between client
96 * If possible, the legacy MTU value should be the TCP MSS less 5 bytes of
97 * TLS and 8 bytes of CSTP overhead. We can get the MSS from either the
98 * TCP_INFO or TCP_MAXSEG sockopts.
100 * The base MTU comes from the TCP_INFO sockopt under Linux, but I don't know
101 * how to work it out on other systems. So leave it blank and do things the
102 * legacy way there. Contributions welcome...
104 * If we don't even have TCP_MAXSEG, then default to sending a legacy MTU of
105 * 1406 which is what we always used to do.
107 static void calculate_mtu(struct openconnect_info *vpninfo, int *base_mtu, int *mtu)
109 *mtu = vpninfo->reqmtu;
110 *base_mtu = vpninfo->basemtu;
112 #if defined(__linux__) && defined(TCP_INFO)
113 if (!*mtu || !*base_mtu) {
115 socklen_t ti_size = sizeof(ti);
117 if (!getsockopt(vpninfo->ssl_fd, IPPROTO_TCP, TCP_INFO,
119 vpn_progress(vpninfo, PRG_TRACE,
120 _("TCP_INFO rcv mss %d, snd mss %d, adv mss %d, pmtu %d\n"),
121 ti.tcpi_rcv_mss, ti.tcpi_snd_mss, ti.tcpi_advmss, ti.tcpi_pmtu);
122 if (!*base_mtu) *base_mtu = ti.tcpi_pmtu;
124 if (ti.tcpi_rcv_mss < ti.tcpi_snd_mss)
125 *mtu = ti.tcpi_rcv_mss - 13;
127 *mtu = ti.tcpi_snd_mss - 13;
135 socklen_t mss_size = sizeof(mss);
136 if (!getsockopt(vpninfo->ssl_fd, IPPROTO_TCP, TCP_MAXSEG,
138 vpn_progress(vpninfo, PRG_TRACE, _("TCP_MAXSEG %d\n"), mss);
151 static int start_cstp_connection(struct openconnect_info *vpninfo)
155 int retried = 0, sessid_found = 0;
156 struct vpn_option **next_dtls_option = &vpninfo->dtls_options;
157 struct vpn_option **next_cstp_option = &vpninfo->cstp_options;
158 struct vpn_option *old_cstp_opts = vpninfo->cstp_options;
159 struct vpn_option *old_dtls_opts = vpninfo->dtls_options;
160 const char *old_addr = vpninfo->vpn_addr;
161 const char *old_netmask = vpninfo->vpn_netmask;
162 const char *old_addr6 = vpninfo->vpn_addr6;
163 const char *old_netmask6 = vpninfo->vpn_netmask6;
164 struct split_include *inc;
167 /* Clear old options which will be overwritten */
168 vpninfo->vpn_addr = vpninfo->vpn_netmask = NULL;
169 vpninfo->vpn_addr6 = vpninfo->vpn_netmask6 = NULL;
170 vpninfo->cstp_options = vpninfo->dtls_options = NULL;
171 vpninfo->vpn_domain = vpninfo->vpn_proxy_pac = NULL;
172 vpninfo->banner = NULL;
175 vpninfo->vpn_dns[i] = vpninfo->vpn_nbns[i] = NULL;
177 for (inc = vpninfo->split_includes; inc; ) {
178 struct split_include *next = inc->next;
182 for (inc = vpninfo->split_excludes; inc; ) {
183 struct split_include *next = inc->next;
187 for (inc = vpninfo->split_dns; inc; ) {
188 struct split_include *next = inc->next;
192 vpninfo->split_dns = vpninfo->split_includes = vpninfo->split_excludes = NULL;
194 /* Create (new) random master key for DTLS connection, if needed */
195 if (vpninfo->dtls_times.last_rekey + vpninfo->dtls_times.rekey <
197 openconnect_random(vpninfo->dtls_secret, sizeof(vpninfo->dtls_secret))) {
198 fprintf(stderr, _("Failed to initialise DTLS secret\n"));
203 calculate_mtu(vpninfo, &base_mtu, &mtu);
206 buf_append(buf, sizeof(buf), "CONNECT /CSCOSSLC/tunnel HTTP/1.1\r\n");
207 buf_append(buf, sizeof(buf), "Host: %s\r\n", vpninfo->hostname);
208 buf_append(buf, sizeof(buf), "User-Agent: %s\r\n", vpninfo->useragent);
209 buf_append(buf, sizeof(buf), "Cookie: webvpn=%s\r\n", vpninfo->cookie);
210 buf_append(buf, sizeof(buf), "X-CSTP-Version: 1\r\n");
211 buf_append(buf, sizeof(buf), "X-CSTP-Hostname: %s\r\n", vpninfo->localname);
212 if (vpninfo->deflate && i < sizeof(buf))
213 buf_append(buf, sizeof(buf), "X-CSTP-Accept-Encoding: deflate;q=1.0\r\n");
215 buf_append(buf, sizeof(buf), "X-CSTP-Base-MTU: %d\r\n", base_mtu);
216 buf_append(buf, sizeof(buf), "X-CSTP-MTU: %d\r\n", mtu);
217 buf_append(buf, sizeof(buf), "X-CSTP-Address-Type: %s\r\n",
218 vpninfo->disable_ipv6?"IPv4":"IPv6,IPv4");
219 buf_append(buf, sizeof(buf), "X-DTLS-Master-Secret: ");
220 for (i = 0; i < sizeof(vpninfo->dtls_secret); i++)
221 buf_append(buf, sizeof(buf), "%02X", vpninfo->dtls_secret[i]);
222 buf_append(buf, sizeof(buf), "\r\nX-DTLS-CipherSuite: %s\r\n\r\n",
223 vpninfo->dtls_ciphers?:"AES256-SHA:AES128-SHA:DES-CBC3-SHA:DES-CBC-SHA");
225 openconnect_SSL_write(vpninfo, buf, strlen(buf));
227 if ((i = openconnect_SSL_gets(vpninfo, buf, 65536) < 0)) {
230 vpn_progress(vpninfo, PRG_ERR,
231 _("Error fetching HTTPS response\n"));
234 openconnect_close_https(vpninfo, 0);
236 if (openconnect_open_https(vpninfo)) {
237 vpn_progress(vpninfo, PRG_ERR,
238 _("Failed to open HTTPS connection to %s\n"),
247 if (strncmp(buf, "HTTP/1.1 200 ", 13)) {
248 if (!strncmp(buf, "HTTP/1.1 503 ", 13)) {
249 /* "Service Unavailable. Why? */
250 const char *reason = "<unknown>";
251 while ((i = openconnect_SSL_gets(vpninfo, buf, sizeof(buf)))) {
252 if (!strncmp(buf, "X-Reason: ", 10)) {
257 vpn_progress(vpninfo, PRG_ERR,
258 _("VPN service unavailable; reason: %s\n"),
262 vpn_progress(vpninfo, PRG_ERR,
263 _("Got inappropriate HTTP CONNECT response: %s\n"),
265 if (!strncmp(buf, "HTTP/1.1 401 ", 13))
270 vpn_progress(vpninfo, PRG_INFO, _("Got CONNECT response: %s\n"), buf);
272 /* We may have advertised it, but we only do it if the server agrees */
273 vpninfo->deflate = 0;
276 while ((i = openconnect_SSL_gets(vpninfo, buf, sizeof(buf)))) {
277 struct vpn_option *new_option;
283 colon = strchr(buf, ':');
292 if (strncmp(buf, "X-DTLS-", 7) &&
293 strncmp(buf, "X-CSTP-", 7))
296 new_option = malloc(sizeof(*new_option));
298 vpn_progress(vpninfo, PRG_ERR, _("No memory for options\n"));
301 new_option->option = strdup(buf);
302 new_option->value = strdup(colon);
303 new_option->next = NULL;
305 if (!new_option->option || !new_option->value) {
306 vpn_progress(vpninfo, PRG_ERR, _("No memory for options\n"));
307 free(new_option->option);
308 free(new_option->value);
313 vpn_progress(vpninfo, PRG_TRACE, "%s: %s\n", buf, colon);
315 if (!strncmp(buf, "X-DTLS-", 7)) {
316 *next_dtls_option = new_option;
317 next_dtls_option = &new_option->next;
319 if (!strcmp(buf + 7, "MTU")) {
320 int dtlsmtu = atol(colon);
323 } else if (!strcmp(buf + 7, "Session-ID")) {
324 if (strlen(colon) != 64) {
325 vpn_progress(vpninfo, PRG_ERR,
326 _("X-DTLS-Session-ID not 64 characters; is: \"%s\"\n"),
328 vpninfo->dtls_attempt_period = 0;
331 for (i = 0; i < 64; i += 2)
332 vpninfo->dtls_session_id[i/2] = unhex(colon + i);
334 time(&vpninfo->dtls_times.last_rekey);
338 /* CSTP options... */
339 *next_cstp_option = new_option;
340 next_cstp_option = &new_option->next;
343 if (!strcmp(buf + 7, "Keepalive")) {
344 vpninfo->ssl_times.keepalive = atol(colon);
345 } else if (!strcmp(buf + 7, "DPD")) {
347 if (j && (!vpninfo->ssl_times.dpd || j < vpninfo->ssl_times.dpd))
348 vpninfo->ssl_times.dpd = j;
349 } else if (!strcmp(buf + 7, "Rekey-Time")) {
350 vpninfo->ssl_times.rekey = atol(colon);
351 } else if (!strcmp(buf + 7, "Content-Encoding")) {
352 if (!strcmp(colon, "deflate"))
353 vpninfo->deflate = 1;
355 vpn_progress(vpninfo, PRG_ERR,
356 _("Unknown CSTP-Content-Encoding %s\n"),
360 } else if (!strcmp(buf + 7, "MTU")) {
361 int cstpmtu = atol(colon);
364 } else if (!strcmp(buf + 7, "Address")) {
365 if (strchr(new_option->value, ':')) {
366 if (!vpninfo->disable_ipv6)
367 vpninfo->vpn_addr6 = new_option->value;
369 vpninfo->vpn_addr = new_option->value;
370 } else if (!strcmp(buf + 7, "Netmask")) {
371 if (strchr(new_option->value, ':')) {
372 if (!vpninfo->disable_ipv6)
373 vpninfo->vpn_netmask6 = new_option->value;
375 vpninfo->vpn_netmask = new_option->value;
376 } else if (!strcmp(buf + 7, "DNS")) {
378 for (j = 0; j < 3; j++) {
379 if (!vpninfo->vpn_dns[j]) {
380 vpninfo->vpn_dns[j] = new_option->value;
384 } else if (!strcmp(buf + 7, "NBNS")) {
386 for (j = 0; j < 3; j++) {
387 if (!vpninfo->vpn_nbns[j]) {
388 vpninfo->vpn_nbns[j] = new_option->value;
392 } else if (!strcmp(buf + 7, "Default-Domain")) {
393 vpninfo->vpn_domain = new_option->value;
394 } else if (!strcmp(buf + 7, "MSIE-Proxy-PAC-URL")) {
395 vpninfo->vpn_proxy_pac = new_option->value;
396 } else if (!strcmp(buf + 7, "Banner")) {
397 vpninfo->banner = new_option->value;
398 } else if (!strcmp(buf + 7, "Split-DNS")) {
399 struct split_include *dns = malloc(sizeof(*dns));
402 dns->route = new_option->value;
403 dns->next = vpninfo->split_dns;
404 vpninfo->split_dns = dns;
405 } else if (!strcmp(buf + 7, "Split-Include")) {
406 struct split_include *inc = malloc(sizeof(*inc));
409 inc->route = new_option->value;
410 inc->next = vpninfo->split_includes;
411 vpninfo->split_includes = inc;
412 } else if (!strcmp(buf + 7, "Split-Exclude")) {
413 struct split_include *exc = malloc(sizeof(*exc));
416 exc->route = new_option->value;
417 exc->next = vpninfo->split_excludes;
418 vpninfo->split_excludes = exc;
423 vpn_progress(vpninfo, PRG_ERR,
424 _("No MTU received. Aborting\n"));
427 vpninfo->actual_mtu = mtu;
429 if (!vpninfo->vpn_addr && !vpninfo->vpn_addr6) {
430 vpn_progress(vpninfo, PRG_ERR,
431 _("No IP address received. Aborting\n"));
435 if (strcmp(old_addr, vpninfo->vpn_addr)) {
436 vpn_progress(vpninfo, PRG_ERR,
437 _("Reconnect gave different Legacy IP address (%s != %s)\n"),
438 vpninfo->vpn_addr, old_addr);
443 if (strcmp(old_netmask, vpninfo->vpn_netmask)) {
444 vpn_progress(vpninfo, PRG_ERR,
445 _("Reconnect gave different Legacy IP netmask (%s != %s)\n"),
446 vpninfo->vpn_netmask, old_netmask);
451 if (strcmp(old_addr6, vpninfo->vpn_addr6)) {
452 vpn_progress(vpninfo, PRG_ERR,
453 _("Reconnect gave different IPv6 address (%s != %s)\n"),
454 vpninfo->vpn_addr6, old_addr6);
459 if (strcmp(old_netmask6, vpninfo->vpn_netmask6)) {
460 vpn_progress(vpninfo, PRG_ERR,
461 _("Reconnect gave different IPv6 netmask (%s != %s)\n"),
462 vpninfo->vpn_netmask6, old_netmask6);
467 while (old_dtls_opts) {
468 struct vpn_option *tmp = old_dtls_opts;
469 old_dtls_opts = old_dtls_opts->next;
474 while (old_cstp_opts) {
475 struct vpn_option *tmp = old_cstp_opts;
476 old_cstp_opts = old_cstp_opts->next;
481 vpn_progress(vpninfo, PRG_INFO, _("CSTP connected. DPD %d, Keepalive %d\n"),
482 vpninfo->ssl_times.dpd, vpninfo->ssl_times.keepalive);
484 if (vpninfo->select_nfds <= vpninfo->ssl_fd)
485 vpninfo->select_nfds = vpninfo->ssl_fd + 1;
487 FD_SET(vpninfo->ssl_fd, &vpninfo->select_rfds);
488 FD_SET(vpninfo->ssl_fd, &vpninfo->select_efds);
491 vpninfo->dtls_attempt_period = 0;
493 vpninfo->ssl_times.last_rekey = vpninfo->ssl_times.last_rx =
494 vpninfo->ssl_times.last_tx = time(NULL);
499 int make_cstp_connection(struct openconnect_info *vpninfo)
503 ret = openconnect_open_https(vpninfo);
507 if (vpninfo->deflate) {
508 vpninfo->deflate_adler32 = 1;
509 vpninfo->inflate_adler32 = 1;
511 if (inflateInit2(&vpninfo->inflate_strm, -12) ||
512 deflateInit2(&vpninfo->deflate_strm, Z_DEFAULT_COMPRESSION,
513 Z_DEFLATED, -12, 9, Z_DEFAULT_STRATEGY)) {
514 vpn_progress(vpninfo, PRG_ERR, _("Compression setup failed\n"));
515 vpninfo->deflate = 0;
518 if (!vpninfo->deflate_pkt) {
519 vpninfo->deflate_pkt = malloc(sizeof(struct pkt) + 2048);
520 if (!vpninfo->deflate_pkt) {
521 vpn_progress(vpninfo, PRG_ERR,
522 _("Allocation of deflate buffer failed\n"));
523 inflateEnd(&vpninfo->inflate_strm);
524 deflateEnd(&vpninfo->deflate_strm);
525 vpninfo->deflate = 0;
527 memset(vpninfo->deflate_pkt, 0, sizeof(struct pkt));
528 memcpy(vpninfo->deflate_pkt->hdr, data_hdr, 8);
529 vpninfo->deflate_pkt->hdr[6] = AC_PKT_COMPRESSED;
534 return start_cstp_connection(vpninfo);
537 int cstp_reconnect(struct openconnect_info *vpninfo)
543 openconnect_close_https(vpninfo, 0);
545 if (vpninfo->deflate) {
546 /* Requeue the original packet that was deflated */
547 if (vpninfo->current_ssl_pkt == vpninfo->deflate_pkt) {
548 vpninfo->current_ssl_pkt = NULL;
549 queue_packet(&vpninfo->outgoing_queue, vpninfo->pending_deflated_pkt);
550 vpninfo->pending_deflated_pkt = NULL;
552 inflateEnd(&vpninfo->inflate_strm);
553 deflateEnd(&vpninfo->deflate_strm);
555 timeout = vpninfo->reconnect_timeout;
556 interval = vpninfo->reconnect_interval;
558 while ((ret = make_cstp_connection(vpninfo))) {
561 vpn_progress(vpninfo, PRG_INFO,
562 _("sleep %ds, remaining timeout %ds\n"),
568 interval += vpninfo->reconnect_interval;
569 if (interval > RECONNECT_INTERVAL_MAX)
570 interval = RECONNECT_INTERVAL_MAX;
572 script_config_tun(vpninfo, "reconnect");
576 static int inflate_and_queue_packet(struct openconnect_info *vpninfo,
577 unsigned char *buf, int len)
579 struct pkt *new = malloc(sizeof(struct pkt) + vpninfo->actual_mtu);
587 vpninfo->inflate_strm.next_in = buf;
588 vpninfo->inflate_strm.avail_in = len - 4;
590 vpninfo->inflate_strm.next_out = new->data;
591 vpninfo->inflate_strm.avail_out = vpninfo->actual_mtu;
592 vpninfo->inflate_strm.total_out = 0;
594 if (inflate(&vpninfo->inflate_strm, Z_SYNC_FLUSH)) {
595 vpn_progress(vpninfo, PRG_ERR, _("inflate failed\n"));
600 new->len = vpninfo->inflate_strm.total_out;
602 vpninfo->inflate_adler32 = adler32(vpninfo->inflate_adler32,
603 new->data, new->len);
605 pkt_sum = buf[len - 1] | (buf[len - 2] << 8) |
606 (buf[len - 3] << 16) | (buf[len - 4] << 24);
608 if (vpninfo->inflate_adler32 != pkt_sum) {
609 vpninfo->quit_reason = "Compression (inflate) adler32 failure";
612 vpn_progress(vpninfo, PRG_TRACE,
613 _("Received compressed data packet of %ld bytes\n"),
614 (long)vpninfo->inflate_strm.total_out);
616 queue_packet(&vpninfo->incoming_queue, new);
620 #if defined (OPENCONNECT_OPENSSL)
621 static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
625 len = SSL_read(vpninfo->https_ssl, buf, maxlen);
629 ret = SSL_get_error(vpninfo->https_ssl, len);
630 if (ret == SSL_ERROR_SYSCALL || ret == SSL_ERROR_ZERO_RETURN) {
631 vpn_progress(vpninfo, PRG_ERR,
632 _("SSL read error %d (server probably closed connection); reconnecting.\n"),
639 static int cstp_write(struct openconnect_info *vpninfo, void *buf, int buflen)
643 ret = SSL_write(vpninfo->https_ssl, buf, buflen);
647 ret = SSL_get_error(vpninfo->https_ssl, ret);
649 case SSL_ERROR_WANT_WRITE:
650 /* Waiting for the socket to become writable -- it's
651 probably stalled, and/or the buffers are full */
652 FD_SET(vpninfo->ssl_fd, &vpninfo->select_wfds);
653 case SSL_ERROR_WANT_READ:
657 vpn_progress(vpninfo, PRG_ERR, _("SSL_write failed: %d\n"), ret);
658 openconnect_report_ssl_errors(vpninfo);
662 #elif defined (OPENCONNECT_GNUTLS)
663 static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
667 ret = gnutls_record_recv(vpninfo->https_sess, buf, maxlen);
671 if (ret != GNUTLS_E_AGAIN) {
672 vpn_progress(vpninfo, PRG_ERR,
673 _("SSL read error: %s; reconnecting.\n"),
674 gnutls_strerror(ret));
680 static int cstp_write(struct openconnect_info *vpninfo, void *buf, int buflen)
684 ret = gnutls_record_send(vpninfo->https_sess, buf, buflen);
688 if (ret == GNUTLS_E_AGAIN) {
689 if (gnutls_record_get_direction(vpninfo->https_sess)) {
690 /* Waiting for the socket to become writable -- it's
691 probably stalled, and/or the buffers are full */
692 FD_SET(vpninfo->ssl_fd, &vpninfo->select_wfds);
696 vpn_progress(vpninfo, PRG_ERR, _("SSL send failed: %s\n"),
697 gnutls_strerror(ret));
702 int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
704 unsigned char buf[16384];
708 /* FIXME: The poll() handling here is fairly simplistic. Actually,
709 if the SSL connection stalls it could return a WANT_WRITE error
710 on _either_ of the SSL_read() or SSL_write() calls. In that case,
711 we should probably remove POLLIN from the events we're looking for,
712 and add POLLOUT. As it is, though, it'll just chew CPU time in that
713 fairly unlikely situation, until the write backlog clears. */
714 while ( (len = cstp_read(vpninfo, buf, sizeof(buf))) > 0) {
717 if (buf[0] != 'S' || buf[1] != 'T' ||
718 buf[2] != 'F' || buf[3] != 1 || buf[7])
721 payload_len = (buf[4] << 8) + buf[5];
722 if (len != 8 + payload_len) {
723 vpn_progress(vpninfo, PRG_ERR,
724 _("Unexpected packet length. SSL_read returned %d but packet is\n"),
726 vpn_progress(vpninfo, PRG_ERR,
727 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
728 buf[0], buf[1], buf[2], buf[3],
729 buf[4], buf[5], buf[6], buf[7]);
732 vpninfo->ssl_times.last_rx = time(NULL);
735 vpn_progress(vpninfo, PRG_TRACE,
736 _("Got CSTP DPD request\n"));
737 vpninfo->owe_ssl_dpd_response = 1;
740 case AC_PKT_DPD_RESP:
741 vpn_progress(vpninfo, PRG_TRACE,
742 _("Got CSTP DPD response\n"));
745 case AC_PKT_KEEPALIVE:
746 vpn_progress(vpninfo, PRG_TRACE,
747 _("Got CSTP Keepalive\n"));
751 vpn_progress(vpninfo, PRG_TRACE,
752 _("Received uncompressed data packet of %d bytes\n"),
754 queue_new_packet(&vpninfo->incoming_queue, buf + 8,
759 case AC_PKT_DISCONN: {
761 for (i = 0; i < payload_len; i++) {
762 if (!isprint(buf[payload_len + 8 + i]))
763 buf[payload_len + 8 + i] = '.';
765 buf[payload_len + 8] = 0;
766 vpn_progress(vpninfo, PRG_ERR,
767 _("Received server disconnect: %02x '%s'\n"),
769 vpninfo->quit_reason = "Server request";
772 case AC_PKT_COMPRESSED:
773 if (!vpninfo->deflate) {
774 vpn_progress(vpninfo, PRG_ERR,
775 _("Compressed packet received in !deflate mode\n"));
778 inflate_and_queue_packet(vpninfo, buf + 8, payload_len);
782 case AC_PKT_TERM_SERVER:
783 vpn_progress(vpninfo, PRG_ERR, _("received server terminate packet\n"));
784 vpninfo->quit_reason = "Server request";
789 vpn_progress(vpninfo, PRG_ERR,
790 _("Unknown packet %02x %02x %02x %02x %02x %02x %02x %02x\n"),
791 buf[0], buf[1], buf[2], buf[3],
792 buf[4], buf[5], buf[6], buf[7]);
793 vpninfo->quit_reason = "Unknown packet received";
800 /* If SSL_write() fails we are expected to try again. With exactly
801 the same data, at exactly the same location. So we keep the
802 packet we had before.... */
803 if (vpninfo->current_ssl_pkt) {
805 vpninfo->ssl_times.last_tx = time(NULL);
806 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
808 ret = cstp_write(vpninfo,
809 vpninfo->current_ssl_pkt->hdr,
810 vpninfo->current_ssl_pkt->len + 8);
814 /* -EAGAIN: cstp_write() will have added the SSL fd to
815 ->select_wfds if appropriate, so we can just return
816 and wait. Unless it's been stalled for so long that
817 DPD kicks in and we kill the connection. */
818 switch (ka_stalled_action(&vpninfo->ssl_times, timeout)) {
826 /* This should never happen */
831 if (ret != vpninfo->current_ssl_pkt->len + 8) {
832 vpn_progress(vpninfo, PRG_ERR,
833 _("SSL wrote too few bytes! Asked for %d, sent %d\n"),
834 vpninfo->current_ssl_pkt->len + 8, ret);
835 vpninfo->quit_reason = "Internal error";
838 /* Don't free the 'special' packets */
839 if (vpninfo->current_ssl_pkt == vpninfo->deflate_pkt)
840 free(vpninfo->pending_deflated_pkt);
841 else if (vpninfo->current_ssl_pkt != &dpd_pkt &&
842 vpninfo->current_ssl_pkt != &dpd_resp_pkt &&
843 vpninfo->current_ssl_pkt != &keepalive_pkt)
844 free(vpninfo->current_ssl_pkt);
846 vpninfo->current_ssl_pkt = NULL;
849 if (vpninfo->owe_ssl_dpd_response) {
850 vpninfo->owe_ssl_dpd_response = 0;
851 vpninfo->current_ssl_pkt = &dpd_resp_pkt;
852 goto handle_outgoing;
855 switch (keepalive_action(&vpninfo->ssl_times, timeout)) {
858 /* Not that this will ever happen; we don't even process
859 the setting when we're asked for it. */
860 vpn_progress(vpninfo, PRG_INFO, _("CSTP rekey due\n"));
866 vpn_progress(vpninfo, PRG_ERR,
867 _("CSTP Dead Peer Detection detected dead peer!\n"));
869 if (cstp_reconnect(vpninfo)) {
870 vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
871 vpninfo->quit_reason = "CSTP reconnect failed";
874 /* I think we can leave DTLS to its own devices; when we reconnect
875 with the same master secret, we do seem to get the same sessid */
879 vpn_progress(vpninfo, PRG_TRACE, _("Send CSTP DPD\n"));
881 vpninfo->current_ssl_pkt = &dpd_pkt;
882 goto handle_outgoing;
885 /* No need to send an explicit keepalive
886 if we have real data to send */
887 if (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue)
890 vpn_progress(vpninfo, PRG_TRACE, _("Send CSTP Keepalive\n"));
892 vpninfo->current_ssl_pkt = &keepalive_pkt;
893 goto handle_outgoing;
899 /* Service outgoing packet queue, if no DTLS */
900 while (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue) {
901 struct pkt *this = vpninfo->outgoing_queue;
902 vpninfo->outgoing_queue = this->next;
903 vpninfo->outgoing_qlen--;
905 if (vpninfo->deflate) {
906 unsigned char *adler;
909 vpninfo->deflate_strm.next_in = this->data;
910 vpninfo->deflate_strm.avail_in = this->len;
911 vpninfo->deflate_strm.next_out = (void *)vpninfo->deflate_pkt->data;
912 vpninfo->deflate_strm.avail_out = 2040;
913 vpninfo->deflate_strm.total_out = 0;
915 ret = deflate(&vpninfo->deflate_strm, Z_SYNC_FLUSH);
917 vpn_progress(vpninfo, PRG_ERR, _("deflate failed %d\n"), ret);
921 vpninfo->deflate_pkt->hdr[4] = (vpninfo->deflate_strm.total_out + 4) >> 8;
922 vpninfo->deflate_pkt->hdr[5] = (vpninfo->deflate_strm.total_out + 4) & 0xff;
924 /* Add ongoing adler32 to tail of compressed packet */
925 vpninfo->deflate_adler32 = adler32(vpninfo->deflate_adler32,
926 this->data, this->len);
928 adler = &vpninfo->deflate_pkt->data[vpninfo->deflate_strm.total_out];
929 *(adler++) = vpninfo->deflate_adler32 >> 24;
930 *(adler++) = (vpninfo->deflate_adler32 >> 16) & 0xff;
931 *(adler++) = (vpninfo->deflate_adler32 >> 8) & 0xff;
932 *(adler) = vpninfo->deflate_adler32 & 0xff;
934 vpninfo->deflate_pkt->len = vpninfo->deflate_strm.total_out + 4;
936 vpn_progress(vpninfo, PRG_TRACE,
937 _("Sending compressed data packet of %d bytes\n"),
940 vpninfo->pending_deflated_pkt = this;
941 vpninfo->current_ssl_pkt = vpninfo->deflate_pkt;
944 memcpy(this->hdr, data_hdr, 8);
945 this->hdr[4] = this->len >> 8;
946 this->hdr[5] = this->len & 0xff;
948 vpn_progress(vpninfo, PRG_TRACE,
949 _("Sending uncompressed data packet of %d bytes\n"),
952 vpninfo->current_ssl_pkt = this;
954 goto handle_outgoing;
957 /* Work is not done if we just got rid of packets off the queue */
961 int cstp_bye(struct openconnect_info *vpninfo, const char *reason)
963 unsigned char *bye_pkt;
966 /* already lost connection? */
967 #if defined (OPENCONNECT_OPENSSL)
968 if (!vpninfo->https_ssl)
970 #elif defined (OPENCONNECT_GNUTLS)
971 if (!vpninfo->https_sess)
975 reason_len = strlen(reason);
976 bye_pkt = malloc(reason_len + 9);
980 memcpy(bye_pkt, data_hdr, 8);
981 memcpy(bye_pkt + 9, reason, reason_len);
983 bye_pkt[4] = (reason_len + 1) >> 8;
984 bye_pkt[5] = (reason_len + 1) & 0xff;
985 bye_pkt[6] = AC_PKT_DISCONN;
988 vpn_progress(vpninfo, PRG_INFO,
989 _("Send BYE packet: %s\n"), reason);
991 cstp_write(vpninfo, bye_pkt, reason_len + 9);