Update translations from Transifex
[platform/upstream/openconnect.git] / cstp.c
1 /*
2  * OpenConnect (SSL + DTLS) VPN client
3  *
4  * Copyright © 2008-2012 Intel Corporation.
5  * Copyright © 2008 Nick Andrew <nick@nick-andrew.net>
6  *
7  * Author: David Woodhouse <dwmw2@infradead.org>
8  *
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.
12  *
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.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to:
20  *
21  *   Free Software Foundation, Inc.
22  *   51 Franklin Street, Fifth Floor,
23  *   Boston, MA 02110-1301 USA
24  */
25
26 #include <netdb.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <time.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <errno.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <netinet/tcp.h>
39 #include <stdarg.h>
40
41 #include "openconnect-internal.h"
42
43 /*
44  * Data packets are encapsulated in the SSL stream as follows:
45  *
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)
49  * 0008: data payload
50  */
51
52 static char data_hdr[8] = {
53         'S', 'T', 'F', 1,
54         0, 0,           /* Length */
55         AC_PKT_DATA,    /* Type */
56         0               /* Unknown */
57 };
58
59 static struct pkt keepalive_pkt = {
60         .hdr = { 'S', 'T', 'F', 1, 0, 0, AC_PKT_KEEPALIVE, 0 },
61 };
62
63 static struct pkt dpd_pkt = {
64         .hdr = { 'S', 'T', 'F', 1, 0, 0, AC_PKT_DPD_OUT, 0 },
65 };
66
67 static struct pkt dpd_resp_pkt = {
68         .hdr = { 'S', 'T', 'F', 1, 0, 0, AC_PKT_DPD_RESP, 0 },
69 };
70
71 static int  __attribute__ ((format (printf, 3, 4)))
72     buf_append(char *buf, int len, const char *fmt, ...)
73 {
74         int start = strlen(buf);
75         int ret;
76         va_list args;
77
78         if (start >= len)
79                 return 0;
80
81         va_start(args, fmt);
82         ret = vsnprintf(buf + start, len - start, fmt, args);
83         va_end(args);
84
85         if (ret > len)
86                 ret = len;
87
88         return ret;
89 }
90
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
94  * and server.
95  *
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.
99  *
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...
103  *
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.
106  */
107 static void calculate_mtu(struct openconnect_info *vpninfo, int *base_mtu, int *mtu)
108 {
109         *mtu = vpninfo->reqmtu;
110         *base_mtu = vpninfo->basemtu;
111
112 #if defined(__linux__) && defined(TCP_INFO)
113         if (!*mtu || !*base_mtu) {
114                 struct tcp_info ti;
115                 socklen_t ti_size = sizeof(ti);
116
117                 if (!getsockopt(vpninfo->ssl_fd, IPPROTO_TCP, TCP_INFO,
118                                 &ti, &ti_size)) {
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;
123                         if (!*mtu) {
124                                 if (ti.tcpi_rcv_mss < ti.tcpi_snd_mss)
125                                         *mtu = ti.tcpi_rcv_mss - 13;
126                                 else
127                                         *mtu = ti.tcpi_snd_mss - 13;
128                         }
129                 }
130         }
131 #endif
132 #ifdef TCP_MAXSEG
133         if (!*mtu) {
134                 int mss;
135                 socklen_t mss_size = sizeof(mss);
136                 if (!getsockopt(vpninfo->ssl_fd, IPPROTO_TCP, TCP_MAXSEG,
137                                 &mss, &mss_size)) {
138                         vpn_progress(vpninfo, PRG_TRACE, _("TCP_MAXSEG %d\n"), mss);
139                         *mtu = mss - 13;
140                 }
141         }
142 #endif
143         if (!*mtu) {
144                 /* Default */
145                 *mtu = 1406;
146         }
147         if (*mtu < 1280)
148                 *mtu = 1280;
149 }
150
151 static int start_cstp_connection(struct openconnect_info *vpninfo)
152 {
153         char buf[65536];
154         int i;
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;
165         int base_mtu, mtu;
166
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;
173
174         for (i=0; i<3; i++)
175                 vpninfo->vpn_dns[i] = vpninfo->vpn_nbns[i] = NULL;
176
177         for (inc = vpninfo->split_includes; inc; ) {
178                 struct split_include *next = inc->next;
179                 free(inc);
180                 inc = next;
181         }
182         for (inc = vpninfo->split_excludes; inc; ) {
183                 struct split_include *next = inc->next;
184                 free(inc);
185                 inc = next;
186         }
187         for (inc = vpninfo->split_dns; inc; ) {
188                 struct split_include *next = inc->next;
189                 free(inc);
190                 inc = next;
191         }
192         vpninfo->split_dns = vpninfo->split_includes = vpninfo->split_excludes = NULL;
193
194         /* Create (new) random master key for DTLS connection, if needed */
195         if (vpninfo->dtls_times.last_rekey + vpninfo->dtls_times.rekey <
196             time(NULL) + 300 &&
197             openconnect_random(vpninfo->dtls_secret, sizeof(vpninfo->dtls_secret))) {
198                 fprintf(stderr, _("Failed to initialise DTLS secret\n"));
199                 exit(1);
200         }
201
202  retry:
203         calculate_mtu(vpninfo, &base_mtu, &mtu);
204
205         buf[0] = 0;
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");
214         if (base_mtu)
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");
224
225         openconnect_SSL_write(vpninfo, buf, strlen(buf));
226
227         if ((i = openconnect_SSL_gets(vpninfo, buf, 65536) < 0)) {
228                 if (i == -EINTR)
229                         return i;
230                 vpn_progress(vpninfo, PRG_ERR,
231                              _("Error fetching HTTPS response\n"));
232                 if (!retried) {
233                         retried = 1;
234                         openconnect_close_https(vpninfo, 0);
235
236                         if (openconnect_open_https(vpninfo)) {
237                                 vpn_progress(vpninfo, PRG_ERR,
238                                              _("Failed to open HTTPS connection to %s\n"),
239                                              vpninfo->hostname);
240                                 exit(1);
241                         }
242                         goto retry;
243                 }
244                 return -EINVAL;
245         }
246
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)) {
253                                         reason = buf + 10;
254                                         break;
255                                 }
256                         }
257                         vpn_progress(vpninfo, PRG_ERR,
258                                      _("VPN service unavailable; reason: %s\n"),
259                                      reason);
260                         return -EINVAL;
261                 }
262                 vpn_progress(vpninfo, PRG_ERR,
263                              _("Got inappropriate HTTP CONNECT response: %s\n"),
264                              buf);
265                 if (!strncmp(buf, "HTTP/1.1 401 ", 13))
266                         exit(2);
267                 return -EINVAL;
268         }
269
270         vpn_progress(vpninfo, PRG_INFO, _("Got CONNECT response: %s\n"), buf);
271
272         /* We may have advertised it, but we only do it if the server agrees */
273         vpninfo->deflate = 0;
274         mtu = 0;
275
276         while ((i = openconnect_SSL_gets(vpninfo, buf, sizeof(buf)))) {
277                 struct vpn_option *new_option;
278                 char *colon;
279
280                 if (i < 0)
281                         return i;
282
283                 colon = strchr(buf, ':');
284                 if (!colon)
285                         continue;
286
287                 *colon = 0;
288                 colon++;
289                 if (*colon == ' ')
290                         colon++;
291
292                 if (strncmp(buf, "X-DTLS-", 7) &&
293                     strncmp(buf, "X-CSTP-", 7))
294                         continue;
295
296                 new_option = malloc(sizeof(*new_option));
297                 if (!new_option) {
298                         vpn_progress(vpninfo, PRG_ERR, _("No memory for options\n"));
299                         return -ENOMEM;
300                 }
301                 new_option->option = strdup(buf);
302                 new_option->value = strdup(colon);
303                 new_option->next = NULL;
304
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);
309                         free(new_option);
310                         return -ENOMEM;
311                 }
312
313                 vpn_progress(vpninfo, PRG_TRACE, "%s: %s\n", buf, colon);
314
315                 if (!strncmp(buf, "X-DTLS-", 7)) {
316                         *next_dtls_option = new_option;
317                         next_dtls_option = &new_option->next;
318
319                         if (!strcmp(buf + 7, "MTU")) {
320                                 int dtlsmtu = atol(colon);
321                                 if (dtlsmtu > mtu)
322                                         mtu = dtlsmtu;
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"),
327                                                      colon);
328                                         vpninfo->dtls_attempt_period = 0;
329                                         return -EINVAL;
330                                 }
331                                 for (i = 0; i < 64; i += 2)
332                                         vpninfo->dtls_session_id[i/2] = unhex(colon + i);
333                                 sessid_found = 1;
334                                 time(&vpninfo->dtls_times.last_rekey);
335                         }
336                         continue;
337                 }
338                 /* CSTP options... */
339                 *next_cstp_option = new_option;
340                 next_cstp_option = &new_option->next;
341
342
343                 if (!strcmp(buf + 7, "Keepalive")) {
344                         vpninfo->ssl_times.keepalive = atol(colon);
345                 } else if (!strcmp(buf + 7, "DPD")) {
346                         int j = atol(colon);
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;
354                         else {
355                                 vpn_progress(vpninfo, PRG_ERR,
356                                              _("Unknown CSTP-Content-Encoding %s\n"),
357                                              colon);
358                                 return -EINVAL;
359                         }
360                 } else if (!strcmp(buf + 7, "MTU")) {
361                         int cstpmtu = atol(colon);
362                         if (cstpmtu > mtu)
363                                 mtu = cstpmtu;
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;
368                         } else
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;
374                         } else
375                                 vpninfo->vpn_netmask = new_option->value;
376                 } else if (!strcmp(buf + 7, "DNS")) {
377                         int j;
378                         for (j = 0; j < 3; j++) {
379                                 if (!vpninfo->vpn_dns[j]) {
380                                         vpninfo->vpn_dns[j] = new_option->value;
381                                         break;
382                                 }
383                         }
384                 } else if (!strcmp(buf + 7, "NBNS")) {
385                         int j;
386                         for (j = 0; j < 3; j++) {
387                                 if (!vpninfo->vpn_nbns[j]) {
388                                         vpninfo->vpn_nbns[j] = new_option->value;
389                                         break;
390                                 }
391                         }
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));
400                         if (!dns)
401                                 continue;
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));
407                         if (!inc)
408                                 continue;
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));
414                         if (!exc)
415                                 continue;
416                         exc->route = new_option->value;
417                         exc->next = vpninfo->split_excludes;
418                         vpninfo->split_excludes = exc;
419                 }
420         }
421
422         if (!mtu) {
423                 vpn_progress(vpninfo, PRG_ERR,
424                              _("No MTU received. Aborting\n"));
425                 return -EINVAL;
426         }
427         vpninfo->actual_mtu = mtu;
428
429         if (!vpninfo->vpn_addr && !vpninfo->vpn_addr6) {
430                 vpn_progress(vpninfo, PRG_ERR,
431                              _("No IP address received. Aborting\n"));
432                 return -EINVAL;
433         }
434         if (old_addr) {
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);
439                         return -EINVAL;
440                 }
441         }
442         if (old_netmask) {
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);
447                         return -EINVAL;
448                 }
449         }
450         if (old_addr6) {
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);
455                         return -EINVAL;
456                 }
457         }
458         if (old_netmask6) {
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);
463                         return -EINVAL;
464                 }
465         }
466
467         while (old_dtls_opts) {
468                 struct vpn_option *tmp = old_dtls_opts;
469                 old_dtls_opts = old_dtls_opts->next;
470                 free(tmp->value);
471                 free(tmp->option);
472                 free(tmp);
473         }
474         while (old_cstp_opts) {
475                 struct vpn_option *tmp = old_cstp_opts;
476                 old_cstp_opts = old_cstp_opts->next;
477                 free(tmp->value);
478                 free(tmp->option);
479                 free(tmp);
480         }
481         vpn_progress(vpninfo, PRG_INFO, _("CSTP connected. DPD %d, Keepalive %d\n"),
482                      vpninfo->ssl_times.dpd, vpninfo->ssl_times.keepalive);
483
484         if (vpninfo->select_nfds <= vpninfo->ssl_fd)
485                 vpninfo->select_nfds = vpninfo->ssl_fd + 1;
486
487         FD_SET(vpninfo->ssl_fd, &vpninfo->select_rfds);
488         FD_SET(vpninfo->ssl_fd, &vpninfo->select_efds);
489
490         if (!sessid_found)
491                 vpninfo->dtls_attempt_period = 0;
492
493         vpninfo->ssl_times.last_rekey = vpninfo->ssl_times.last_rx =
494                 vpninfo->ssl_times.last_tx = time(NULL);
495         return 0;
496 }
497
498
499 int make_cstp_connection(struct openconnect_info *vpninfo)
500 {
501         int ret;
502
503         ret = openconnect_open_https(vpninfo);
504         if (ret)
505                 return ret;
506
507         if (vpninfo->deflate) {
508                 vpninfo->deflate_adler32 = 1;
509                 vpninfo->inflate_adler32 = 1;
510
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;
516                 }
517
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;
526                         } else {
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;
530                         }
531                 }
532         }
533
534         return start_cstp_connection(vpninfo);
535 }
536
537 int cstp_reconnect(struct openconnect_info *vpninfo)
538 {
539         int ret;
540         int timeout;
541         int interval;
542
543         openconnect_close_https(vpninfo, 0);
544
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;
551                 }
552                 inflateEnd(&vpninfo->inflate_strm);
553                 deflateEnd(&vpninfo->deflate_strm);
554         }
555         timeout = vpninfo->reconnect_timeout;
556         interval = vpninfo->reconnect_interval;
557
558         while ((ret = make_cstp_connection(vpninfo))) {
559                 if (timeout <= 0)
560                         return ret;
561                 vpn_progress(vpninfo, PRG_INFO,
562                              _("sleep %ds, remaining timeout %ds\n"),
563                              interval, timeout);
564                 sleep(interval);
565                 if (killed)
566                         return 1;
567                 timeout -= interval;
568                 interval += vpninfo->reconnect_interval;
569                 if (interval > RECONNECT_INTERVAL_MAX)
570                         interval = RECONNECT_INTERVAL_MAX;
571         }
572         script_config_tun(vpninfo, "reconnect");
573         return 0;
574 }
575
576 static int inflate_and_queue_packet(struct openconnect_info *vpninfo,
577                                     unsigned char *buf, int len)
578 {
579         struct pkt *new = malloc(sizeof(struct pkt) + vpninfo->actual_mtu);
580         uint32_t pkt_sum;
581
582         if (!new)
583                 return -ENOMEM;
584
585         new->next = NULL;
586
587         vpninfo->inflate_strm.next_in = buf;
588         vpninfo->inflate_strm.avail_in = len - 4;
589
590         vpninfo->inflate_strm.next_out = new->data;
591         vpninfo->inflate_strm.avail_out = vpninfo->actual_mtu;
592         vpninfo->inflate_strm.total_out = 0;
593
594         if (inflate(&vpninfo->inflate_strm, Z_SYNC_FLUSH)) {
595                 vpn_progress(vpninfo, PRG_ERR, _("inflate failed\n"));
596                 free(new);
597                 return -EINVAL;
598         }
599
600         new->len = vpninfo->inflate_strm.total_out;
601
602         vpninfo->inflate_adler32 = adler32(vpninfo->inflate_adler32,
603                                            new->data, new->len);
604
605         pkt_sum = buf[len - 1] | (buf[len - 2] << 8) |
606                 (buf[len - 3] << 16) | (buf[len - 4] << 24);
607
608         if (vpninfo->inflate_adler32 != pkt_sum) {
609                 vpninfo->quit_reason = "Compression (inflate) adler32 failure";
610         }
611
612         vpn_progress(vpninfo, PRG_TRACE,
613                      _("Received compressed data packet of %ld bytes\n"),
614                      (long)vpninfo->inflate_strm.total_out);
615
616         queue_packet(&vpninfo->incoming_queue, new);
617         return 0;
618 }
619
620 #if defined (OPENCONNECT_OPENSSL)
621 static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
622 {
623         int len, ret;
624
625         len = SSL_read(vpninfo->https_ssl, buf, maxlen);
626         if (len > 0)
627                 return len;
628
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"),
633                              ret);
634                 return -EIO;
635         }
636         return 0;
637 }
638
639 static int cstp_write(struct openconnect_info *vpninfo, void *buf, int buflen)
640 {
641         int ret;
642
643         ret = SSL_write(vpninfo->https_ssl, buf, buflen);
644         if (ret > 0)
645                 return ret;
646
647         ret = SSL_get_error(vpninfo->https_ssl, ret);
648         switch (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:
654                 return 0;
655
656         default:
657                 vpn_progress(vpninfo, PRG_ERR, _("SSL_write failed: %d\n"), ret);
658                 openconnect_report_ssl_errors(vpninfo);
659                 return -1;
660         }
661 }
662 #elif defined (OPENCONNECT_GNUTLS)
663 static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
664 {
665         int ret;
666
667         ret = gnutls_record_recv(vpninfo->https_sess, buf, maxlen);
668         if (ret > 0)
669                 return ret;
670
671         if (ret != GNUTLS_E_AGAIN) {
672                 vpn_progress(vpninfo, PRG_ERR,
673                              _("SSL read error: %s; reconnecting.\n"),
674                              gnutls_strerror(ret));
675                 return -EIO;
676         }
677         return 0;
678 }
679
680 static int cstp_write(struct openconnect_info *vpninfo, void *buf, int buflen)
681 {
682         int ret;
683
684         ret = gnutls_record_send(vpninfo->https_sess, buf, buflen);
685         if (ret > 0)
686                 return ret;
687
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);
693                 }
694                 return 0;
695         }
696         vpn_progress(vpninfo, PRG_ERR, _("SSL send failed: %s\n"),
697                      gnutls_strerror(ret));
698         return -1;
699 }
700 #endif
701
702 int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
703 {
704         unsigned char buf[16384];
705         int len, ret;
706         int work_done = 0;
707
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) {
715                 int payload_len;
716
717                 if (buf[0] != 'S' || buf[1] != 'T' ||
718                     buf[2] != 'F' || buf[3] != 1 || buf[7])
719                         goto unknown_pkt;
720
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"),
725                                      len);
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]);
730                         continue;
731                 }
732                 vpninfo->ssl_times.last_rx = time(NULL);
733                 switch(buf[6]) {
734                 case AC_PKT_DPD_OUT:
735                         vpn_progress(vpninfo, PRG_TRACE,
736                                      _("Got CSTP DPD request\n"));
737                         vpninfo->owe_ssl_dpd_response = 1;
738                         continue;
739
740                 case AC_PKT_DPD_RESP:
741                         vpn_progress(vpninfo, PRG_TRACE,
742                                      _("Got CSTP DPD response\n"));
743                         continue;
744
745                 case AC_PKT_KEEPALIVE:
746                         vpn_progress(vpninfo, PRG_TRACE,
747                                      _("Got CSTP Keepalive\n"));
748                         continue;
749
750                 case AC_PKT_DATA:
751                         vpn_progress(vpninfo, PRG_TRACE,
752                                      _("Received uncompressed data packet of %d bytes\n"),
753                                      payload_len);
754                         queue_new_packet(&vpninfo->incoming_queue, buf + 8,
755                                          payload_len);
756                         work_done = 1;
757                         continue;
758
759                 case AC_PKT_DISCONN: {
760                         int i;
761                         for (i = 0; i < payload_len; i++) {
762                                 if (!isprint(buf[payload_len + 8 + i]))
763                                         buf[payload_len + 8 + i] = '.';
764                         }
765                         buf[payload_len + 8] = 0;
766                         vpn_progress(vpninfo, PRG_ERR,
767                                      _("Received server disconnect: %02x '%s'\n"),
768                                      buf[8], buf + 9);
769                         vpninfo->quit_reason = "Server request";
770                         return 1;
771                 }
772                 case AC_PKT_COMPRESSED:
773                         if (!vpninfo->deflate) {
774                                 vpn_progress(vpninfo, PRG_ERR,
775                                              _("Compressed packet received in !deflate mode\n"));
776                                 goto unknown_pkt;
777                         }
778                         inflate_and_queue_packet(vpninfo, buf + 8, payload_len);
779                         work_done = 1;
780                         continue;
781
782                 case AC_PKT_TERM_SERVER:
783                         vpn_progress(vpninfo, PRG_ERR, _("received server terminate packet\n"));
784                         vpninfo->quit_reason = "Server request";
785                         return 1;
786                 }
787
788         unknown_pkt:
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";
794                 return 1;
795         }
796         if (len < 0)
797                 goto do_reconnect;
798
799
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) {
804         handle_outgoing:
805                 vpninfo->ssl_times.last_tx = time(NULL);
806                 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
807
808                 ret = cstp_write(vpninfo,
809                                  vpninfo->current_ssl_pkt->hdr,
810                                  vpninfo->current_ssl_pkt->len + 8);
811                 if (ret < 0)
812                         goto do_reconnect;
813                 else if (!ret) {
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)) {
819                         case KA_DPD_DEAD:
820                                 goto peer_dead;
821                         case KA_REKEY:
822                                 goto do_rekey;
823                         case KA_NONE:
824                                 return work_done;
825                         default:
826                                 /* This should never happen */
827                                 ;
828                         }
829                 }
830
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";
836                         return 1;
837                 }
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);
845
846                 vpninfo->current_ssl_pkt = NULL;
847         }
848
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;
853         }
854
855         switch (keepalive_action(&vpninfo->ssl_times, timeout)) {
856         case KA_REKEY:
857         do_rekey:
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"));
861                 goto do_reconnect;
862                 break;
863
864         case KA_DPD_DEAD:
865         peer_dead:
866                 vpn_progress(vpninfo, PRG_ERR,
867                              _("CSTP Dead Peer Detection detected dead peer!\n"));
868         do_reconnect:
869                 if (cstp_reconnect(vpninfo)) {
870                         vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
871                         vpninfo->quit_reason = "CSTP reconnect failed";
872                         return 1;
873                 }
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 */
876                 return 1;
877
878         case KA_DPD:
879                 vpn_progress(vpninfo, PRG_TRACE, _("Send CSTP DPD\n"));
880
881                 vpninfo->current_ssl_pkt = &dpd_pkt;
882                 goto handle_outgoing;
883
884         case KA_KEEPALIVE:
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)
888                         break;
889
890                 vpn_progress(vpninfo, PRG_TRACE, _("Send CSTP Keepalive\n"));
891
892                 vpninfo->current_ssl_pkt = &keepalive_pkt;
893                 goto handle_outgoing;
894
895         case KA_NONE:
896                 ;
897         }
898
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--;
904
905                 if (vpninfo->deflate) {
906                         unsigned char *adler;
907                         int ret;
908
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;
914
915                         ret = deflate(&vpninfo->deflate_strm, Z_SYNC_FLUSH);
916                         if (ret) {
917                                 vpn_progress(vpninfo, PRG_ERR, _("deflate failed %d\n"), ret);
918                                 goto uncompr;
919                         }
920
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;
923
924                         /* Add ongoing adler32 to tail of compressed packet */
925                         vpninfo->deflate_adler32 = adler32(vpninfo->deflate_adler32,
926                                                            this->data, this->len);
927
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;
933
934                         vpninfo->deflate_pkt->len = vpninfo->deflate_strm.total_out + 4;
935
936                         vpn_progress(vpninfo, PRG_TRACE,
937                                      _("Sending compressed data packet of %d bytes\n"),
938                                      this->len);
939
940                         vpninfo->pending_deflated_pkt = this;
941                         vpninfo->current_ssl_pkt = vpninfo->deflate_pkt;
942                 } else {
943                 uncompr:
944                         memcpy(this->hdr, data_hdr, 8);
945                         this->hdr[4] = this->len >> 8;
946                         this->hdr[5] = this->len & 0xff;
947
948                         vpn_progress(vpninfo, PRG_TRACE,
949                                      _("Sending uncompressed data packet of %d bytes\n"),
950                                      this->len);
951
952                         vpninfo->current_ssl_pkt = this;
953                 }
954                 goto handle_outgoing;
955         }
956
957         /* Work is not done if we just got rid of packets off the queue */
958         return work_done;
959 }
960
961 int cstp_bye(struct openconnect_info *vpninfo, const char *reason)
962 {
963         unsigned char *bye_pkt;
964         int reason_len;
965
966         /* already lost connection? */
967 #if defined (OPENCONNECT_OPENSSL)
968         if (!vpninfo->https_ssl)
969                 return 0;
970 #elif defined (OPENCONNECT_GNUTLS)
971         if (!vpninfo->https_sess)
972                 return 0;
973 #endif
974
975         reason_len = strlen(reason);
976         bye_pkt = malloc(reason_len + 9);
977         if (!bye_pkt)
978                 return -ENOMEM;
979
980         memcpy(bye_pkt, data_hdr, 8);
981         memcpy(bye_pkt + 9, reason, reason_len);
982
983         bye_pkt[4] = (reason_len + 1) >> 8;
984         bye_pkt[5] = (reason_len + 1) & 0xff;
985         bye_pkt[6] = AC_PKT_DISCONN;
986         bye_pkt[8] = 0xb0;
987
988         vpn_progress(vpninfo, PRG_INFO,
989                      _("Send BYE packet: %s\n"), reason);
990
991         cstp_write(vpninfo, bye_pkt, reason_len + 9);
992         free(bye_pkt);
993
994         return 0;
995 }