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"));
305 free(new_option->option);
306 free(new_option->value);
311 vpn_progress(vpninfo, PRG_TRACE, "%s: %s\n", buf, colon);
313 if (!strncmp(buf, "X-DTLS-", 7)) {
314 *next_dtls_option = new_option;
315 next_dtls_option = &new_option->next;
317 if (!strcmp(buf + 7, "MTU")) {
318 int dtlsmtu = atol(colon);
321 } else if (!strcmp(buf + 7, "Session-ID")) {
322 if (strlen(colon) != 64) {
323 vpn_progress(vpninfo, PRG_ERR,
324 _("X-DTLS-Session-ID not 64 characters; is: \"%s\"\n"),
326 vpninfo->dtls_attempt_period = 0;
329 for (i = 0; i < 64; i += 2)
330 vpninfo->dtls_session_id[i/2] = unhex(colon + i);
332 time(&vpninfo->dtls_times.last_rekey);
336 /* CSTP options... */
337 *next_cstp_option = new_option;
338 next_cstp_option = &new_option->next;
341 if (!strcmp(buf + 7, "Keepalive")) {
342 vpninfo->ssl_times.keepalive = atol(colon);
343 } else if (!strcmp(buf + 7, "DPD")) {
345 if (j && (!vpninfo->ssl_times.dpd || j < vpninfo->ssl_times.dpd))
346 vpninfo->ssl_times.dpd = j;
347 } else if (!strcmp(buf + 7, "Rekey-Time")) {
348 vpninfo->ssl_times.rekey = atol(colon);
349 } else if (!strcmp(buf + 7, "Content-Encoding")) {
350 if (!strcmp(colon, "deflate"))
351 vpninfo->deflate = 1;
353 vpn_progress(vpninfo, PRG_ERR,
354 _("Unknown CSTP-Content-Encoding %s\n"),
358 } else if (!strcmp(buf + 7, "MTU")) {
359 int cstpmtu = atol(colon);
362 } else if (!strcmp(buf + 7, "Address")) {
363 if (strchr(new_option->value, ':')) {
364 if (!vpninfo->disable_ipv6)
365 vpninfo->vpn_addr6 = new_option->value;
367 vpninfo->vpn_addr = new_option->value;
368 } else if (!strcmp(buf + 7, "Netmask")) {
369 if (strchr(new_option->value, ':')) {
370 if (!vpninfo->disable_ipv6)
371 vpninfo->vpn_netmask6 = new_option->value;
373 vpninfo->vpn_netmask = new_option->value;
374 } else if (!strcmp(buf + 7, "DNS")) {
376 for (j = 0; j < 3; j++) {
377 if (!vpninfo->vpn_dns[j]) {
378 vpninfo->vpn_dns[j] = new_option->value;
382 } else if (!strcmp(buf + 7, "NBNS")) {
384 for (j = 0; j < 3; j++) {
385 if (!vpninfo->vpn_nbns[j]) {
386 vpninfo->vpn_nbns[j] = new_option->value;
390 } else if (!strcmp(buf + 7, "Default-Domain")) {
391 vpninfo->vpn_domain = new_option->value;
392 } else if (!strcmp(buf + 7, "MSIE-Proxy-PAC-URL")) {
393 vpninfo->vpn_proxy_pac = new_option->value;
394 } else if (!strcmp(buf + 7, "Banner")) {
395 vpninfo->banner = new_option->value;
396 } else if (!strcmp(buf + 7, "Split-DNS")) {
397 struct split_include *dns = malloc(sizeof(*dns));
400 dns->route = new_option->value;
401 dns->next = vpninfo->split_dns;
402 vpninfo->split_dns = dns;
403 } else if (!strcmp(buf + 7, "Split-Include")) {
404 struct split_include *inc = malloc(sizeof(*inc));
407 inc->route = new_option->value;
408 inc->next = vpninfo->split_includes;
409 vpninfo->split_includes = inc;
410 } else if (!strcmp(buf + 7, "Split-Exclude")) {
411 struct split_include *exc = malloc(sizeof(*exc));
414 exc->route = new_option->value;
415 exc->next = vpninfo->split_excludes;
416 vpninfo->split_excludes = exc;
421 vpn_progress(vpninfo, PRG_ERR,
422 _("No MTU received. Aborting\n"));
425 vpninfo->actual_mtu = mtu;
427 if (!vpninfo->vpn_addr && !vpninfo->vpn_addr6) {
428 vpn_progress(vpninfo, PRG_ERR,
429 _("No IP address received. Aborting\n"));
433 if (strcmp(old_addr, vpninfo->vpn_addr)) {
434 vpn_progress(vpninfo, PRG_ERR,
435 _("Reconnect gave different Legacy IP address (%s != %s)\n"),
436 vpninfo->vpn_addr, old_addr);
441 if (strcmp(old_netmask, vpninfo->vpn_netmask)) {
442 vpn_progress(vpninfo, PRG_ERR,
443 _("Reconnect gave different Legacy IP netmask (%s != %s)\n"),
444 vpninfo->vpn_netmask, old_netmask);
449 if (strcmp(old_addr6, vpninfo->vpn_addr6)) {
450 vpn_progress(vpninfo, PRG_ERR,
451 _("Reconnect gave different IPv6 address (%s != %s)\n"),
452 vpninfo->vpn_addr6, old_addr6);
457 if (strcmp(old_netmask6, vpninfo->vpn_netmask6)) {
458 vpn_progress(vpninfo, PRG_ERR,
459 _("Reconnect gave different IPv6 netmask (%s != %s)\n"),
460 vpninfo->vpn_netmask6, old_netmask6);
465 while (old_dtls_opts) {
466 struct vpn_option *tmp = old_dtls_opts;
467 old_dtls_opts = old_dtls_opts->next;
472 while (old_cstp_opts) {
473 struct vpn_option *tmp = old_cstp_opts;
474 old_cstp_opts = old_cstp_opts->next;
479 vpn_progress(vpninfo, PRG_INFO, _("CSTP connected. DPD %d, Keepalive %d\n"),
480 vpninfo->ssl_times.dpd, vpninfo->ssl_times.keepalive);
482 if (vpninfo->select_nfds <= vpninfo->ssl_fd)
483 vpninfo->select_nfds = vpninfo->ssl_fd + 1;
485 FD_SET(vpninfo->ssl_fd, &vpninfo->select_rfds);
486 FD_SET(vpninfo->ssl_fd, &vpninfo->select_efds);
489 vpninfo->dtls_attempt_period = 0;
491 vpninfo->ssl_times.last_rekey = vpninfo->ssl_times.last_rx =
492 vpninfo->ssl_times.last_tx = time(NULL);
497 int make_cstp_connection(struct openconnect_info *vpninfo)
501 ret = openconnect_open_https(vpninfo);
505 if (vpninfo->deflate) {
506 vpninfo->deflate_adler32 = 1;
507 vpninfo->inflate_adler32 = 1;
509 if (inflateInit2(&vpninfo->inflate_strm, -12) ||
510 deflateInit2(&vpninfo->deflate_strm, Z_DEFAULT_COMPRESSION,
511 Z_DEFLATED, -12, 9, Z_DEFAULT_STRATEGY)) {
512 vpn_progress(vpninfo, PRG_ERR, _("Compression setup failed\n"));
513 vpninfo->deflate = 0;
516 if (!vpninfo->deflate_pkt) {
517 vpninfo->deflate_pkt = malloc(sizeof(struct pkt) + 2048);
518 if (!vpninfo->deflate_pkt) {
519 vpn_progress(vpninfo, PRG_ERR,
520 _("Allocation of deflate buffer failed\n"));
521 inflateEnd(&vpninfo->inflate_strm);
522 deflateEnd(&vpninfo->deflate_strm);
523 vpninfo->deflate = 0;
525 memset(vpninfo->deflate_pkt, 0, sizeof(struct pkt));
526 memcpy(vpninfo->deflate_pkt->hdr, data_hdr, 8);
527 vpninfo->deflate_pkt->hdr[6] = AC_PKT_COMPRESSED;
532 return start_cstp_connection(vpninfo);
535 int cstp_reconnect(struct openconnect_info *vpninfo)
541 openconnect_close_https(vpninfo, 0);
543 if (vpninfo->deflate) {
544 /* Requeue the original packet that was deflated */
545 if (vpninfo->current_ssl_pkt == vpninfo->deflate_pkt) {
546 vpninfo->current_ssl_pkt = NULL;
547 queue_packet(&vpninfo->outgoing_queue, vpninfo->pending_deflated_pkt);
548 vpninfo->pending_deflated_pkt = NULL;
550 inflateEnd(&vpninfo->inflate_strm);
551 deflateEnd(&vpninfo->deflate_strm);
553 timeout = vpninfo->reconnect_timeout;
554 interval = vpninfo->reconnect_interval;
556 while ((ret = make_cstp_connection(vpninfo))) {
559 vpn_progress(vpninfo, PRG_INFO,
560 _("sleep %ds, remaining timeout %ds\n"),
566 interval += vpninfo->reconnect_interval;
567 if (interval > RECONNECT_INTERVAL_MAX)
568 interval = RECONNECT_INTERVAL_MAX;
570 script_config_tun(vpninfo, "reconnect");
574 static int inflate_and_queue_packet(struct openconnect_info *vpninfo,
575 unsigned char *buf, int len)
577 struct pkt *new = malloc(sizeof(struct pkt) + vpninfo->actual_mtu);
585 vpninfo->inflate_strm.next_in = buf;
586 vpninfo->inflate_strm.avail_in = len - 4;
588 vpninfo->inflate_strm.next_out = new->data;
589 vpninfo->inflate_strm.avail_out = vpninfo->actual_mtu;
590 vpninfo->inflate_strm.total_out = 0;
592 if (inflate(&vpninfo->inflate_strm, Z_SYNC_FLUSH)) {
593 vpn_progress(vpninfo, PRG_ERR, _("inflate failed\n"));
598 new->len = vpninfo->inflate_strm.total_out;
600 vpninfo->inflate_adler32 = adler32(vpninfo->inflate_adler32,
601 new->data, new->len);
603 pkt_sum = buf[len - 1] | (buf[len - 2] << 8) |
604 (buf[len - 3] << 16) | (buf[len - 4] << 24);
606 if (vpninfo->inflate_adler32 != pkt_sum) {
607 vpninfo->quit_reason = "Compression (inflate) adler32 failure";
610 vpn_progress(vpninfo, PRG_TRACE,
611 _("Received compressed data packet of %ld bytes\n"),
612 (long)vpninfo->inflate_strm.total_out);
614 queue_packet(&vpninfo->incoming_queue, new);
618 #if defined (OPENCONNECT_OPENSSL)
619 static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
623 len = SSL_read(vpninfo->https_ssl, buf, maxlen);
627 ret = SSL_get_error(vpninfo->https_ssl, len);
628 if (ret == SSL_ERROR_SYSCALL || ret == SSL_ERROR_ZERO_RETURN) {
629 vpn_progress(vpninfo, PRG_ERR,
630 _("SSL read error %d (server probably closed connection); reconnecting.\n"),
637 static int cstp_write(struct openconnect_info *vpninfo, void *buf, int buflen)
641 ret = SSL_write(vpninfo->https_ssl, buf, buflen);
645 ret = SSL_get_error(vpninfo->https_ssl, ret);
647 case SSL_ERROR_WANT_WRITE:
648 /* Waiting for the socket to become writable -- it's
649 probably stalled, and/or the buffers are full */
650 FD_SET(vpninfo->ssl_fd, &vpninfo->select_wfds);
651 case SSL_ERROR_WANT_READ:
655 vpn_progress(vpninfo, PRG_ERR, _("SSL_write failed: %d\n"), ret);
656 openconnect_report_ssl_errors(vpninfo);
660 #elif defined (OPENCONNECT_GNUTLS)
661 static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
665 ret = gnutls_record_recv(vpninfo->https_sess, buf, maxlen);
669 if (ret != GNUTLS_E_AGAIN) {
670 vpn_progress(vpninfo, PRG_ERR,
671 _("SSL read error: %s; reconnecting.\n"),
672 gnutls_strerror(ret));
678 static int cstp_write(struct openconnect_info *vpninfo, void *buf, int buflen)
682 ret = gnutls_record_send(vpninfo->https_sess, buf, buflen);
686 if (ret == GNUTLS_E_AGAIN) {
687 if (gnutls_record_get_direction(vpninfo->https_sess)) {
688 /* Waiting for the socket to become writable -- it's
689 probably stalled, and/or the buffers are full */
690 FD_SET(vpninfo->ssl_fd, &vpninfo->select_wfds);
694 vpn_progress(vpninfo, PRG_ERR, _("SSL send failed: %s\n"),
695 gnutls_strerror(ret));
700 int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
702 unsigned char buf[16384];
706 /* FIXME: The poll() handling here is fairly simplistic. Actually,
707 if the SSL connection stalls it could return a WANT_WRITE error
708 on _either_ of the SSL_read() or SSL_write() calls. In that case,
709 we should probably remove POLLIN from the events we're looking for,
710 and add POLLOUT. As it is, though, it'll just chew CPU time in that
711 fairly unlikely situation, until the write backlog clears. */
712 while ( (len = cstp_read(vpninfo, buf, sizeof(buf))) > 0) {
715 if (buf[0] != 'S' || buf[1] != 'T' ||
716 buf[2] != 'F' || buf[3] != 1 || buf[7])
719 payload_len = (buf[4] << 8) + buf[5];
720 if (len != 8 + payload_len) {
721 vpn_progress(vpninfo, PRG_ERR,
722 _("Unexpected packet length. SSL_read returned %d but packet is\n"),
724 vpn_progress(vpninfo, PRG_ERR,
725 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
726 buf[0], buf[1], buf[2], buf[3],
727 buf[4], buf[5], buf[6], buf[7]);
730 vpninfo->ssl_times.last_rx = time(NULL);
733 vpn_progress(vpninfo, PRG_TRACE,
734 _("Got CSTP DPD request\n"));
735 vpninfo->owe_ssl_dpd_response = 1;
738 case AC_PKT_DPD_RESP:
739 vpn_progress(vpninfo, PRG_TRACE,
740 _("Got CSTP DPD response\n"));
743 case AC_PKT_KEEPALIVE:
744 vpn_progress(vpninfo, PRG_TRACE,
745 _("Got CSTP Keepalive\n"));
749 vpn_progress(vpninfo, PRG_TRACE,
750 _("Received uncompressed data packet of %d bytes\n"),
752 queue_new_packet(&vpninfo->incoming_queue, buf + 8,
757 case AC_PKT_DISCONN: {
759 for (i = 0; i < payload_len; i++) {
760 if (!isprint(buf[payload_len + 8 + i]))
761 buf[payload_len + 8 + i] = '.';
763 buf[payload_len + 8] = 0;
764 vpn_progress(vpninfo, PRG_ERR,
765 _("Received server disconnect: %02x '%s'\n"),
767 vpninfo->quit_reason = "Server request";
770 case AC_PKT_COMPRESSED:
771 if (!vpninfo->deflate) {
772 vpn_progress(vpninfo, PRG_ERR,
773 _("Compressed packet received in !deflate mode\n"));
776 inflate_and_queue_packet(vpninfo, buf + 8, payload_len);
780 case AC_PKT_TERM_SERVER:
781 vpn_progress(vpninfo, PRG_ERR, _("received server terminate packet\n"));
782 vpninfo->quit_reason = "Server request";
787 vpn_progress(vpninfo, PRG_ERR,
788 _("Unknown packet %02x %02x %02x %02x %02x %02x %02x %02x\n"),
789 buf[0], buf[1], buf[2], buf[3],
790 buf[4], buf[5], buf[6], buf[7]);
791 vpninfo->quit_reason = "Unknown packet received";
798 /* If SSL_write() fails we are expected to try again. With exactly
799 the same data, at exactly the same location. So we keep the
800 packet we had before.... */
801 if (vpninfo->current_ssl_pkt) {
803 vpninfo->ssl_times.last_tx = time(NULL);
804 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
806 ret = cstp_write(vpninfo,
807 vpninfo->current_ssl_pkt->hdr,
808 vpninfo->current_ssl_pkt->len + 8);
812 /* -EAGAIN: cstp_write() will have added the SSL fd to
813 ->select_wfds if appropriate, so we can just return
814 and wait. Unless it's been stalled for so long that
815 DPD kicks in and we kill the connection. */
816 switch (ka_stalled_action(&vpninfo->ssl_times, timeout)) {
824 /* This should never happen */
829 if (ret != vpninfo->current_ssl_pkt->len + 8) {
830 vpn_progress(vpninfo, PRG_ERR,
831 _("SSL wrote too few bytes! Asked for %d, sent %d\n"),
832 vpninfo->current_ssl_pkt->len + 8, ret);
833 vpninfo->quit_reason = "Internal error";
836 /* Don't free the 'special' packets */
837 if (vpninfo->current_ssl_pkt == vpninfo->deflate_pkt)
838 free(vpninfo->pending_deflated_pkt);
839 else if (vpninfo->current_ssl_pkt != &dpd_pkt &&
840 vpninfo->current_ssl_pkt != &dpd_resp_pkt &&
841 vpninfo->current_ssl_pkt != &keepalive_pkt)
842 free(vpninfo->current_ssl_pkt);
844 vpninfo->current_ssl_pkt = NULL;
847 if (vpninfo->owe_ssl_dpd_response) {
848 vpninfo->owe_ssl_dpd_response = 0;
849 vpninfo->current_ssl_pkt = &dpd_resp_pkt;
850 goto handle_outgoing;
853 switch (keepalive_action(&vpninfo->ssl_times, timeout)) {
856 /* Not that this will ever happen; we don't even process
857 the setting when we're asked for it. */
858 vpn_progress(vpninfo, PRG_INFO, _("CSTP rekey due\n"));
864 vpn_progress(vpninfo, PRG_ERR,
865 _("CSTP Dead Peer Detection detected dead peer!\n"));
867 if (cstp_reconnect(vpninfo)) {
868 vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
869 vpninfo->quit_reason = "CSTP reconnect failed";
872 /* I think we can leave DTLS to its own devices; when we reconnect
873 with the same master secret, we do seem to get the same sessid */
877 vpn_progress(vpninfo, PRG_TRACE, _("Send CSTP DPD\n"));
879 vpninfo->current_ssl_pkt = &dpd_pkt;
880 goto handle_outgoing;
883 /* No need to send an explicit keepalive
884 if we have real data to send */
885 if (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue)
888 vpn_progress(vpninfo, PRG_TRACE, _("Send CSTP Keepalive\n"));
890 vpninfo->current_ssl_pkt = &keepalive_pkt;
891 goto handle_outgoing;
897 /* Service outgoing packet queue, if no DTLS */
898 while (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue) {
899 struct pkt *this = vpninfo->outgoing_queue;
900 vpninfo->outgoing_queue = this->next;
901 vpninfo->outgoing_qlen--;
903 if (vpninfo->deflate) {
904 unsigned char *adler;
907 vpninfo->deflate_strm.next_in = this->data;
908 vpninfo->deflate_strm.avail_in = this->len;
909 vpninfo->deflate_strm.next_out = (void *)vpninfo->deflate_pkt->data;
910 vpninfo->deflate_strm.avail_out = 2040;
911 vpninfo->deflate_strm.total_out = 0;
913 ret = deflate(&vpninfo->deflate_strm, Z_SYNC_FLUSH);
915 vpn_progress(vpninfo, PRG_ERR, _("deflate failed %d\n"), ret);
919 vpninfo->deflate_pkt->hdr[4] = (vpninfo->deflate_strm.total_out + 4) >> 8;
920 vpninfo->deflate_pkt->hdr[5] = (vpninfo->deflate_strm.total_out + 4) & 0xff;
922 /* Add ongoing adler32 to tail of compressed packet */
923 vpninfo->deflate_adler32 = adler32(vpninfo->deflate_adler32,
924 this->data, this->len);
926 adler = &vpninfo->deflate_pkt->data[vpninfo->deflate_strm.total_out];
927 *(adler++) = vpninfo->deflate_adler32 >> 24;
928 *(adler++) = (vpninfo->deflate_adler32 >> 16) & 0xff;
929 *(adler++) = (vpninfo->deflate_adler32 >> 8) & 0xff;
930 *(adler) = vpninfo->deflate_adler32 & 0xff;
932 vpninfo->deflate_pkt->len = vpninfo->deflate_strm.total_out + 4;
934 vpn_progress(vpninfo, PRG_TRACE,
935 _("Sending compressed data packet of %d bytes\n"),
938 vpninfo->pending_deflated_pkt = this;
939 vpninfo->current_ssl_pkt = vpninfo->deflate_pkt;
942 memcpy(this->hdr, data_hdr, 8);
943 this->hdr[4] = this->len >> 8;
944 this->hdr[5] = this->len & 0xff;
946 vpn_progress(vpninfo, PRG_TRACE,
947 _("Sending uncompressed data packet of %d bytes\n"),
950 vpninfo->current_ssl_pkt = this;
952 goto handle_outgoing;
955 /* Work is not done if we just got rid of packets off the queue */
959 int cstp_bye(struct openconnect_info *vpninfo, const char *reason)
961 unsigned char *bye_pkt;
964 /* already lost connection? */
965 #if defined (OPENCONNECT_OPENSSL)
966 if (!vpninfo->https_ssl)
968 #elif defined (OPENCONNECT_GNUTLS)
969 if (!vpninfo->https_sess)
973 reason_len = strlen(reason);
974 bye_pkt = malloc(reason_len + 9);
978 memcpy(bye_pkt, data_hdr, 8);
979 memcpy(bye_pkt + 9, reason, reason_len);
981 bye_pkt[4] = (reason_len + 1) >> 8;
982 bye_pkt[5] = (reason_len + 1) & 0xff;
983 bye_pkt[6] = AC_PKT_DISCONN;
986 vpn_progress(vpninfo, PRG_INFO,
987 _("Send BYE packet: %s\n"), reason);
989 cstp_write(vpninfo, bye_pkt, reason_len + 9);