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);
149 static int start_cstp_connection(struct openconnect_info *vpninfo)
153 int retried = 0, sessid_found = 0;
154 struct vpn_option **next_dtls_option = &vpninfo->dtls_options;
155 struct vpn_option **next_cstp_option = &vpninfo->cstp_options;
156 struct vpn_option *old_cstp_opts = vpninfo->cstp_options;
157 struct vpn_option *old_dtls_opts = vpninfo->dtls_options;
158 const char *old_addr = vpninfo->vpn_addr;
159 const char *old_netmask = vpninfo->vpn_netmask;
160 const char *old_addr6 = vpninfo->vpn_addr6;
161 const char *old_netmask6 = vpninfo->vpn_netmask6;
162 struct split_include *inc;
165 /* Clear old options which will be overwritten */
166 vpninfo->vpn_addr = vpninfo->vpn_netmask = NULL;
167 vpninfo->vpn_addr6 = vpninfo->vpn_netmask6 = NULL;
168 vpninfo->cstp_options = vpninfo->dtls_options = NULL;
169 vpninfo->vpn_domain = vpninfo->vpn_proxy_pac = NULL;
170 vpninfo->banner = NULL;
173 vpninfo->vpn_dns[i] = vpninfo->vpn_nbns[i] = NULL;
175 for (inc = vpninfo->split_includes; inc; ) {
176 struct split_include *next = inc->next;
180 for (inc = vpninfo->split_excludes; inc; ) {
181 struct split_include *next = inc->next;
185 for (inc = vpninfo->split_dns; inc; ) {
186 struct split_include *next = inc->next;
190 vpninfo->split_dns = vpninfo->split_includes = vpninfo->split_excludes = NULL;
192 /* Create (new) random master key for DTLS connection, if needed */
193 if (vpninfo->dtls_times.last_rekey + vpninfo->dtls_times.rekey <
195 openconnect_random(vpninfo->dtls_secret, sizeof(vpninfo->dtls_secret))) {
196 fprintf(stderr, _("Failed to initialise DTLS secret\n"));
201 calculate_mtu(vpninfo, &base_mtu, &mtu);
204 buf_append(buf, sizeof(buf), "CONNECT /CSCOSSLC/tunnel HTTP/1.1\r\n");
205 buf_append(buf, sizeof(buf), "Host: %s\r\n", vpninfo->hostname);
206 buf_append(buf, sizeof(buf), "User-Agent: %s\r\n", vpninfo->useragent);
207 buf_append(buf, sizeof(buf), "Cookie: webvpn=%s\r\n", vpninfo->cookie);
208 buf_append(buf, sizeof(buf), "X-CSTP-Version: 1\r\n");
209 buf_append(buf, sizeof(buf), "X-CSTP-Hostname: %s\r\n", vpninfo->localname);
210 if (vpninfo->deflate && i < sizeof(buf))
211 buf_append(buf, sizeof(buf), "X-CSTP-Accept-Encoding: deflate;q=1.0\r\n");
213 buf_append(buf, sizeof(buf), "X-CSTP-Base-MTU: %d\r\n", base_mtu);
214 buf_append(buf, sizeof(buf), "X-CSTP-MTU: %d\r\n", mtu);
215 buf_append(buf, sizeof(buf), "X-CSTP-Address-Type: %s\r\n",
216 vpninfo->disable_ipv6?"IPv4":"IPv6,IPv4");
217 buf_append(buf, sizeof(buf), "X-DTLS-Master-Secret: ");
218 for (i = 0; i < sizeof(vpninfo->dtls_secret); i++)
219 buf_append(buf, sizeof(buf), "%02X", vpninfo->dtls_secret[i]);
220 buf_append(buf, sizeof(buf), "\r\nX-DTLS-CipherSuite: %s\r\n\r\n",
221 vpninfo->dtls_ciphers?:"AES256-SHA:AES128-SHA:DES-CBC3-SHA:DES-CBC-SHA");
223 openconnect_SSL_write(vpninfo, buf, strlen(buf));
225 if ((i = openconnect_SSL_gets(vpninfo, buf, 65536) < 0)) {
228 vpn_progress(vpninfo, PRG_ERR,
229 _("Error fetching HTTPS response\n"));
232 openconnect_close_https(vpninfo, 0);
234 if (openconnect_open_https(vpninfo)) {
235 vpn_progress(vpninfo, PRG_ERR,
236 _("Failed to open HTTPS connection to %s\n"),
245 if (strncmp(buf, "HTTP/1.1 200 ", 13)) {
246 if (!strncmp(buf, "HTTP/1.1 503 ", 13)) {
247 /* "Service Unavailable. Why? */
248 const char *reason = "<unknown>";
249 while ((i = openconnect_SSL_gets(vpninfo, buf, sizeof(buf)))) {
250 if (!strncmp(buf, "X-Reason: ", 10)) {
255 vpn_progress(vpninfo, PRG_ERR,
256 _("VPN service unavailable; reason: %s\n"),
260 vpn_progress(vpninfo, PRG_ERR,
261 _("Got inappropriate HTTP CONNECT response: %s\n"),
263 if (!strncmp(buf, "HTTP/1.1 401 ", 13))
268 vpn_progress(vpninfo, PRG_INFO, _("Got CONNECT response: %s\n"), buf);
270 /* We may have advertised it, but we only do it if the server agrees */
271 vpninfo->deflate = 0;
274 while ((i = openconnect_SSL_gets(vpninfo, buf, sizeof(buf)))) {
275 struct vpn_option *new_option;
281 colon = strchr(buf, ':');
290 if (strncmp(buf, "X-DTLS-", 7) &&
291 strncmp(buf, "X-CSTP-", 7))
294 new_option = malloc(sizeof(*new_option));
296 vpn_progress(vpninfo, PRG_ERR, _("No memory for options\n"));
299 new_option->option = strdup(buf);
300 new_option->value = strdup(colon);
301 new_option->next = NULL;
303 if (!new_option->option || !new_option->value) {
304 vpn_progress(vpninfo, PRG_ERR, _("No memory for options\n"));
308 vpn_progress(vpninfo, PRG_TRACE, "%s: %s\n", buf, colon);
310 if (!strncmp(buf, "X-DTLS-", 7)) {
311 *next_dtls_option = new_option;
312 next_dtls_option = &new_option->next;
314 if (!strcmp(buf + 7, "MTU")) {
315 int dtlsmtu = atol(colon);
318 } else if (!strcmp(buf + 7, "Session-ID")) {
319 if (strlen(colon) != 64) {
320 vpn_progress(vpninfo, PRG_ERR,
321 _("X-DTLS-Session-ID not 64 characters; is: \"%s\"\n"),
323 vpninfo->dtls_attempt_period = 0;
326 for (i = 0; i < 64; i += 2)
327 vpninfo->dtls_session_id[i/2] = unhex(colon + i);
329 time(&vpninfo->dtls_times.last_rekey);
333 /* CSTP options... */
334 *next_cstp_option = new_option;
335 next_cstp_option = &new_option->next;
338 if (!strcmp(buf + 7, "Keepalive")) {
339 vpninfo->ssl_times.keepalive = atol(colon);
340 } else if (!strcmp(buf + 7, "DPD")) {
342 if (j && (!vpninfo->ssl_times.dpd || j < vpninfo->ssl_times.dpd))
343 vpninfo->ssl_times.dpd = j;
344 } else if (!strcmp(buf + 7, "Rekey-Time")) {
345 vpninfo->ssl_times.rekey = atol(colon);
346 } else if (!strcmp(buf + 7, "Content-Encoding")) {
347 if (!strcmp(colon, "deflate"))
348 vpninfo->deflate = 1;
350 vpn_progress(vpninfo, PRG_ERR,
351 _("Unknown CSTP-Content-Encoding %s\n"),
355 } else if (!strcmp(buf + 7, "MTU")) {
356 int cstpmtu = atol(colon);
359 } else if (!strcmp(buf + 7, "Address")) {
360 if (strchr(new_option->value, ':')) {
361 if (!vpninfo->disable_ipv6)
362 vpninfo->vpn_addr6 = new_option->value;
364 vpninfo->vpn_addr = new_option->value;
365 } else if (!strcmp(buf + 7, "Netmask")) {
366 if (strchr(new_option->value, ':')) {
367 if (!vpninfo->disable_ipv6)
368 vpninfo->vpn_netmask6 = new_option->value;
370 vpninfo->vpn_netmask = new_option->value;
371 } else if (!strcmp(buf + 7, "DNS")) {
373 for (j = 0; j < 3; j++) {
374 if (!vpninfo->vpn_dns[j]) {
375 vpninfo->vpn_dns[j] = new_option->value;
379 } else if (!strcmp(buf + 7, "NBNS")) {
381 for (j = 0; j < 3; j++) {
382 if (!vpninfo->vpn_nbns[j]) {
383 vpninfo->vpn_nbns[j] = new_option->value;
387 } else if (!strcmp(buf + 7, "Default-Domain")) {
388 vpninfo->vpn_domain = new_option->value;
389 } else if (!strcmp(buf + 7, "MSIE-Proxy-PAC-URL")) {
390 vpninfo->vpn_proxy_pac = new_option->value;
391 } else if (!strcmp(buf + 7, "Banner")) {
392 vpninfo->banner = new_option->value;
393 } else if (!strcmp(buf + 7, "Split-DNS")) {
394 struct split_include *dns = malloc(sizeof(*dns));
397 dns->route = new_option->value;
398 dns->next = vpninfo->split_dns;
399 vpninfo->split_dns = dns;
400 } else if (!strcmp(buf + 7, "Split-Include")) {
401 struct split_include *inc = malloc(sizeof(*inc));
404 inc->route = new_option->value;
405 inc->next = vpninfo->split_includes;
406 vpninfo->split_includes = inc;
407 } else if (!strcmp(buf + 7, "Split-Exclude")) {
408 struct split_include *exc = malloc(sizeof(*exc));
411 exc->route = new_option->value;
412 exc->next = vpninfo->split_excludes;
413 vpninfo->split_excludes = exc;
418 vpn_progress(vpninfo, PRG_ERR,
419 _("No MTU received. Aborting\n"));
422 vpninfo->actual_mtu = mtu;
424 if (!vpninfo->vpn_addr && !vpninfo->vpn_addr6) {
425 vpn_progress(vpninfo, PRG_ERR,
426 _("No IP address received. Aborting\n"));
430 if (strcmp(old_addr, vpninfo->vpn_addr)) {
431 vpn_progress(vpninfo, PRG_ERR,
432 _("Reconnect gave different Legacy IP address (%s != %s)\n"),
433 vpninfo->vpn_addr, old_addr);
438 if (strcmp(old_netmask, vpninfo->vpn_netmask)) {
439 vpn_progress(vpninfo, PRG_ERR,
440 _("Reconnect gave different Legacy IP netmask (%s != %s)\n"),
441 vpninfo->vpn_netmask, old_netmask);
446 if (strcmp(old_addr6, vpninfo->vpn_addr6)) {
447 vpn_progress(vpninfo, PRG_ERR,
448 _("Reconnect gave different IPv6 address (%s != %s)\n"),
449 vpninfo->vpn_addr6, old_addr6);
454 if (strcmp(old_netmask6, vpninfo->vpn_netmask6)) {
455 vpn_progress(vpninfo, PRG_ERR,
456 _("Reconnect gave different IPv6 netmask (%s != %s)\n"),
457 vpninfo->vpn_netmask6, old_netmask6);
462 while (old_dtls_opts) {
463 struct vpn_option *tmp = old_dtls_opts;
464 old_dtls_opts = old_dtls_opts->next;
469 while (old_cstp_opts) {
470 struct vpn_option *tmp = old_cstp_opts;
471 old_cstp_opts = old_cstp_opts->next;
476 vpn_progress(vpninfo, PRG_INFO, _("CSTP connected. DPD %d, Keepalive %d\n"),
477 vpninfo->ssl_times.dpd, vpninfo->ssl_times.keepalive);
479 if (vpninfo->select_nfds <= vpninfo->ssl_fd)
480 vpninfo->select_nfds = vpninfo->ssl_fd + 1;
482 FD_SET(vpninfo->ssl_fd, &vpninfo->select_rfds);
483 FD_SET(vpninfo->ssl_fd, &vpninfo->select_efds);
486 vpninfo->dtls_attempt_period = 0;
488 vpninfo->ssl_times.last_rekey = vpninfo->ssl_times.last_rx =
489 vpninfo->ssl_times.last_tx = time(NULL);
494 int make_cstp_connection(struct openconnect_info *vpninfo)
498 ret = openconnect_open_https(vpninfo);
502 if (vpninfo->deflate) {
503 vpninfo->deflate_adler32 = 1;
504 vpninfo->inflate_adler32 = 1;
506 if (inflateInit2(&vpninfo->inflate_strm, -12) ||
507 deflateInit2(&vpninfo->deflate_strm, Z_DEFAULT_COMPRESSION,
508 Z_DEFLATED, -12, 9, Z_DEFAULT_STRATEGY)) {
509 vpn_progress(vpninfo, PRG_ERR, _("Compression setup failed\n"));
510 vpninfo->deflate = 0;
513 if (!vpninfo->deflate_pkt) {
514 vpninfo->deflate_pkt = malloc(sizeof(struct pkt) + 2048);
515 if (!vpninfo->deflate_pkt) {
516 vpn_progress(vpninfo, PRG_ERR,
517 _("Allocation of deflate buffer failed\n"));
518 inflateEnd(&vpninfo->inflate_strm);
519 deflateEnd(&vpninfo->deflate_strm);
520 vpninfo->deflate = 0;
522 memset(vpninfo->deflate_pkt, 0, sizeof(struct pkt));
523 memcpy(vpninfo->deflate_pkt->hdr, data_hdr, 8);
524 vpninfo->deflate_pkt->hdr[6] = AC_PKT_COMPRESSED;
529 return start_cstp_connection(vpninfo);
532 int cstp_reconnect(struct openconnect_info *vpninfo)
538 openconnect_close_https(vpninfo, 0);
540 if (vpninfo->deflate) {
541 /* Requeue the original packet that was deflated */
542 if (vpninfo->current_ssl_pkt == vpninfo->deflate_pkt) {
543 vpninfo->current_ssl_pkt = NULL;
544 queue_packet(&vpninfo->outgoing_queue, vpninfo->pending_deflated_pkt);
545 vpninfo->pending_deflated_pkt = NULL;
547 inflateEnd(&vpninfo->inflate_strm);
548 deflateEnd(&vpninfo->deflate_strm);
550 timeout = vpninfo->reconnect_timeout;
551 interval = vpninfo->reconnect_interval;
553 while ((ret = make_cstp_connection(vpninfo))) {
556 vpn_progress(vpninfo, PRG_INFO,
557 _("sleep %ds, remaining timeout %ds\n"),
563 interval += vpninfo->reconnect_interval;
564 if (interval > RECONNECT_INTERVAL_MAX)
565 interval = RECONNECT_INTERVAL_MAX;
567 script_config_tun(vpninfo, "reconnect");
571 static int inflate_and_queue_packet(struct openconnect_info *vpninfo,
572 unsigned char *buf, int len)
574 struct pkt *new = malloc(sizeof(struct pkt) + vpninfo->actual_mtu);
582 vpninfo->inflate_strm.next_in = buf;
583 vpninfo->inflate_strm.avail_in = len - 4;
585 vpninfo->inflate_strm.next_out = new->data;
586 vpninfo->inflate_strm.avail_out = vpninfo->actual_mtu;
587 vpninfo->inflate_strm.total_out = 0;
589 if (inflate(&vpninfo->inflate_strm, Z_SYNC_FLUSH)) {
590 vpn_progress(vpninfo, PRG_ERR, _("inflate failed\n"));
595 new->len = vpninfo->inflate_strm.total_out;
597 vpninfo->inflate_adler32 = adler32(vpninfo->inflate_adler32,
598 new->data, new->len);
600 pkt_sum = buf[len - 1] | (buf[len - 2] << 8) |
601 (buf[len - 3] << 16) | (buf[len - 4] << 24);
603 if (vpninfo->inflate_adler32 != pkt_sum) {
604 vpninfo->quit_reason = "Compression (inflate) adler32 failure";
607 vpn_progress(vpninfo, PRG_TRACE,
608 _("Received compressed data packet of %ld bytes\n"),
609 (long)vpninfo->inflate_strm.total_out);
611 queue_packet(&vpninfo->incoming_queue, new);
615 #if defined (OPENCONNECT_OPENSSL)
616 static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
620 len = SSL_read(vpninfo->https_ssl, buf, maxlen);
624 ret = SSL_get_error(vpninfo->https_ssl, len);
625 if (ret == SSL_ERROR_SYSCALL || ret == SSL_ERROR_ZERO_RETURN) {
626 vpn_progress(vpninfo, PRG_ERR,
627 _("SSL read error %d (server probably closed connection); reconnecting.\n"),
634 static int cstp_write(struct openconnect_info *vpninfo, void *buf, int buflen)
638 ret = SSL_write(vpninfo->https_ssl, buf, buflen);
642 ret = SSL_get_error(vpninfo->https_ssl, ret);
644 case SSL_ERROR_WANT_WRITE:
645 /* Waiting for the socket to become writable -- it's
646 probably stalled, and/or the buffers are full */
647 FD_SET(vpninfo->ssl_fd, &vpninfo->select_wfds);
648 case SSL_ERROR_WANT_READ:
652 vpn_progress(vpninfo, PRG_ERR, _("SSL_write failed: %d\n"), ret);
653 openconnect_report_ssl_errors(vpninfo);
657 #elif defined (OPENCONNECT_GNUTLS)
658 static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
662 ret = gnutls_record_recv(vpninfo->https_sess, buf, maxlen);
666 if (ret != GNUTLS_E_AGAIN) {
667 vpn_progress(vpninfo, PRG_ERR,
668 _("SSL read error: %s; reconnecting.\n"),
669 gnutls_strerror(ret));
675 static int cstp_write(struct openconnect_info *vpninfo, void *buf, int buflen)
679 ret = gnutls_record_send(vpninfo->https_sess, buf, buflen);
683 if (ret == GNUTLS_E_AGAIN) {
684 if (gnutls_record_get_direction(vpninfo->https_sess)) {
685 /* Waiting for the socket to become writable -- it's
686 probably stalled, and/or the buffers are full */
687 FD_SET(vpninfo->ssl_fd, &vpninfo->select_wfds);
691 vpn_progress(vpninfo, PRG_ERR, _("SSL send failed: %s\n"),
692 gnutls_strerror(ret));
697 int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
699 unsigned char buf[16384];
703 /* FIXME: The poll() handling here is fairly simplistic. Actually,
704 if the SSL connection stalls it could return a WANT_WRITE error
705 on _either_ of the SSL_read() or SSL_write() calls. In that case,
706 we should probably remove POLLIN from the events we're looking for,
707 and add POLLOUT. As it is, though, it'll just chew CPU time in that
708 fairly unlikely situation, until the write backlog clears. */
709 while ( (len = cstp_read(vpninfo, buf, sizeof(buf))) > 0) {
712 if (buf[0] != 'S' || buf[1] != 'T' ||
713 buf[2] != 'F' || buf[3] != 1 || buf[7])
716 payload_len = (buf[4] << 8) + buf[5];
717 if (len != 8 + payload_len) {
718 vpn_progress(vpninfo, PRG_ERR,
719 _("Unexpected packet length. SSL_read returned %d but packet is\n"),
721 vpn_progress(vpninfo, PRG_ERR,
722 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
723 buf[0], buf[1], buf[2], buf[3],
724 buf[4], buf[5], buf[6], buf[7]);
727 vpninfo->ssl_times.last_rx = time(NULL);
730 vpn_progress(vpninfo, PRG_TRACE,
731 _("Got CSTP DPD request\n"));
732 vpninfo->owe_ssl_dpd_response = 1;
735 case AC_PKT_DPD_RESP:
736 vpn_progress(vpninfo, PRG_TRACE,
737 _("Got CSTP DPD response\n"));
740 case AC_PKT_KEEPALIVE:
741 vpn_progress(vpninfo, PRG_TRACE,
742 _("Got CSTP Keepalive\n"));
746 vpn_progress(vpninfo, PRG_TRACE,
747 _("Received uncompressed data packet of %d bytes\n"),
749 queue_new_packet(&vpninfo->incoming_queue, buf + 8,
754 case AC_PKT_DISCONN: {
756 for (i = 0; i < payload_len; i++) {
757 if (!isprint(buf[payload_len + 8 + i]))
758 buf[payload_len + 8 + i] = '.';
760 buf[payload_len + 8] = 0;
761 vpn_progress(vpninfo, PRG_ERR,
762 _("Received server disconnect: %02x '%s'\n"),
764 vpninfo->quit_reason = "Server request";
767 case AC_PKT_COMPRESSED:
768 if (!vpninfo->deflate) {
769 vpn_progress(vpninfo, PRG_ERR,
770 _("Compressed packet received in !deflate mode\n"));
773 inflate_and_queue_packet(vpninfo, buf + 8, payload_len);
777 case AC_PKT_TERM_SERVER:
778 vpn_progress(vpninfo, PRG_ERR, _("received server terminate packet\n"));
779 vpninfo->quit_reason = "Server request";
784 vpn_progress(vpninfo, PRG_ERR,
785 _("Unknown packet %02x %02x %02x %02x %02x %02x %02x %02x\n"),
786 buf[0], buf[1], buf[2], buf[3],
787 buf[4], buf[5], buf[6], buf[7]);
788 vpninfo->quit_reason = "Unknown packet received";
795 /* If SSL_write() fails we are expected to try again. With exactly
796 the same data, at exactly the same location. So we keep the
797 packet we had before.... */
798 if (vpninfo->current_ssl_pkt) {
800 vpninfo->ssl_times.last_tx = time(NULL);
801 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
803 ret = cstp_write(vpninfo,
804 vpninfo->current_ssl_pkt->hdr,
805 vpninfo->current_ssl_pkt->len + 8);
809 /* -EAGAIN: cstp_write() will have added the SSL fd to
810 ->select_wfds if appropriate, so we can just return
811 and wait. Unless it's been stalled for so long that
812 DPD kicks in and we kill the connection. */
813 switch (ka_stalled_action(&vpninfo->ssl_times, timeout)) {
821 /* This should never happen */
826 if (ret != vpninfo->current_ssl_pkt->len + 8) {
827 vpn_progress(vpninfo, PRG_ERR,
828 _("SSL wrote too few bytes! Asked for %d, sent %d\n"),
829 vpninfo->current_ssl_pkt->len + 8, ret);
830 vpninfo->quit_reason = "Internal error";
833 /* Don't free the 'special' packets */
834 if (vpninfo->current_ssl_pkt == vpninfo->deflate_pkt)
835 free(vpninfo->pending_deflated_pkt);
836 else if (vpninfo->current_ssl_pkt != &dpd_pkt &&
837 vpninfo->current_ssl_pkt != &dpd_resp_pkt &&
838 vpninfo->current_ssl_pkt != &keepalive_pkt)
839 free(vpninfo->current_ssl_pkt);
841 vpninfo->current_ssl_pkt = NULL;
844 if (vpninfo->owe_ssl_dpd_response) {
845 vpninfo->owe_ssl_dpd_response = 0;
846 vpninfo->current_ssl_pkt = &dpd_resp_pkt;
847 goto handle_outgoing;
850 switch (keepalive_action(&vpninfo->ssl_times, timeout)) {
853 /* Not that this will ever happen; we don't even process
854 the setting when we're asked for it. */
855 vpn_progress(vpninfo, PRG_INFO, _("CSTP rekey due\n"));
861 vpn_progress(vpninfo, PRG_ERR,
862 _("CSTP Dead Peer Detection detected dead peer!\n"));
864 if (cstp_reconnect(vpninfo)) {
865 vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
866 vpninfo->quit_reason = "CSTP reconnect failed";
869 /* I think we can leave DTLS to its own devices; when we reconnect
870 with the same master secret, we do seem to get the same sessid */
874 vpn_progress(vpninfo, PRG_TRACE, _("Send CSTP DPD\n"));
876 vpninfo->current_ssl_pkt = &dpd_pkt;
877 goto handle_outgoing;
880 /* No need to send an explicit keepalive
881 if we have real data to send */
882 if (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue)
885 vpn_progress(vpninfo, PRG_TRACE, _("Send CSTP Keepalive\n"));
887 vpninfo->current_ssl_pkt = &keepalive_pkt;
888 goto handle_outgoing;
894 /* Service outgoing packet queue, if no DTLS */
895 while (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue) {
896 struct pkt *this = vpninfo->outgoing_queue;
897 vpninfo->outgoing_queue = this->next;
898 vpninfo->outgoing_qlen--;
900 if (vpninfo->deflate) {
901 unsigned char *adler;
904 vpninfo->deflate_strm.next_in = this->data;
905 vpninfo->deflate_strm.avail_in = this->len;
906 vpninfo->deflate_strm.next_out = (void *)vpninfo->deflate_pkt->data;
907 vpninfo->deflate_strm.avail_out = 2040;
908 vpninfo->deflate_strm.total_out = 0;
910 ret = deflate(&vpninfo->deflate_strm, Z_SYNC_FLUSH);
912 vpn_progress(vpninfo, PRG_ERR, _("deflate failed %d\n"), ret);
916 vpninfo->deflate_pkt->hdr[4] = (vpninfo->deflate_strm.total_out + 4) >> 8;
917 vpninfo->deflate_pkt->hdr[5] = (vpninfo->deflate_strm.total_out + 4) & 0xff;
919 /* Add ongoing adler32 to tail of compressed packet */
920 vpninfo->deflate_adler32 = adler32(vpninfo->deflate_adler32,
921 this->data, this->len);
923 adler = &vpninfo->deflate_pkt->data[vpninfo->deflate_strm.total_out];
924 *(adler++) = vpninfo->deflate_adler32 >> 24;
925 *(adler++) = (vpninfo->deflate_adler32 >> 16) & 0xff;
926 *(adler++) = (vpninfo->deflate_adler32 >> 8) & 0xff;
927 *(adler) = vpninfo->deflate_adler32 & 0xff;
929 vpninfo->deflate_pkt->len = vpninfo->deflate_strm.total_out + 4;
931 vpn_progress(vpninfo, PRG_TRACE,
932 _("Sending compressed data packet of %d bytes\n"),
935 vpninfo->pending_deflated_pkt = this;
936 vpninfo->current_ssl_pkt = vpninfo->deflate_pkt;
939 memcpy(this->hdr, data_hdr, 8);
940 this->hdr[4] = this->len >> 8;
941 this->hdr[5] = this->len & 0xff;
943 vpn_progress(vpninfo, PRG_TRACE,
944 _("Sending uncompressed data packet of %d bytes\n"),
947 vpninfo->current_ssl_pkt = this;
949 goto handle_outgoing;
952 /* Work is not done if we just got rid of packets off the queue */
956 int cstp_bye(struct openconnect_info *vpninfo, const char *reason)
958 unsigned char *bye_pkt;
961 /* already lost connection? */
962 #if defined (OPENCONNECT_OPENSSL)
963 if (!vpninfo->https_ssl)
965 #elif defined (OPENCONNECT_GNUTLS)
966 if (!vpninfo->https_sess)
970 reason_len = strlen(reason);
971 bye_pkt = malloc(reason_len + 9);
975 memcpy(bye_pkt, data_hdr, 8);
976 memcpy(bye_pkt + 9, reason, reason_len);
978 bye_pkt[4] = (reason_len + 1) >> 8;
979 bye_pkt[5] = (reason_len + 1) & 0xff;
980 bye_pkt[6] = AC_PKT_DISCONN;
983 vpn_progress(vpninfo, PRG_INFO,
984 _("Send BYE packet: %s\n"), reason);
986 cstp_write(vpninfo, bye_pkt, reason_len + 9);