Free CSTP option structure before error return if malloc fails
[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 }
148
149 static int start_cstp_connection(struct openconnect_info *vpninfo)
150 {
151         char buf[65536];
152         int i;
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;
163         int base_mtu, mtu;
164
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;
171
172         for (i=0; i<3; i++)
173                 vpninfo->vpn_dns[i] = vpninfo->vpn_nbns[i] = NULL;
174
175         for (inc = vpninfo->split_includes; inc; ) {
176                 struct split_include *next = inc->next;
177                 free(inc);
178                 inc = next;
179         }
180         for (inc = vpninfo->split_excludes; inc; ) {
181                 struct split_include *next = inc->next;
182                 free(inc);
183                 inc = next;
184         }
185         for (inc = vpninfo->split_dns; inc; ) {
186                 struct split_include *next = inc->next;
187                 free(inc);
188                 inc = next;
189         }
190         vpninfo->split_dns = vpninfo->split_includes = vpninfo->split_excludes = NULL;
191
192         /* Create (new) random master key for DTLS connection, if needed */
193         if (vpninfo->dtls_times.last_rekey + vpninfo->dtls_times.rekey <
194             time(NULL) + 300 &&
195             openconnect_random(vpninfo->dtls_secret, sizeof(vpninfo->dtls_secret))) {
196                 fprintf(stderr, _("Failed to initialise DTLS secret\n"));
197                 exit(1);
198         }
199
200  retry:
201         calculate_mtu(vpninfo, &base_mtu, &mtu);
202
203         buf[0] = 0;
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");
212         if (base_mtu)
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");
222
223         openconnect_SSL_write(vpninfo, buf, strlen(buf));
224
225         if ((i = openconnect_SSL_gets(vpninfo, buf, 65536) < 0)) {
226                 if (i == -EINTR)
227                         return i;
228                 vpn_progress(vpninfo, PRG_ERR,
229                              _("Error fetching HTTPS response\n"));
230                 if (!retried) {
231                         retried = 1;
232                         openconnect_close_https(vpninfo, 0);
233
234                         if (openconnect_open_https(vpninfo)) {
235                                 vpn_progress(vpninfo, PRG_ERR,
236                                              _("Failed to open HTTPS connection to %s\n"),
237                                              vpninfo->hostname);
238                                 exit(1);
239                         }
240                         goto retry;
241                 }
242                 return -EINVAL;
243         }
244
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)) {
251                                         reason = buf + 10;
252                                         break;
253                                 }
254                         }
255                         vpn_progress(vpninfo, PRG_ERR,
256                                      _("VPN service unavailable; reason: %s\n"),
257                                      reason);
258                         return -EINVAL;
259                 }
260                 vpn_progress(vpninfo, PRG_ERR,
261                              _("Got inappropriate HTTP CONNECT response: %s\n"),
262                              buf);
263                 if (!strncmp(buf, "HTTP/1.1 401 ", 13))
264                         exit(2);
265                 return -EINVAL;
266         }
267
268         vpn_progress(vpninfo, PRG_INFO, _("Got CONNECT response: %s\n"), buf);
269
270         /* We may have advertised it, but we only do it if the server agrees */
271         vpninfo->deflate = 0;
272         mtu = 0;
273
274         while ((i = openconnect_SSL_gets(vpninfo, buf, sizeof(buf)))) {
275                 struct vpn_option *new_option;
276                 char *colon;
277
278                 if (i < 0)
279                         return i;
280
281                 colon = strchr(buf, ':');
282                 if (!colon)
283                         continue;
284
285                 *colon = 0;
286                 colon++;
287                 if (*colon == ' ')
288                         colon++;
289
290                 if (strncmp(buf, "X-DTLS-", 7) &&
291                     strncmp(buf, "X-CSTP-", 7))
292                         continue;
293
294                 new_option = malloc(sizeof(*new_option));
295                 if (!new_option) {
296                         vpn_progress(vpninfo, PRG_ERR, _("No memory for options\n"));
297                         return -ENOMEM;
298                 }
299                 new_option->option = strdup(buf);
300                 new_option->value = strdup(colon);
301                 new_option->next = NULL;
302
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);
307                         free(new_option);
308                         return -ENOMEM;
309                 }
310
311                 vpn_progress(vpninfo, PRG_TRACE, "%s: %s\n", buf, colon);
312
313                 if (!strncmp(buf, "X-DTLS-", 7)) {
314                         *next_dtls_option = new_option;
315                         next_dtls_option = &new_option->next;
316
317                         if (!strcmp(buf + 7, "MTU")) {
318                                 int dtlsmtu = atol(colon);
319                                 if (dtlsmtu > mtu)
320                                         mtu = dtlsmtu;
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"),
325                                                      colon);
326                                         vpninfo->dtls_attempt_period = 0;
327                                         return -EINVAL;
328                                 }
329                                 for (i = 0; i < 64; i += 2)
330                                         vpninfo->dtls_session_id[i/2] = unhex(colon + i);
331                                 sessid_found = 1;
332                                 time(&vpninfo->dtls_times.last_rekey);
333                         }
334                         continue;
335                 }
336                 /* CSTP options... */
337                 *next_cstp_option = new_option;
338                 next_cstp_option = &new_option->next;
339
340
341                 if (!strcmp(buf + 7, "Keepalive")) {
342                         vpninfo->ssl_times.keepalive = atol(colon);
343                 } else if (!strcmp(buf + 7, "DPD")) {
344                         int j = atol(colon);
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;
352                         else {
353                                 vpn_progress(vpninfo, PRG_ERR,
354                                              _("Unknown CSTP-Content-Encoding %s\n"),
355                                              colon);
356                                 return -EINVAL;
357                         }
358                 } else if (!strcmp(buf + 7, "MTU")) {
359                         int cstpmtu = atol(colon);
360                         if (cstpmtu > mtu)
361                                 mtu = cstpmtu;
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;
366                         } else
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;
372                         } else
373                                 vpninfo->vpn_netmask = new_option->value;
374                 } else if (!strcmp(buf + 7, "DNS")) {
375                         int j;
376                         for (j = 0; j < 3; j++) {
377                                 if (!vpninfo->vpn_dns[j]) {
378                                         vpninfo->vpn_dns[j] = new_option->value;
379                                         break;
380                                 }
381                         }
382                 } else if (!strcmp(buf + 7, "NBNS")) {
383                         int j;
384                         for (j = 0; j < 3; j++) {
385                                 if (!vpninfo->vpn_nbns[j]) {
386                                         vpninfo->vpn_nbns[j] = new_option->value;
387                                         break;
388                                 }
389                         }
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));
398                         if (!dns)
399                                 continue;
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));
405                         if (!inc)
406                                 continue;
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));
412                         if (!exc)
413                                 continue;
414                         exc->route = new_option->value;
415                         exc->next = vpninfo->split_excludes;
416                         vpninfo->split_excludes = exc;
417                 }
418         }
419
420         if (!mtu) {
421                 vpn_progress(vpninfo, PRG_ERR,
422                              _("No MTU received. Aborting\n"));
423                 return -EINVAL;
424         }
425         vpninfo->actual_mtu = mtu;
426
427         if (!vpninfo->vpn_addr && !vpninfo->vpn_addr6) {
428                 vpn_progress(vpninfo, PRG_ERR,
429                              _("No IP address received. Aborting\n"));
430                 return -EINVAL;
431         }
432         if (old_addr) {
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);
437                         return -EINVAL;
438                 }
439         }
440         if (old_netmask) {
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);
445                         return -EINVAL;
446                 }
447         }
448         if (old_addr6) {
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);
453                         return -EINVAL;
454                 }
455         }
456         if (old_netmask6) {
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);
461                         return -EINVAL;
462                 }
463         }
464
465         while (old_dtls_opts) {
466                 struct vpn_option *tmp = old_dtls_opts;
467                 old_dtls_opts = old_dtls_opts->next;
468                 free(tmp->value);
469                 free(tmp->option);
470                 free(tmp);
471         }
472         while (old_cstp_opts) {
473                 struct vpn_option *tmp = old_cstp_opts;
474                 old_cstp_opts = old_cstp_opts->next;
475                 free(tmp->value);
476                 free(tmp->option);
477                 free(tmp);
478         }
479         vpn_progress(vpninfo, PRG_INFO, _("CSTP connected. DPD %d, Keepalive %d\n"),
480                      vpninfo->ssl_times.dpd, vpninfo->ssl_times.keepalive);
481
482         if (vpninfo->select_nfds <= vpninfo->ssl_fd)
483                 vpninfo->select_nfds = vpninfo->ssl_fd + 1;
484
485         FD_SET(vpninfo->ssl_fd, &vpninfo->select_rfds);
486         FD_SET(vpninfo->ssl_fd, &vpninfo->select_efds);
487
488         if (!sessid_found)
489                 vpninfo->dtls_attempt_period = 0;
490
491         vpninfo->ssl_times.last_rekey = vpninfo->ssl_times.last_rx =
492                 vpninfo->ssl_times.last_tx = time(NULL);
493         return 0;
494 }
495
496
497 int make_cstp_connection(struct openconnect_info *vpninfo)
498 {
499         int ret;
500
501         ret = openconnect_open_https(vpninfo);
502         if (ret)
503                 return ret;
504
505         if (vpninfo->deflate) {
506                 vpninfo->deflate_adler32 = 1;
507                 vpninfo->inflate_adler32 = 1;
508
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;
514                 }
515
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;
524                         } else {
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;
528                         }
529                 }
530         }
531
532         return start_cstp_connection(vpninfo);
533 }
534
535 int cstp_reconnect(struct openconnect_info *vpninfo)
536 {
537         int ret;
538         int timeout;
539         int interval;
540
541         openconnect_close_https(vpninfo, 0);
542
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;
549                 }
550                 inflateEnd(&vpninfo->inflate_strm);
551                 deflateEnd(&vpninfo->deflate_strm);
552         }
553         timeout = vpninfo->reconnect_timeout;
554         interval = vpninfo->reconnect_interval;
555
556         while ((ret = make_cstp_connection(vpninfo))) {
557                 if (timeout <= 0)
558                         return ret;
559                 vpn_progress(vpninfo, PRG_INFO,
560                              _("sleep %ds, remaining timeout %ds\n"),
561                              interval, timeout);
562                 sleep(interval);
563                 if (killed)
564                         return 1;
565                 timeout -= interval;
566                 interval += vpninfo->reconnect_interval;
567                 if (interval > RECONNECT_INTERVAL_MAX)
568                         interval = RECONNECT_INTERVAL_MAX;
569         }
570         script_config_tun(vpninfo, "reconnect");
571         return 0;
572 }
573
574 static int inflate_and_queue_packet(struct openconnect_info *vpninfo,
575                                     unsigned char *buf, int len)
576 {
577         struct pkt *new = malloc(sizeof(struct pkt) + vpninfo->actual_mtu);
578         uint32_t pkt_sum;
579
580         if (!new)
581                 return -ENOMEM;
582
583         new->next = NULL;
584
585         vpninfo->inflate_strm.next_in = buf;
586         vpninfo->inflate_strm.avail_in = len - 4;
587
588         vpninfo->inflate_strm.next_out = new->data;
589         vpninfo->inflate_strm.avail_out = vpninfo->actual_mtu;
590         vpninfo->inflate_strm.total_out = 0;
591
592         if (inflate(&vpninfo->inflate_strm, Z_SYNC_FLUSH)) {
593                 vpn_progress(vpninfo, PRG_ERR, _("inflate failed\n"));
594                 free(new);
595                 return -EINVAL;
596         }
597
598         new->len = vpninfo->inflate_strm.total_out;
599
600         vpninfo->inflate_adler32 = adler32(vpninfo->inflate_adler32,
601                                            new->data, new->len);
602
603         pkt_sum = buf[len - 1] | (buf[len - 2] << 8) |
604                 (buf[len - 3] << 16) | (buf[len - 4] << 24);
605
606         if (vpninfo->inflate_adler32 != pkt_sum) {
607                 vpninfo->quit_reason = "Compression (inflate) adler32 failure";
608         }
609
610         vpn_progress(vpninfo, PRG_TRACE,
611                      _("Received compressed data packet of %ld bytes\n"),
612                      (long)vpninfo->inflate_strm.total_out);
613
614         queue_packet(&vpninfo->incoming_queue, new);
615         return 0;
616 }
617
618 #if defined (OPENCONNECT_OPENSSL)
619 static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
620 {
621         int len, ret;
622
623         len = SSL_read(vpninfo->https_ssl, buf, maxlen);
624         if (len > 0)
625                 return len;
626
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"),
631                              ret);
632                 return -EIO;
633         }
634         return 0;
635 }
636
637 static int cstp_write(struct openconnect_info *vpninfo, void *buf, int buflen)
638 {
639         int ret;
640
641         ret = SSL_write(vpninfo->https_ssl, buf, buflen);
642         if (ret > 0)
643                 return ret;
644
645         ret = SSL_get_error(vpninfo->https_ssl, ret);
646         switch (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:
652                 return 0;
653
654         default:
655                 vpn_progress(vpninfo, PRG_ERR, _("SSL_write failed: %d\n"), ret);
656                 openconnect_report_ssl_errors(vpninfo);
657                 return -1;
658         }
659 }
660 #elif defined (OPENCONNECT_GNUTLS)
661 static int cstp_read(struct openconnect_info *vpninfo, void *buf, int maxlen)
662 {
663         int ret;
664
665         ret = gnutls_record_recv(vpninfo->https_sess, buf, maxlen);
666         if (ret > 0)
667                 return ret;
668
669         if (ret != GNUTLS_E_AGAIN) {
670                 vpn_progress(vpninfo, PRG_ERR,
671                              _("SSL read error: %s; reconnecting.\n"),
672                              gnutls_strerror(ret));
673                 return -EIO;
674         }
675         return 0;
676 }
677
678 static int cstp_write(struct openconnect_info *vpninfo, void *buf, int buflen)
679 {
680         int ret;
681
682         ret = gnutls_record_send(vpninfo->https_sess, buf, buflen);
683         if (ret > 0)
684                 return ret;
685
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);
691                 }
692                 return 0;
693         }
694         vpn_progress(vpninfo, PRG_ERR, _("SSL send failed: %s\n"),
695                      gnutls_strerror(ret));
696         return -1;
697 }
698 #endif
699
700 int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
701 {
702         unsigned char buf[16384];
703         int len, ret;
704         int work_done = 0;
705
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) {
713                 int payload_len;
714
715                 if (buf[0] != 'S' || buf[1] != 'T' ||
716                     buf[2] != 'F' || buf[3] != 1 || buf[7])
717                         goto unknown_pkt;
718
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"),
723                                      len);
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]);
728                         continue;
729                 }
730                 vpninfo->ssl_times.last_rx = time(NULL);
731                 switch(buf[6]) {
732                 case AC_PKT_DPD_OUT:
733                         vpn_progress(vpninfo, PRG_TRACE,
734                                      _("Got CSTP DPD request\n"));
735                         vpninfo->owe_ssl_dpd_response = 1;
736                         continue;
737
738                 case AC_PKT_DPD_RESP:
739                         vpn_progress(vpninfo, PRG_TRACE,
740                                      _("Got CSTP DPD response\n"));
741                         continue;
742
743                 case AC_PKT_KEEPALIVE:
744                         vpn_progress(vpninfo, PRG_TRACE,
745                                      _("Got CSTP Keepalive\n"));
746                         continue;
747
748                 case AC_PKT_DATA:
749                         vpn_progress(vpninfo, PRG_TRACE,
750                                      _("Received uncompressed data packet of %d bytes\n"),
751                                      payload_len);
752                         queue_new_packet(&vpninfo->incoming_queue, buf + 8,
753                                          payload_len);
754                         work_done = 1;
755                         continue;
756
757                 case AC_PKT_DISCONN: {
758                         int i;
759                         for (i = 0; i < payload_len; i++) {
760                                 if (!isprint(buf[payload_len + 8 + i]))
761                                         buf[payload_len + 8 + i] = '.';
762                         }
763                         buf[payload_len + 8] = 0;
764                         vpn_progress(vpninfo, PRG_ERR,
765                                      _("Received server disconnect: %02x '%s'\n"),
766                                      buf[8], buf + 9);
767                         vpninfo->quit_reason = "Server request";
768                         return 1;
769                 }
770                 case AC_PKT_COMPRESSED:
771                         if (!vpninfo->deflate) {
772                                 vpn_progress(vpninfo, PRG_ERR,
773                                              _("Compressed packet received in !deflate mode\n"));
774                                 goto unknown_pkt;
775                         }
776                         inflate_and_queue_packet(vpninfo, buf + 8, payload_len);
777                         work_done = 1;
778                         continue;
779
780                 case AC_PKT_TERM_SERVER:
781                         vpn_progress(vpninfo, PRG_ERR, _("received server terminate packet\n"));
782                         vpninfo->quit_reason = "Server request";
783                         return 1;
784                 }
785
786         unknown_pkt:
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";
792                 return 1;
793         }
794         if (len < 0)
795                 goto do_reconnect;
796
797
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) {
802         handle_outgoing:
803                 vpninfo->ssl_times.last_tx = time(NULL);
804                 FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
805
806                 ret = cstp_write(vpninfo,
807                                  vpninfo->current_ssl_pkt->hdr,
808                                  vpninfo->current_ssl_pkt->len + 8);
809                 if (ret < 0)
810                         goto do_reconnect;
811                 else if (!ret) {
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)) {
817                         case KA_DPD_DEAD:
818                                 goto peer_dead;
819                         case KA_REKEY:
820                                 goto do_rekey;
821                         case KA_NONE:
822                                 return work_done;
823                         default:
824                                 /* This should never happen */
825                                 ;
826                         }
827                 }
828
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";
834                         return 1;
835                 }
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);
843
844                 vpninfo->current_ssl_pkt = NULL;
845         }
846
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;
851         }
852
853         switch (keepalive_action(&vpninfo->ssl_times, timeout)) {
854         case KA_REKEY:
855         do_rekey:
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"));
859                 goto do_reconnect;
860                 break;
861
862         case KA_DPD_DEAD:
863         peer_dead:
864                 vpn_progress(vpninfo, PRG_ERR,
865                              _("CSTP Dead Peer Detection detected dead peer!\n"));
866         do_reconnect:
867                 if (cstp_reconnect(vpninfo)) {
868                         vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
869                         vpninfo->quit_reason = "CSTP reconnect failed";
870                         return 1;
871                 }
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 */
874                 return 1;
875
876         case KA_DPD:
877                 vpn_progress(vpninfo, PRG_TRACE, _("Send CSTP DPD\n"));
878
879                 vpninfo->current_ssl_pkt = &dpd_pkt;
880                 goto handle_outgoing;
881
882         case KA_KEEPALIVE:
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)
886                         break;
887
888                 vpn_progress(vpninfo, PRG_TRACE, _("Send CSTP Keepalive\n"));
889
890                 vpninfo->current_ssl_pkt = &keepalive_pkt;
891                 goto handle_outgoing;
892
893         case KA_NONE:
894                 ;
895         }
896
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--;
902
903                 if (vpninfo->deflate) {
904                         unsigned char *adler;
905                         int ret;
906
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;
912
913                         ret = deflate(&vpninfo->deflate_strm, Z_SYNC_FLUSH);
914                         if (ret) {
915                                 vpn_progress(vpninfo, PRG_ERR, _("deflate failed %d\n"), ret);
916                                 goto uncompr;
917                         }
918
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;
921
922                         /* Add ongoing adler32 to tail of compressed packet */
923                         vpninfo->deflate_adler32 = adler32(vpninfo->deflate_adler32,
924                                                            this->data, this->len);
925
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;
931
932                         vpninfo->deflate_pkt->len = vpninfo->deflate_strm.total_out + 4;
933
934                         vpn_progress(vpninfo, PRG_TRACE,
935                                      _("Sending compressed data packet of %d bytes\n"),
936                                      this->len);
937
938                         vpninfo->pending_deflated_pkt = this;
939                         vpninfo->current_ssl_pkt = vpninfo->deflate_pkt;
940                 } else {
941                 uncompr:
942                         memcpy(this->hdr, data_hdr, 8);
943                         this->hdr[4] = this->len >> 8;
944                         this->hdr[5] = this->len & 0xff;
945
946                         vpn_progress(vpninfo, PRG_TRACE,
947                                      _("Sending uncompressed data packet of %d bytes\n"),
948                                      this->len);
949
950                         vpninfo->current_ssl_pkt = this;
951                 }
952                 goto handle_outgoing;
953         }
954
955         /* Work is not done if we just got rid of packets off the queue */
956         return work_done;
957 }
958
959 int cstp_bye(struct openconnect_info *vpninfo, const char *reason)
960 {
961         unsigned char *bye_pkt;
962         int reason_len;
963
964         /* already lost connection? */
965 #if defined (OPENCONNECT_OPENSSL)
966         if (!vpninfo->https_ssl)
967                 return 0;
968 #elif defined (OPENCONNECT_GNUTLS)
969         if (!vpninfo->https_sess)
970                 return 0;
971 #endif
972
973         reason_len = strlen(reason);
974         bye_pkt = malloc(reason_len + 9);
975         if (!bye_pkt)
976                 return -ENOMEM;
977
978         memcpy(bye_pkt, data_hdr, 8);
979         memcpy(bye_pkt + 9, reason, reason_len);
980
981         bye_pkt[4] = (reason_len + 1) >> 8;
982         bye_pkt[5] = (reason_len + 1) & 0xff;
983         bye_pkt[6] = AC_PKT_DISCONN;
984         bye_pkt[8] = 0xb0;
985
986         vpn_progress(vpninfo, PRG_INFO,
987                      _("Send BYE packet: %s\n"), reason);
988
989         cstp_write(vpninfo, bye_pkt, reason_len + 9);
990         free(bye_pkt);
991
992         return 0;
993 }