1 /*
2 * Copyright (C) 2013-2018 Nikos Mavrogiannopoulos
3 * Copyright (C) 2015, 2016 Red Hat, Inc.
4 *
5 * This file is part of ocserv.
6 *
7 * ocserv is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * ocserv is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <config.h>
22
23 #include <gnutls/gnutls.h>
24 #include <gnutls/dtls.h>
25 #include <gnutls/crypto.h>
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <limits.h>
36 #include <netinet/in.h>
37 #include <sys/socket.h>
38 #include <netinet/tcp.h>
39 #include <arpa/inet.h>
40 #include <system.h>
41 #include <time.h>
42 #include <gettime.h>
43 #include <common.h>
44 #include <html.h>
45 #include <c-strcase.h>
46 #include <c-ctype.h>
47 #include <worker-bandwidth.h>
48 #include <signal.h>
49 #include <poll.h>
50 #include <math.h>
51 #include <ev.h>
52
53 #if defined(__linux__) && !defined(IPV6_PATHMTU)
54 # define IPV6_PATHMTU 61
55 #endif
56
57 #include <vpn.h>
58 #include "ipc.pb-c.h"
59 #include <worker.h>
60 #include <tlslib.h>
61 #include <http_parser.h>
62
63 #if defined(CAPTURE_LATENCY_SUPPORT)
64 #include <linux/net_tstamp.h>
65 #include <linux/errqueue.h>
66 #include <worker-latency.h>
67 #endif
68
69 #define MIN_MTU(ws) (((ws)->vinfo.ipv6!=NULL)?1280:800)
70
71 #define PERIODIC_CHECK_TIME 30
72 #define MIN_STATS_INTERVAL 10
73
74 /* The number of DPD packets a client skips before he's kicked */
75 #define DPD_TRIES 2
76 #define DPD_MAX_TRIES 3
77
78 /* HTTP requests prior to disconnection */
79 #define MAX_HTTP_REQUESTS 16
80
81 #define CSTP_DTLS_OVERHEAD 1
82 #define CSTP_OVERHEAD 8
83
84 #define IP_HEADER_SIZE 20
85 #define IPV6_HEADER_SIZE 40
86 #define TCP_HEADER_SIZE 20
87 #define UDP_HEADER_SIZE 8
88
89 #define MSS_ADJUST(x) x += TCP_HEADER_SIZE + ((ws->proto == AF_INET)?(IP_HEADER_SIZE):(IPV6_HEADER_SIZE))
90
91 #define WORKER_MAINTENANCE_TIME (10.)
92
93 struct worker_st *global_ws = NULL;
94
95 static int terminate = 0;
96 static int terminate_reason = REASON_SERVER_DISCONNECT;
97
98 static struct ev_loop *worker_loop = NULL;
99 ev_io command_watcher;
100 ev_io tls_watcher;
101 ev_io tun_watcher;
102 ev_timer period_check_watcher;
103 ev_signal term_sig_watcher;
104 ev_signal int_sig_watcher;
105 ev_signal alarm_sig_watcher;
106
107 static void term_sig_watcher_cb(struct ev_loop *loop, ev_signal *w, int revents);
108
109 static int worker_event_loop(struct worker_st * ws);
110
111 static int parse_cstp_data(struct worker_st *ws, uint8_t * buf, size_t buf_size,
112 time_t);
113 static int parse_dtls_data(struct worker_st *ws, uint8_t * buf, size_t buf_size,
114 time_t);
115 static int connect_handler(worker_st * ws);
116 static void session_info_send(worker_st * ws);
117 static void set_net_priority(worker_st * ws, int fd, int priority);
118 static void set_socket_timeout(worker_st * ws, int fd);
119
120 static void link_mtu_set(worker_st * ws, struct dtls_st * dtls, unsigned mtu);
121
122 static int test_for_tcp_health_probe(struct worker_st *ws);
123
124 static void dtls_watcher_cb (EV_P_ ev_io * w, int revents);
125
handle_alarm(int signo)126 static void handle_alarm(int signo)
127 {
128 if (global_ws)
129 exit_worker_reason(global_ws, terminate_reason);
130
131 _exit(1);
132 }
133
handle_term(int signo)134 static void handle_term(int signo)
135 {
136 terminate = 1;
137 terminate_reason = REASON_SERVER_DISCONNECT;
138 alarm(2); /* force exit by SIGALRM */
139 }
140
141 /* we override that function to force gnutls use poll()
142 */
143 static
tls_pull_timeout(gnutls_transport_ptr_t ptr,unsigned int ms)144 int tls_pull_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
145 {
146 int ret;
147 int fd = (long)ptr;
148 struct pollfd pfd;
149
150 pfd.fd = fd;
151 pfd.events = POLLIN;
152 pfd.revents = 0;
153
154 ret = poll(&pfd, 1, ms);
155 if (ret <= 0)
156 return ret;
157
158 return ret;
159 }
160
dtls_pull_buffer_non_empty(gnutls_transport_ptr_t ptr)161 inline static ssize_t dtls_pull_buffer_non_empty(gnutls_transport_ptr_t ptr)
162 {
163 dtls_transport_ptr *p = ptr;
164 if (p->msg)
165 return 1;
166 return 0;
167 }
168
169 static
dtls_pull(gnutls_transport_ptr_t ptr,void * data,size_t size)170 ssize_t dtls_pull(gnutls_transport_ptr_t ptr, void *data, size_t size)
171 {
172 dtls_transport_ptr *p = ptr;
173
174 if (p->msg) {
175 ssize_t need = p->msg->data.len;
176 if (need > size) {
177 need = size;
178 }
179 memcpy(data, p->msg->data.data, need);
180
181 udp_fd_msg__free_unpacked(p->msg, NULL);
182 p->msg = NULL;
183 return need;
184 }
185 return recv(p->fd, data, size, 0);
186 }
187
188 static
dtls_pull_timeout(gnutls_transport_ptr_t ptr,unsigned int ms)189 int dtls_pull_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
190 {
191 int ret;
192 dtls_transport_ptr *p = ptr;
193 int fd = p->fd;
194 struct pollfd pfd;
195
196 if (dtls_pull_buffer_non_empty(ptr)) {
197 return 1;
198 }
199
200 pfd.fd = fd;
201 pfd.events = POLLIN;
202 pfd.revents = 0;
203
204 ret = poll(&pfd, 1, ms);
205 if (ret <= 0)
206 return ret;
207
208 return ret;
209 }
210
211 static
dtls_push(gnutls_transport_ptr_t ptr,const void * data,size_t size)212 ssize_t dtls_push(gnutls_transport_ptr_t ptr, const void *data, size_t size)
213 {
214 dtls_transport_ptr *p = ptr;
215
216 return send(p->fd, data, size, 0);
217 }
218
get_psk_key(gnutls_session_t session,const char * username,gnutls_datum_t * key)219 int get_psk_key(gnutls_session_t session,
220 const char *username, gnutls_datum_t *key)
221 {
222 struct worker_st *ws = gnutls_session_get_ptr(session);
223
224 key->data = gnutls_malloc(PSK_KEY_SIZE);
225 if (key->data == NULL)
226 return GNUTLS_E_MEMORY_ERROR;
227
228 memcpy(key->data, ws->master_secret, PSK_KEY_SIZE);
229 key->size = PSK_KEY_SIZE;
230
231 return 0;
232 }
233
234 #if GNUTLS_VERSION_NUMBER < 0x030318
235 # define VERS_STRING "-VERS-TLS-ALL"
236 #else
237 # define VERS_STRING "-VERS-ALL"
238 #endif
239
240 #define PSK_LABEL "EXPORTER-openconnect-psk"
241 #define PSK_LABEL_SIZE sizeof(PSK_LABEL)-1
242 /* We initial a PSK connection with ciphers and MAC matching the TLS negotiated
243 * ciphers and MAC. The key is 32-bytes generated from gnutls_prf_rfc5705()
244 * with label being the PSK_LABEL.
245 */
setup_dtls_psk_keys(gnutls_session_t session,struct worker_st * ws)246 static int setup_dtls_psk_keys(gnutls_session_t session, struct worker_st *ws)
247 {
248 int ret;
249 char prio_string[256];
250 gnutls_mac_algorithm_t mac;
251 gnutls_cipher_algorithm_t cipher;
252
253 gnutls_psk_set_server_credentials_function(WSCREDS(ws)->pskcred, get_psk_key);
254
255 if (!ws->session) {
256 oclog(ws, LOG_ERR, "cannot setup PSK keys without an encrypted CSTP channel");
257 return -1;
258 }
259
260 if (WSCONFIG(ws)->match_dtls_and_tls) {
261 cipher = gnutls_cipher_get(ws->session);
262 mac = gnutls_mac_get(ws->session);
263
264 snprintf(prio_string, sizeof(prio_string), "%s:"VERS_STRING":-CIPHER-ALL:-MAC-ALL:-KX-ALL:+PSK:+VERS-DTLS-ALL:+%s:+%s",
265 WSCONFIG(ws)->priorities, gnutls_mac_get_name(mac), gnutls_cipher_get_name(cipher));
266 } else {
267 /* if we haven't an associated session, enable all ciphers we would have enabled
268 * otherwise for TLS. */
269 snprintf(prio_string, sizeof(prio_string), "%s:"VERS_STRING":-KX-ALL:+PSK:+VERS-DTLS-ALL",
270 WSCONFIG(ws)->priorities);
271 }
272
273 ret =
274 gnutls_priority_set_direct(session, prio_string, NULL);
275 if (ret < 0) {
276 oclog(ws, LOG_ERR, "could not set TLS priority: '%s': %s",
277 prio_string, gnutls_strerror(ret));
278 return ret;
279 }
280
281 /* we should have used gnutls_prf_rfc5705() but since we don't use
282 * the RFC5705 context, the output is identical with gnutls_prf(). The
283 * latter is available in much earlier versions of gnutls. */
284 ret = gnutls_prf(ws->session, PSK_LABEL_SIZE, PSK_LABEL, 0, 0, 0, PSK_KEY_SIZE, (char*)ws->master_secret);
285 if (ret < 0) {
286 oclog(ws, LOG_ERR, "error in PSK key generation: %s",
287 gnutls_strerror(ret));
288 return ret;
289 }
290
291 ret =
292 gnutls_credentials_set(session, GNUTLS_CRD_PSK,
293 WSCREDS(ws)->pskcred);
294 if (ret < 0) {
295 oclog(ws, LOG_ERR, "could not set TLS PSK credentials: %s",
296 gnutls_strerror(ret));
297 return ret;
298 }
299
300 return 0;
301 }
302
setup_legacy_dtls_keys(gnutls_session_t session,struct worker_st * ws)303 static int setup_legacy_dtls_keys(gnutls_session_t session, struct worker_st *ws)
304 {
305 int ret;
306 gnutls_datum_t master =
307 { ws->master_secret, sizeof(ws->master_secret) };
308 gnutls_datum_t sid = { ws->session_id, sizeof(ws->session_id) };
309
310 if (ws->req.selected_ciphersuite == NULL) {
311 oclog(ws, LOG_ERR, "no DTLS ciphersuite negotiated");
312 return -1;
313 }
314
315 ret =
316 gnutls_priority_set_direct(session,
317 ws->req.
318 selected_ciphersuite->gnutls_name, NULL);
319 if (ret < 0) {
320 oclog(ws, LOG_ERR, "could not set TLS priority: %s",
321 gnutls_strerror(ret));
322 return ret;
323 }
324
325 ret = gnutls_session_set_premaster(session, GNUTLS_SERVER,
326 ws->req.
327 selected_ciphersuite->gnutls_version,
328 ws->req.
329 selected_ciphersuite->gnutls_kx,
330 ws->req.
331 selected_ciphersuite->gnutls_cipher,
332 ws->req.
333 selected_ciphersuite->gnutls_mac,
334 GNUTLS_COMP_NULL, &master, &sid);
335 if (ret < 0) {
336 oclog(ws, LOG_ERR, "could not set TLS premaster: %s",
337 gnutls_strerror(ret));
338 return ret;
339 }
340
341 gnutls_certificate_server_set_request(session, GNUTLS_CERT_IGNORE);
342
343 ret =
344 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
345 WSCREDS(ws)->xcred);
346 if (ret < 0) {
347 oclog(ws, LOG_ERR, "could not set TLS credentials: %s",
348 gnutls_strerror(ret));
349 return ret;
350 }
351
352 return 0;
353 }
354
setup_dtls_connection(struct worker_st * ws,struct dtls_st * dtls)355 static int setup_dtls_connection(struct worker_st *ws, struct dtls_st * dtls)
356 {
357 int ret;
358 gnutls_session_t session;
359 #if defined(CAPTURE_LATENCY_SUPPORT)
360 int ts_socket_opt = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
361 #endif
362
363 /* DTLS cookie verified.
364 * Initialize session.
365 */
366 ret = gnutls_init(&session, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK);
367 if (ret < 0) {
368 oclog(ws, LOG_ERR, "could not initialize TLS session: %s",
369 gnutls_strerror(ret));
370 return -1;
371 }
372
373 gnutls_session_set_ptr(session, ws);
374
375 if (ws->req.use_psk && ws->session) {
376 oclog(ws, LOG_INFO, "setting up DTLS-PSK connection");
377 ret = setup_dtls_psk_keys(session, ws);
378 } else {
379 if (!WSCONFIG(ws)->dtls_legacy) {
380 oclog(ws, LOG_INFO, "CISCO client compatibility (dtls-legacy) is disabled; will not setup a DTLS session");
381 goto fail;
382 }
383 oclog(ws, LOG_INFO, "setting up legacy DTLS (resumption) connection");
384 ret = setup_legacy_dtls_keys(session, ws);
385 }
386
387 if (ret < 0) {
388 goto fail;
389 }
390
391 gnutls_transport_set_push_function(session, dtls_push);
392 #if defined(CAPTURE_LATENCY_SUPPORT)
393 gnutls_transport_set_pull_function(session, dtls_pull_latency);
394 #else
395 gnutls_transport_set_pull_function(session, dtls_pull);
396 #endif
397 gnutls_transport_set_pull_timeout_function(session, dtls_pull_timeout);
398 gnutls_transport_set_ptr(session, &dtls->dtls_tptr);
399
400 /* we decrease the default retransmission timeout to bring
401 * our DTLS support in par with the DTLS1.3 recommendations.
402 */
403 gnutls_dtls_set_timeouts(session, 400, 60*1000);
404
405 dtls->udp_state = UP_HANDSHAKE;
406
407 #if defined(CAPTURE_LATENCY_SUPPORT)
408 ret = setsockopt(dtls->dtls_tptr.fd, SOL_SOCKET, SO_TIMESTAMPING, &ts_socket_opt, sizeof(ts_socket_opt));
409 if (ret == -1)
410 oclog(ws, LOG_DEBUG, "setsockopt(UDP, SO_TIMESTAMPING), failed.");
411 #endif
412
413 /* Setup the fd settings */
414 if (WSCONFIG(ws)->output_buffer > 0) {
415 int t = MIN(2048, ws->link_mtu * WSCONFIG(ws)->output_buffer);
416 ret = setsockopt(dtls->dtls_tptr.fd, SOL_SOCKET, SO_SNDBUF, &t,
417 sizeof(t));
418 if (ret == -1)
419 oclog(ws, LOG_DEBUG,
420 "setsockopt(UDP, SO_SNDBUF) to %u, failed.",
421 t);
422 }
423 set_net_priority(ws, dtls->dtls_tptr.fd, ws->user_config->net_priority);
424 set_socket_timeout(ws, dtls->dtls_tptr.fd);
425
426 /* reset MTU */
427 link_mtu_set(ws, dtls, ws->adv_link_mtu);
428
429 if (dtls->dtls_session != NULL) {
430 gnutls_deinit(dtls->dtls_session);
431 }
432
433 dtls->dtls_session = session;
434 ev_io_stop(worker_loop, &dtls->io);
435 ev_io_set(&dtls->io, dtls->dtls_tptr.fd, EV_READ);
436 ev_io_start(worker_loop, &dtls->io);
437 ev_invoke(worker_loop, &dtls->io, EV_READ);
438
439 return 0;
440 fail:
441 gnutls_deinit(session);
442 return -1;
443 }
444
ws_add_score_to_ip(worker_st * ws,unsigned points,unsigned final,unsigned discon_reason)445 void ws_add_score_to_ip(worker_st *ws, unsigned points, unsigned final, unsigned discon_reason)
446 {
447 int ret, e;
448 BanIpMsg msg = BAN_IP_MSG__INIT;
449 BanIpReplyMsg *reply = NULL;
450 PROTOBUF_ALLOCATOR(pa, ws);
451
452 /* no reporting if banning is disabled */
453 if (WSCONFIG(ws)->max_ban_score == 0)
454 return;
455
456 /* In final call, no score added, we simply send */
457 if (final == 0) {
458 ws->ban_points += points;
459 /* do not use IPC for small values */
460 if (points < WSCONFIG(ws)->ban_points_wrong_password)
461 return;
462 }
463
464 msg.ip = ws->remote_ip_str;
465 msg.score = points;
466 if (final) {
467 msg.has_discon_reason = 1;
468 msg.discon_reason = discon_reason;
469 }
470
471 ret = send_msg(ws, ws->cmd_fd, CMD_BAN_IP, &msg,
472 (pack_size_func) ban_ip_msg__get_packed_size,
473 (pack_func) ban_ip_msg__pack);
474 if (ret < 0) {
475 e = errno;
476 oclog(ws, LOG_WARNING, "error in sending BAN IP message: %s", strerror(e));
477 return;
478 }
479
480 ret = recv_msg(ws, ws->cmd_fd, CMD_BAN_IP_REPLY,
481 (void *)&reply, (unpack_func) ban_ip_reply_msg__unpack, DEFAULT_SOCKET_TIMEOUT);
482 if (ret < 0) {
483 oclog(ws, LOG_ERR, "error receiving BAN IP reply message");
484 return;
485 }
486
487 if (final ==0 && reply->reply != AUTH__REP__OK) {
488 /* we have exceeded the maximum score */
489 exit(1);
490 }
491
492 ban_ip_reply_msg__free_unpacked(reply, &pa);
493
494 return;
495 }
496
send_stats_to_secmod(worker_st * ws,time_t now,unsigned discon_reason)497 void send_stats_to_secmod(worker_st * ws, time_t now, unsigned discon_reason)
498 {
499 CliStatsMsg msg = CLI_STATS_MSG__INIT;
500 int sd, ret, e;
501
502 /* this is only used by certain tests */
503 if (WSPCONFIG(ws)->debug_no_secmod_stats != 0)
504 return;
505
506 ws->last_stats_msg = now;
507
508 sd = connect_to_secmod(ws);
509 if (sd >= 0) {
510 char buf[64];
511 msg.bytes_in = ws->tun_bytes_in;
512 msg.bytes_out = ws->tun_bytes_out;
513 msg.uptime = now - ws->session_start_time;
514 msg.sid.len = sizeof(ws->sid);
515 msg.sid.data = ws->sid;
516 msg.has_sid = 1;
517
518 if (discon_reason) {
519 msg.has_discon_reason = 1;
520 msg.discon_reason = discon_reason;
521 }
522
523 msg.remote_ip = human_addr2((void *)&ws->remote_addr, ws->remote_addr_len,
524 buf, sizeof(buf), 0);
525
526 msg.ipv4 = ws->vinfo.ipv4;
527 msg.ipv6 = ws->vinfo.ipv6;
528
529 ret = send_msg_to_secmod(ws, sd, CMD_SEC_CLI_STATS, &msg,
530 (pack_size_func)cli_stats_msg__get_packed_size,
531 (pack_func) cli_stats_msg__pack);
532 if (discon_reason) { /* wait for sec-mod to close connection to verify data have been accounted */
533 e = read(sd, buf, sizeof(buf));
534 if (e == -1) {
535 e = errno;
536 oclog(ws, LOG_DEBUG, "could not wait for sec-mod: %s\n", strerror(e));
537 }
538 }
539 close(sd);
540
541 if (ret >= 0) {
542 oclog(ws, LOG_INFO,
543 "sent periodic stats (in: %lu, out: %lu) to sec-mod",
544 (unsigned long)msg.bytes_in,
545 (unsigned long)msg.bytes_out);
546 } else {
547 e = errno;
548 oclog(ws, LOG_WARNING, "could not send periodic stats to sec-mod: %s\n", strerror(e));
549 }
550 }
551 }
552
553 /* Terminates the worker process, but communicates any required
554 * data to main process before (stats/ban points).
555 */
exit_worker(worker_st * ws)556 void exit_worker(worker_st * ws)
557 {
558 exit_worker_reason(ws, REASON_ANY);
559 }
560
exit_worker_reason(worker_st * ws,unsigned reason)561 void exit_worker_reason(worker_st * ws, unsigned reason)
562 {
563 /* send statistics to parent */
564 if (ws->auth_state == S_AUTH_COMPLETE) {
565 send_stats_to_secmod(ws, time(0), reason);
566 }
567
568 if (ws->ban_points > 0)
569 ws_add_score_to_ip(ws, 0, 1, reason);
570
571 talloc_free(ws->main_pool);
572 closelog();
573 _exit(1);
574 }
575
576 #define HANDSHAKE_SESSION_ID_POS (34)
577 #define SKIP_V16(pos, total) \
578 { uint16_t _s; \
579 if (pos+2 > total) goto finish; \
580 _s = (msg->data[pos] << 8) | msg->data[pos+1]; \
581 if (pos+2+_s > total) goto finish; \
582 pos += 2+_s; \
583 }
584
585 #define SKIP16(pos, total) \
586 if (pos+2 > total) goto finish; \
587 pos += 2
588
589 #define SKIP8(pos, total) \
590 if (pos+1 > total) goto finish; \
591 pos++
592
593 #define SKIP_V8(pos, total) \
594 { uint8_t _s; \
595 if (pos+1 > total) goto finish; \
596 _s = msg->data[pos]; \
597 if (pos+1+_s > total) goto finish; \
598 pos += 1+_s; \
599 }
600
601 #define SET_VHOST_CREDS \
602 ret = \
603 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, \
604 WSCREDS(ws)->xcred); \
605 GNUTLS_FATAL_ERR(ret); \
606 gnutls_certificate_server_set_request(session, WSCONFIG(ws)->cert_req); \
607 ret = gnutls_priority_set(session, WSCREDS(ws)->cprio); \
608 GNUTLS_FATAL_ERR(ret); \
609 gnutls_db_set_cache_expiration(session, TLS_SESSION_EXPIRATION_TIME(WSCONFIG(ws)))
610
611 /* Parse the TLS client hello to figure vhost */
hello_hook_func(gnutls_session_t session,unsigned int htype,unsigned when,unsigned int incoming,const gnutls_datum_t * msg)612 static int hello_hook_func(gnutls_session_t session, unsigned int htype,
613 unsigned when, unsigned int incoming,
614 const gnutls_datum_t *msg)
615
616 {
617 ssize_t ret;
618 size_t pos;
619 size_t hsize;
620 struct worker_st *ws = gnutls_session_get_ptr(session);
621
622 if (htype != GNUTLS_HANDSHAKE_CLIENT_HELLO || when != GNUTLS_HOOK_PRE)
623 goto finish;
624
625 /* find the server name extension */
626
627 pos = HANDSHAKE_SESSION_ID_POS;
628 if (msg->size <= pos)
629 goto finish;
630
631 if (msg->data[0] != 0x03) {
632 /* unknown packet version */
633 goto finish;
634 }
635
636 /* skip session id */
637 SKIP_V8(pos, msg->size);
638
639 /* CipherSuites */
640 SKIP_V16(pos, msg->size);
641
642 /* legacy_compression_methods */
643 SKIP_V8(pos, msg->size);
644
645 /* Skip extension total size */
646 SKIP16(pos, msg->size);
647
648 while (pos < msg->size) {
649 uint16_t type;
650
651 /* read ExtensionType */
652 SKIP16(pos, msg->size);
653 type = (msg->data[pos-2] << 8) | msg->data[pos-1];
654
655 if (type == 0) { /* server name ext */
656 SKIP16(pos, msg->size);
657 SKIP16(pos, msg->size); /* we don't support anything but a single name */
658
659 SKIP8(pos, msg->size);
660 if (msg->data[pos-1] != 0) { /* HostName */
661 oclog(ws, LOG_DEBUG,
662 "received server name extension with invalid name type field");
663 goto finish;
664 }
665
666 SKIP16(pos, msg->size);
667 hsize = (msg->data[pos-2] << 8) | msg->data[pos-1];
668
669 if (hsize == 0 || hsize + pos > msg->size || hsize > sizeof(ws->buffer)-1) {
670 oclog(ws, LOG_DEBUG,
671 "received server name extension with too large name");
672 goto finish;
673 }
674
675 memcpy(ws->buffer, &msg->data[pos], hsize);
676 ws->buffer[hsize] = 0;
677
678 oclog(ws, LOG_DEBUG,
679 "client requested hostname: %s", (char*)ws->buffer);
680
681 ws->vhost = find_vhost(ws->vconfig, (char*)ws->buffer);
682 if (ws->vhost->name && c_strcasecmp(ws->vhost->name, (char*)ws->buffer) != 0) {
683 oclog(ws, LOG_INFO,
684 "client requested hostname %s does not match known vhost", (char*)ws->buffer);
685 }
686
687 goto finish;
688 } else {
689 SKIP_V16(pos, msg->size);
690 }
691 }
692
693 finish:
694 /* We set credentials irrespective of whether a virtual host was found,
695 * as they have not been previously set. */
696 SET_VHOST_CREDS;
697
698 return 0;
699 }
700
701 #if GNUTLS_VERSION_NUMBER < 0x030400
702 # define SIMULATE_CLIENT_HELLO_HOOK
703 #endif
704
705 #ifdef SIMULATE_CLIENT_HELLO_HOOK
706 #define TLS_RECORD_HEADER 5
707 #define TLS_HANDSHAKE_HEADER 4
708
709 /* In gnutls 3.3 we don't get the size in the handshake callback
710 * so we try to simulate.
711 */
peek_client_hello(struct worker_st * ws,gnutls_session_t session,int fd)712 static void peek_client_hello(struct worker_st *ws, gnutls_session_t session, int fd)
713 {
714 unsigned read_tries = 0;
715 int ret;
716 size_t size, hsize;
717 gnutls_datum_t msg;
718
719 do {
720 if (read_tries > 0) {
721 if (read_tries > 5)
722 goto fallback;
723 ms_sleep(150);
724 }
725 read_tries++;
726
727 ret = recv(fd, ws->buffer, sizeof(ws->buffer), MSG_PEEK);
728 if (ret == -1)
729 goto fallback;
730 size = ret;
731
732 if (size < TLS_RECORD_HEADER)
733 goto fallback;
734
735 hsize = (ws->buffer[3] << 8) | ws->buffer[4];
736 } while(hsize+TLS_RECORD_HEADER > size);
737
738 if (size < TLS_RECORD_HEADER+TLS_HANDSHAKE_HEADER+HANDSHAKE_SESSION_ID_POS)
739 goto fallback;
740
741 msg.data = ws->buffer + TLS_RECORD_HEADER+TLS_HANDSHAKE_HEADER;
742 msg.size = size - (TLS_RECORD_HEADER+TLS_HANDSHAKE_HEADER);
743 hello_hook_func(session, GNUTLS_HANDSHAKE_CLIENT_HELLO,
744 GNUTLS_HOOK_PRE, 1, &msg);
745
746 return;
747
748 fallback:
749 SET_VHOST_CREDS;
750 }
751 #endif
752
753 /* vpn_server:
754 * @ws: an initialized worker structure
755 *
756 * This is the main worker process. It is executed
757 * by the main server after fork and drop of privileges.
758 *
759 * It handles the client connection including:
760 * - HTTPS authentication using XML forms that are parsed and
761 * forwarded to main.
762 * - TLS authentication (using certificate)
763 * - TCP VPN tunnel establishment (after HTTP CONNECT)
764 * - UDP VPN tunnel establishment (once an FD is forwarded by main)
765 *
766 */
vpn_server(struct worker_st * ws)767 void vpn_server(struct worker_st *ws)
768 {
769 int ret;
770 ssize_t nparsed, nrecvd;
771 gnutls_session_t session = NULL;
772 http_parser parser;
773 http_parser_settings settings;
774 url_handler_fn fn;
775 int requests_left = MAX_HTTP_REQUESTS;
776
777 ocsigaltstack(ws);
778
779 ocsignal(SIGTERM, handle_term);
780 ocsignal(SIGINT, handle_term);
781 ocsignal(SIGHUP, SIG_IGN);
782 ocsignal(SIGALRM, handle_alarm);
783
784 global_ws = ws;
785 if (GETCONFIG(ws)->auth_timeout) {
786 terminate_reason = REASON_SERVER_DISCONNECT;
787 alarm(GETCONFIG(ws)->auth_timeout);
788 }
789
790 /* do not allow this process to be traced. That
791 * prevents worker processes tracing each other. */
792 if (GETPCONFIG(ws)->pr_dumpable != 1)
793 pr_set_undumpable("worker");
794 if (GETCONFIG(ws)->isolate != 0) {
795 ret = disable_system_calls(ws);
796 if (ret < 0) {
797 oclog(ws, LOG_INFO,
798 "could not disable system calls, kernel might not support seccomp");
799 }
800 }
801
802 if (ws->remote_addr_len == sizeof(struct sockaddr_in))
803 ws->proto = AF_INET;
804 else
805 ws->proto = AF_INET6;
806
807 if (GETCONFIG(ws)->listen_proxy_proto) {
808 oclog(ws, LOG_DEBUG, "accepted proxy protocol connection");
809 ret = parse_proxy_proto_header(ws, ws->conn_fd);
810 if (ret < 0) {
811 oclog(ws, LOG_ERR,
812 "could not parse proxy protocol header; discarding connection");
813 exit_worker(ws);
814 }
815 } else {
816 oclog(ws, LOG_DEBUG, "accepted connection");
817 }
818
819 if (ws->conn_type != SOCK_TYPE_UNIX) {
820 /* ws->vhost is being assigned in gnutls_handshake()
821 * after client hello is received. We set temporarily a value
822 * as we need to set some cipher priorities for handshake to start. */
823 ws->vhost = find_vhost(ws->vconfig, NULL);
824
825 if (test_for_tcp_health_probe(ws) != 0) {
826 oclog(ws, LOG_DEBUG, "Received TCP health probe from load-balancer");
827 exit_worker_reason(ws, REASON_HEALTH_PROBE);
828 }
829
830 /* initialize the session */
831 ret = gnutls_init(&session, GNUTLS_SERVER);
832 GNUTLS_FATAL_ERR(ret);
833
834 ret = gnutls_priority_set(session, WSCREDS(ws)->cprio);
835 GNUTLS_FATAL_ERR(ret);
836 gnutls_session_set_ptr(session, ws);
837
838 /* if we have a single vhost, avoid going through a callback to set credentials. */
839 if (!HAVE_VHOSTS(ws)) {
840 SET_VHOST_CREDS;
841 } else {
842 #ifdef SIMULATE_CLIENT_HELLO_HOOK
843 peek_client_hello(ws, session, ws->conn_fd);
844 #else
845 gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_CLIENT_HELLO,
846 GNUTLS_HOOK_PRE, hello_hook_func);
847 #endif
848 }
849
850 gnutls_transport_set_ptr(session,
851 (gnutls_transport_ptr_t) (long)ws->conn_fd);
852
853 set_resume_db_funcs(session);
854 gnutls_db_set_ptr(session, ws);
855
856 gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
857 gnutls_transport_set_pull_timeout_function(session, tls_pull_timeout);
858 do {
859 ret = gnutls_handshake(session);
860 } while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
861 GNUTLS_FATAL_ERR(ret);
862
863 oclog(ws, LOG_DEBUG, "TLS handshake completed");
864 } else {
865 ws->vhost = find_vhost(ws->vconfig, NULL);
866
867 oclog(ws, LOG_DEBUG, "Accepted unix connection");
868 }
869
870 ws->session = session;
871
872 session_info_send(ws);
873
874 memset(&settings, 0, sizeof(settings));
875
876 ws->selected_auth = &WSPCONFIG(ws)->auth[0];
877 if (ws->cert_auth_ok)
878 ws_switch_auth_to(ws, AUTH_TYPE_CERTIFICATE);
879
880 settings.on_url = http_url_cb;
881 settings.on_header_field = http_header_field_cb;
882 settings.on_header_value = http_header_value_cb;
883 settings.on_headers_complete = http_header_complete_cb;
884 settings.on_message_complete = http_message_complete_cb;
885 settings.on_body = http_body_cb;
886 http_req_init(ws);
887
888 if (WSCONFIG(ws)->listen_proxy_proto) {
889 oclog(ws, LOG_DEBUG, "proxy-hdr: peer is %s\n", ws->remote_ip_str);
890 }
891
892 ws->parser = &parser;
893
894 restart:
895 if (requests_left-- <= 0) {
896 oclog(ws, LOG_INFO, "maximum number of HTTP requests reached");
897 exit_worker(ws);
898 }
899
900 http_parser_init(&parser, HTTP_REQUEST);
901 parser.data = ws;
902 http_req_reset(ws);
903 /* parse as we go */
904 do {
905 nrecvd = cstp_recv(ws, ws->buffer, sizeof(ws->buffer));
906 if (nrecvd <= 0) {
907 if (nrecvd == 0)
908 goto finish;
909 if (nrecvd != GNUTLS_E_PREMATURE_TERMINATION)
910 oclog(ws, LOG_WARNING,
911 "error receiving client data");
912 exit_worker(ws);
913 }
914
915 nparsed =
916 http_parser_execute(&parser, &settings, (void *)ws->buffer,
917 nrecvd);
918 if (nparsed == 0) {
919 oclog(ws, LOG_INFO, "error parsing HTTP request");
920 exit_worker(ws);
921 }
922 } while (ws->req.headers_complete == 0);
923
924 if (parser.method == HTTP_GET) {
925 oclog(ws, LOG_HTTP_DEBUG, "HTTP GET %s", ws->req.url);
926 fn = http_get_url_handler(ws->req.url);
927 if (fn == NULL) {
928 oclog(ws, LOG_HTTP_DEBUG, "unexpected URL %s", ws->req.url);
929 response_404(ws, parser.http_minor);
930 goto finish;
931 }
932 ret = fn(ws, parser.http_minor);
933 if (ret == 0
934 && (parser.http_major != 1 || parser.http_minor != 0))
935 goto restart;
936
937 } else if (parser.method == HTTP_POST) {
938 /* continue reading */
939 oclog(ws, LOG_HTTP_DEBUG, "HTTP POST %s", ws->req.url);
940 while (ws->req.message_complete == 0) {
941 nrecvd = cstp_recv(ws, ws->buffer, sizeof(ws->buffer));
942 CSTP_FATAL_ERR(ws, nrecvd);
943
944 if (nrecvd == 0) {
945 oclog(ws, LOG_HTTP_DEBUG,
946 "EOF while receiving HTTP POST request");
947 exit_worker(ws);
948 }
949
950 nparsed =
951 http_parser_execute(&parser, &settings, (void *)ws->buffer,
952 nrecvd);
953 if (nparsed == 0) {
954 oclog(ws, LOG_HTTP_DEBUG,
955 "error parsing HTTP POST request");
956 exit_worker(ws);
957 }
958 }
959
960 fn = http_post_url_handler(ws, ws->req.url);
961 if (fn == NULL) {
962 oclog(ws, LOG_HTTP_DEBUG, "unexpected POST URL %s",
963 ws->req.url);
964 response_404(ws, parser.http_minor);
965 goto finish;
966 }
967
968 ret = fn(ws, parser.http_minor);
969 if (ret == 0
970 && (parser.http_major != 1 || parser.http_minor != 0))
971 goto restart;
972
973 } else if (parser.method == HTTP_CONNECT) {
974 oclog(ws, LOG_HTTP_DEBUG, "HTTP CONNECT %s", ws->req.url);
975 ret = connect_handler(ws);
976 if (ret == 0
977 && (parser.http_major != 1 || parser.http_minor != 0))
978 goto restart;
979
980 } else {
981 oclog(ws, LOG_HTTP_DEBUG, "unexpected HTTP method %s",
982 http_method_str(parser.method));
983 response_404(ws, parser.http_minor);
984 }
985
986 finish:
987 cstp_close(ws);
988 }
989
990 static
data_mtu_send(worker_st * ws,unsigned mtu)991 void data_mtu_send(worker_st * ws, unsigned mtu)
992 {
993 TunMtuMsg msg = TUN_MTU_MSG__INIT;
994
995 msg.mtu = mtu;
996 send_msg_to_main(ws, CMD_TUN_MTU, &msg,
997 (pack_size_func) tun_mtu_msg__get_packed_size,
998 (pack_func) tun_mtu_msg__pack);
999
1000 oclog(ws, LOG_DEBUG, "setting data MTU to %u", msg.mtu);
1001 }
1002
1003 static
session_info_send(worker_st * ws)1004 void session_info_send(worker_st * ws)
1005 {
1006 SessionInfoMsg msg = SESSION_INFO_MSG__INIT;
1007
1008 if (ws->session) {
1009 msg.tls_ciphersuite = gnutls_session_get_desc(ws->session);
1010 if (ws->cstp_selected_comp)
1011 msg.cstp_compr = (char*)ws->cstp_selected_comp->name;
1012 }
1013
1014 if (DTLS_ACTIVE(ws)->udp_state != UP_DISABLED && DTLS_ACTIVE(ws)->dtls_session) {
1015 msg.dtls_ciphersuite =
1016 gnutls_session_get_desc(DTLS_ACTIVE(ws)->dtls_session);
1017 if (ws->dtls_selected_comp)
1018 msg.dtls_compr = (char*)ws->dtls_selected_comp->name;
1019 }
1020
1021 if (WSCONFIG(ws)->listen_proxy_proto) {
1022 msg.our_addr.data = (uint8_t*)&ws->our_addr;
1023 msg.our_addr.len = ws->our_addr_len;
1024 msg.has_our_addr = 1;
1025 msg.remote_addr.data = (uint8_t*)&ws->remote_addr;
1026 msg.remote_addr.len = ws->remote_addr_len;
1027 msg.has_remote_addr = 1;
1028 }
1029
1030 send_msg_to_main(ws, CMD_SESSION_INFO, &msg,
1031 (pack_size_func) session_info_msg__get_packed_size,
1032 (pack_func) session_info_msg__pack);
1033
1034 gnutls_free(msg.tls_ciphersuite);
1035 gnutls_free(msg.dtls_ciphersuite);
1036 }
1037
1038 /* link_mtu_set: Sets the link MTU for the session
1039 *
1040 * @ws: a worker structure
1041 * @mtu: the link MTU
1042 */
1043 static
link_mtu_set(struct worker_st * ws,struct dtls_st * dtls,unsigned mtu)1044 void link_mtu_set(struct worker_st * ws, struct dtls_st * dtls, unsigned mtu)
1045 {
1046 if (ws->link_mtu == mtu || mtu > sizeof(ws->buffer))
1047 return;
1048
1049 ws->link_mtu = mtu;
1050
1051 oclog(ws, LOG_DEBUG, "setting connection link MTU to %u", mtu);
1052 if (dtls->dtls_session)
1053 gnutls_dtls_set_mtu(dtls->dtls_session,
1054 ws->link_mtu - ws->dtls_proto_overhead);
1055
1056 data_mtu_send(ws, DATA_MTU(ws, ws->link_mtu));
1057 }
1058
1059 /* data_mtu_set: Sets the data MTU for the session
1060 *
1061 * @ws: a worker structure
1062 * @mtu: the "plaintext" data MTU (not including the DTLS protocol byte)
1063 */
1064 static
data_mtu_set(worker_st * ws,struct dtls_st * dtls,unsigned mtu)1065 void data_mtu_set(worker_st * ws, struct dtls_st * dtls, unsigned mtu)
1066 {
1067 if (dtls->dtls_session) {
1068 gnutls_dtls_set_data_mtu(dtls->dtls_session, mtu+1);
1069
1070 mtu = gnutls_dtls_get_mtu(dtls->dtls_session);
1071 if (mtu <= 0 || mtu == ws->link_mtu)
1072 return;
1073
1074 mtu += ws->dtls_proto_overhead;
1075 link_mtu_set(ws, dtls, mtu);
1076 }
1077 }
1078
disable_mtu_disc(worker_st * ws,struct dtls_st * dtls)1079 static void disable_mtu_disc(worker_st *ws, struct dtls_st * dtls)
1080 {
1081 oclog(ws, LOG_DEBUG, "disabling MTU discovery on UDP socket");
1082 set_mtu_disc(dtls->dtls_tptr.fd, ws->proto, 0);
1083 link_mtu_set(ws, dtls, ws->adv_link_mtu);
1084 WSCONFIG(ws)->try_mtu = 0;
1085 }
1086
1087 /* sets the current value of mtu as bad,
1088 * and returns an estimation of good.
1089 *
1090 * Returns -1 on failure.
1091 */
1092 static
mtu_not_ok(worker_st * ws,struct dtls_st * dtls)1093 int mtu_not_ok(worker_st * ws, struct dtls_st * dtls)
1094 {
1095 if (WSCONFIG(ws)->try_mtu == 0 || dtls->dtls_session == NULL)
1096 return 0;
1097
1098 if (ws->proto == AF_INET) {
1099 const unsigned min = MIN_MTU(ws);
1100
1101 ws->last_bad_mtu = ws->link_mtu;
1102
1103 if (ws->last_good_mtu == min) {
1104 oclog(ws, LOG_INFO,
1105 "could not calculate a sufficient MTU; disabling MTU discovery");
1106 disable_mtu_disc(ws, dtls);
1107 link_mtu_set(ws, dtls, min);
1108 return 0;
1109 }
1110
1111 if (ws->last_good_mtu >= ws->link_mtu) {
1112 ws->last_good_mtu = MAX(((2 * (ws->link_mtu)) / 3), min);
1113 }
1114
1115 link_mtu_set(ws, dtls, ws->last_good_mtu);
1116 oclog(ws, LOG_INFO, "MTU %u is too large, switching to %u",
1117 ws->last_bad_mtu, ws->link_mtu);
1118 } else if (ws->proto == AF_INET6) { /* IPv6 */
1119 #ifdef IPV6_PATHMTU
1120 struct ip6_mtuinfo mtuinfo;
1121 socklen_t len = sizeof(mtuinfo);
1122
1123 if (getsockopt(dtls->dtls_tptr.fd, IPPROTO_IPV6, IPV6_PATHMTU, &mtuinfo, &len) < 0 || mtuinfo.ip6m_mtu < 1280) {
1124 oclog(ws, LOG_INFO, "cannot obtain IPv6 MTU (was %u); disabling MTU discovery",
1125 ws->link_mtu);
1126 disable_mtu_disc(ws, dtls);
1127 link_mtu_set(ws, dtls, MIN_MTU(ws));
1128 return 0;
1129 }
1130
1131 oclog(ws, LOG_DEBUG, "setting (via IPV6_PATHMTU) connection MTU to %u", mtuinfo.ip6m_mtu);
1132 link_mtu_set(ws, dtls, mtuinfo.ip6m_mtu);
1133
1134 if (mtuinfo.ip6m_mtu > ws->adv_link_mtu) {
1135 oclog(ws, LOG_INFO, "the discovered IPv6 MTU (%u) is larger than the advertised (%u); disabling MTU discovery",
1136 (unsigned)mtuinfo.ip6m_mtu, ws->adv_link_mtu);
1137 return 0;
1138 }
1139 #else
1140 link_mtu_set(ws, dtls, MIN_MTU(ws));
1141 #endif
1142 }
1143
1144 return 0;
1145 }
1146
1147 /* mtu_discovery_init: initiates MTU discovery
1148 *
1149 * @ws: a worker structure
1150 * @mtu: the current "plaintext" data MTU
1151 */
mtu_discovery_init(worker_st * ws,struct dtls_st * dtls,unsigned mtu)1152 static void mtu_discovery_init(worker_st * ws, struct dtls_st * dtls, unsigned mtu)
1153 {
1154 const unsigned min = MIN_MTU(ws);
1155 if (mtu <= min) {
1156 oclog(ws, LOG_INFO,
1157 "our initial MTU is too low; disabling MTU discovery");
1158 disable_mtu_disc(ws, dtls);
1159 }
1160
1161 if (!WSCONFIG(ws)->try_mtu)
1162 oclog(ws, LOG_DEBUG,
1163 "Initializing MTU discovery; initial MTU: %u\n", mtu);
1164
1165 ws->last_good_mtu = mtu;
1166 ws->last_bad_mtu = mtu;
1167 }
1168
1169 static
mtu_ok(worker_st * ws,struct dtls_st * dtls)1170 void mtu_ok(worker_st * ws, struct dtls_st * dtls)
1171 {
1172 unsigned int c;
1173
1174 if (WSCONFIG(ws)->try_mtu == 0 || ws->proto == AF_INET6)
1175 return;
1176
1177 if (ws->last_bad_mtu == (ws->link_mtu) + 1 ||
1178 ws->last_bad_mtu == (ws->link_mtu))
1179 return;
1180
1181 ws->last_good_mtu = ws->link_mtu;
1182 c = (ws->link_mtu + ws->last_bad_mtu) / 2;
1183
1184 link_mtu_set(ws, dtls, c);
1185 return;
1186 }
1187
1188 #define FUZZ(x, diff, rnd) \
1189 if (x > diff) { \
1190 int16_t r = rnd; \
1191 x += r % diff; \
1192 }
1193
get_pmtu_approx(worker_st * ws)1194 int get_pmtu_approx(worker_st *ws)
1195 {
1196 socklen_t sl;
1197 int ret, e;
1198
1199 #if defined(__linux__) && defined(TCP_INFO)
1200 struct tcp_info ti;
1201 sl = sizeof(ti);
1202
1203 ret = getsockopt(ws->conn_fd, IPPROTO_TCP, TCP_INFO, &ti, &sl);
1204 if (ret == -1) {
1205 e = errno;
1206 oclog(ws, LOG_INFO, "error in getting TCP_INFO: %s",
1207 strerror(e));
1208 return -1;
1209 } else {
1210 return ti.tcpi_pmtu;
1211 }
1212 #else
1213 int max = -1;
1214
1215 sl = sizeof(max);
1216 ret = getsockopt(ws->conn_fd, IPPROTO_TCP, TCP_MAXSEG, &max, &sl);
1217 if (ret == -1) {
1218 e = errno;
1219 oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s",
1220 strerror(e));
1221 return -1;
1222 } else {
1223 MSS_ADJUST(max);
1224 return max;
1225 }
1226 #endif
1227 }
1228
1229 static
periodic_check(worker_st * ws,struct timespec * tnow,unsigned dpd)1230 int periodic_check(worker_st * ws, struct timespec *tnow, unsigned dpd)
1231 {
1232 int max, ret;
1233 time_t now = tnow->tv_sec;
1234 time_t periodic_check_time = PERIODIC_CHECK_TIME;
1235
1236 /* modify timers with a fuzzying factor, to prevent all worker processes
1237 * to act at exactly the same time (e.g., after a server restart on which
1238 * all clients reconnect at the same time). */
1239 FUZZ(periodic_check_time, 5, tnow->tv_nsec);
1240
1241 if (now - ws->last_periodic_check < periodic_check_time)
1242 return 0;
1243
1244 /* we set an alarm at each periodic check to prevent any
1245 * freezes in the worker due to an unexpected block (due to worker
1246 * bug or kernel bug). In that case the worker will be killed due
1247 * the the alarm instead of hanging. */
1248 terminate_reason = REASON_SERVER_DISCONNECT;
1249 alarm(1800);
1250
1251 if (WSCONFIG(ws)->idle_timeout > 0) {
1252 if (now - ws->last_nc_msg > WSCONFIG(ws)->idle_timeout) {
1253 oclog(ws, LOG_ERR,
1254 "idle timeout reached for process (%d secs)",
1255 (int)(now - ws->last_nc_msg));
1256 terminate = 1;
1257 terminate_reason = REASON_IDLE_TIMEOUT;
1258 goto cleanup;
1259 }
1260 }
1261
1262 if (ws->user_config->session_timeout_secs > 0) {
1263 if (now - ws->session_start_time > ws->user_config->session_timeout_secs) {
1264 oclog(ws, LOG_NOTICE,
1265 "session timeout reached for process (%d secs)",
1266 (int)(now - ws->session_start_time));
1267 terminate = 1;
1268 terminate_reason = REASON_SESSION_TIMEOUT;
1269 goto cleanup;
1270 }
1271 }
1272
1273 if (ws->user_config->interim_update_secs > 0 &&
1274 now - ws->last_stats_msg >= ws->user_config->interim_update_secs &&
1275 ws->sid_set) {
1276 send_stats_to_secmod(ws, now, 0);
1277 }
1278
1279 #if defined(CAPTURE_LATENCY_SUPPORT)
1280 if (now - ws->latency.last_stats_msg >= LATENCY_WORKER_AGGREGATION_TIME) {
1281 send_latency_stats_delta_to_main(ws, now);
1282 }
1283 #endif
1284
1285 /* check DPD. Otherwise exit */
1286 if (DTLS_ACTIVE(ws)->udp_state == UP_ACTIVE &&
1287 now - ws->last_msg_udp > DPD_TRIES * dpd && dpd > 0) {
1288 unsigned data_mtu = DATA_MTU(ws, ws->link_mtu);
1289 oclog(ws, LOG_NOTICE,
1290 "have not received any UDP message or DPD for long (%d secs, DPD is %d)",
1291 (int)(now - ws->last_msg_udp), dpd);
1292
1293 memset(ws->buffer+1, 0, data_mtu);
1294 ws->buffer[0] = AC_PKT_DPD_OUT;
1295
1296 ret = dtls_send(DTLS_ACTIVE(ws), ws->buffer, data_mtu+1);
1297 DTLS_FATAL_ERR_CMD(ret, exit_worker_reason(ws, REASON_ERROR));
1298
1299 if (now - ws->last_msg_udp > DPD_MAX_TRIES * dpd) {
1300 oclog(ws, LOG_ERR,
1301 "have not received UDP message or DPD for very long; disabling UDP port");
1302 DTLS_ACTIVE(ws)->udp_state = UP_INACTIVE;
1303 }
1304 }
1305 if (dpd > 0 && now - ws->last_msg_tcp > DPD_TRIES * dpd) {
1306 oclog(ws, LOG_NOTICE,
1307 "have not received TCP DPD for long (%d secs)",
1308 (int)(now - ws->last_msg_tcp));
1309 ws->buffer[0] = 'S';
1310 ws->buffer[1] = 'T';
1311 ws->buffer[2] = 'F';
1312 ws->buffer[3] = 1;
1313 ws->buffer[4] = 0;
1314 ws->buffer[5] = 0;
1315 ws->buffer[6] = AC_PKT_DPD_OUT;
1316 ws->buffer[7] = 0;
1317
1318 ret = cstp_send(ws, ws->buffer, 8);
1319 CSTP_FATAL_ERR_CMD(ws, ret, exit_worker_reason(ws, REASON_ERROR));
1320
1321 if (now - ws->last_msg_tcp > DPD_MAX_TRIES * dpd) {
1322 oclog(ws, LOG_NOTICE,
1323 "connection timeout (DPD); tearing down connection");
1324 exit_worker_reason(ws, REASON_DPD_TIMEOUT);
1325 }
1326 }
1327
1328 if (ws->conn_type != SOCK_TYPE_UNIX && DTLS_ACTIVE(ws)->udp_state != UP_DISABLED) {
1329 max = get_pmtu_approx(ws);
1330 if (max > 0 && max < ws->link_mtu) {
1331 oclog(ws, LOG_DEBUG, "reducing MTU due to TCP/PMTU to %u",
1332 max);
1333 link_mtu_set(ws, DTLS_ACTIVE(ws), max);
1334 }
1335 }
1336
1337 cleanup:
1338 ws->last_periodic_check = now;
1339
1340 return 0;
1341 }
1342
1343 /* Disable any TCP queuing on the TLS port. This allows a connection that works over
1344 * TCP instead of UDP to still be interactive.
1345 */
set_no_delay(worker_st * ws,int fd)1346 static void set_no_delay(worker_st * ws, int fd)
1347 {
1348 int flag = 1;
1349 int ret;
1350
1351 ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
1352 if (ret == -1) {
1353 oclog(ws, LOG_DEBUG,
1354 "setsockopt(TCP_NODELAY) to %x, failed.", (unsigned)flag);
1355 return;
1356 }
1357 }
1358
1359 #define TOSCLASS(x) (IPTOS_CLASS_CS##x)
1360
set_net_priority(worker_st * ws,int fd,int priority)1361 static void set_net_priority(worker_st * ws, int fd, int priority)
1362 {
1363 int t;
1364 int ret;
1365 #if defined(IP_TOS)
1366 if (priority != 0 && IS_TOS(priority)) {
1367 t = TOS_UNPACK(priority);
1368 ret = setsockopt(fd, IPPROTO_IP, IP_TOS, &t, sizeof(t));
1369 if (ret == -1)
1370 oclog(ws, LOG_DEBUG,
1371 "setsockopt(IP_TOS) to %x, failed.", (unsigned)t);
1372
1373 return;
1374 }
1375 #endif
1376
1377 #ifdef SO_PRIORITY
1378 if (priority != 0 && priority <= 7) {
1379 t = ws->user_config->net_priority - 1;
1380 ret = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &t, sizeof(t));
1381 if (ret == -1)
1382 oclog(ws, LOG_DEBUG,
1383 "setsockopt(SO_PRIORITY) to %d, failed.", t);
1384
1385 return;
1386 }
1387 #endif
1388 return;
1389 }
1390
1391 #define SEND_ERR(x) if (x<0) goto send_error
1392
dtls_mainloop(worker_st * ws,struct dtls_st * dtls,struct timespec * tnow)1393 static int dtls_mainloop(worker_st * ws, struct dtls_st * dtls, struct timespec *tnow)
1394 {
1395 int ret;
1396 gnutls_datum_t data;
1397 void *packet = NULL;
1398
1399 switch (dtls->udp_state) {
1400 case UP_ACTIVE:
1401 case UP_INACTIVE:
1402 ret = dtls_recv_packet(dtls, &data, &packet);
1403 oclog(ws, LOG_TRANSFER_DEBUG,
1404 "received %d byte(s) (DTLS)", ret);
1405
1406 DTLS_FATAL_ERR_CMD(ret, exit_worker_reason(ws, REASON_ERROR));
1407
1408 if (ret == GNUTLS_E_REHANDSHAKE) {
1409
1410 if (dtls->last_dtls_rehandshake > 0 &&
1411 tnow->tv_sec - dtls->last_dtls_rehandshake <
1412 WSCONFIG(ws)->rekey_time / 2) {
1413 oclog(ws, LOG_INFO,
1414 "client requested DTLS rehandshake too soon");
1415 ret = -1;
1416 goto cleanup;
1417 }
1418
1419 /* there is not much we can rehandshake on the DTLS channel,
1420 * at least not the way AnyConnect sets it up.
1421 */
1422 oclog(ws, LOG_DEBUG,
1423 "client requested rehandshake on DTLS channel");
1424
1425 do {
1426 ret = gnutls_handshake(dtls->dtls_session);
1427 } while (ret == GNUTLS_E_AGAIN
1428 || ret == GNUTLS_E_INTERRUPTED);
1429
1430 DTLS_FATAL_ERR_CMD(ret, exit_worker_reason(ws, REASON_ERROR));
1431 oclog(ws, LOG_DEBUG, "DTLS rehandshake completed");
1432
1433 dtls->last_dtls_rehandshake = tnow->tv_sec;
1434 } else if (ret >= 1) {
1435 /* where we receive any DTLS UDP packet we reset the state
1436 * to active */
1437 dtls->udp_state = UP_ACTIVE;
1438
1439 if (bandwidth_update
1440 (&ws->b_rx, data.size - CSTP_DTLS_OVERHEAD, tnow) != 0) {
1441 ret =
1442 parse_dtls_data(ws, data.data, data.size,
1443 tnow->tv_sec);
1444 if (ret < 0) {
1445 oclog(ws, LOG_INFO,
1446 "error parsing CSTP data");
1447 goto cleanup;
1448 }
1449 }
1450 } else
1451 oclog(ws, LOG_TRANSFER_DEBUG,
1452 "no data received (%d)", ret);
1453
1454 ws->udp_recv_time = tnow->tv_sec;
1455 break;
1456 case UP_SETUP:
1457 ret = setup_dtls_connection(ws, dtls);
1458 if (ret < 0) {
1459 ret = -1;
1460 goto cleanup;
1461 }
1462
1463 gnutls_dtls_set_mtu(dtls->dtls_session, ws->link_mtu - ws->dtls_proto_overhead);
1464 mtu_discovery_init(ws, dtls, ws->link_mtu);
1465 break;
1466
1467 case UP_HANDSHAKE:
1468 hsk_restart:
1469 ret = gnutls_handshake(dtls->dtls_session);
1470 if (ret < 0 && gnutls_error_is_fatal(ret) != 0) {
1471 if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
1472 oclog(ws, LOG_ERR,
1473 "error in DTLS handshake: %s: %s\n",
1474 gnutls_strerror(ret),
1475 gnutls_alert_get_name
1476 (gnutls_alert_get(dtls->dtls_session)));
1477 else
1478 oclog(ws, LOG_ERR,
1479 "error in DTLS handshake: %s\n",
1480 gnutls_strerror(ret));
1481 dtls->udp_state = UP_DISABLED;
1482 ev_io_stop(worker_loop, &dtls->io);
1483 break;
1484 }
1485
1486 if (ret == GNUTLS_E_LARGE_PACKET) {
1487 /* adjust mtu */
1488 mtu_not_ok(ws, dtls);
1489 goto hsk_restart;
1490 } else if (ret == 0) {
1491 unsigned data_mtu;
1492
1493 /* gnutls_dtls_get_data_mtu() already subtracts the crypto overhead */
1494 data_mtu =
1495 gnutls_dtls_get_data_mtu(dtls->dtls_session) -
1496 CSTP_DTLS_OVERHEAD;
1497
1498 dtls->udp_state = UP_ACTIVE;
1499 oclog(ws, LOG_DEBUG,
1500 "DTLS handshake completed (link MTU: %u, data MTU: %u)\n",
1501 ws->link_mtu, data_mtu);
1502 ws->dtls_active_session++;
1503 oclog(ws, LOG_DEBUG,
1504 "Maing DTLS session %d active", ws->dtls_active_session);
1505 session_info_send(ws);
1506 }
1507
1508 break;
1509 default:
1510 break;
1511 }
1512
1513 ret = 0;
1514 cleanup:
1515 packet_deinit(packet);
1516 return ret;
1517 }
1518
tls_mainloop(struct worker_st * ws,struct timespec * tnow)1519 static int tls_mainloop(struct worker_st *ws, struct timespec *tnow)
1520 {
1521 int ret;
1522 gnutls_datum_t data;
1523 void *packet = NULL;
1524
1525 ret = cstp_recv_packet(ws, &data, &packet);
1526 if (ret == GNUTLS_E_PREMATURE_TERMINATION) {
1527 oclog(ws, LOG_DEBUG, "client disconnected prematurely");
1528 ret = -1;
1529 goto cleanup;
1530 }
1531
1532 CSTP_FATAL_ERR_CMD(ws, ret, exit_worker_reason(ws, REASON_ERROR));
1533
1534 if (ret == 0) { /* disconnect */
1535 oclog(ws, LOG_DEBUG, "client disconnected");
1536 ret = -1;
1537 goto cleanup;
1538 } else if (ret >= 8) {
1539 oclog(ws, LOG_TRANSFER_DEBUG, "received %d byte(s) (TLS)", data.size);
1540
1541 if (bandwidth_update(&ws->b_rx, data.size - 8, tnow) != 0) {
1542 ret = parse_cstp_data(ws, data.data, data.size, tnow->tv_sec);
1543 if (ret < 0) {
1544 oclog(ws, LOG_ERR, "error parsing CSTP data");
1545 goto cleanup;
1546 }
1547
1548 if ((ret == AC_PKT_DATA || ret == AC_PKT_COMPRESSED) && DTLS_ACTIVE(ws)->udp_state == UP_ACTIVE) {
1549 /* client switched to TLS for some reason */
1550 if (tnow->tv_sec - ws->udp_recv_time >
1551 UDP_SWITCH_TIME)
1552 DTLS_ACTIVE(ws)->udp_state = UP_INACTIVE;
1553 }
1554 }
1555
1556 } else if (ret == GNUTLS_E_REHANDSHAKE) {
1557 /* rekey? */
1558 if (ws->last_tls_rehandshake > 0 &&
1559 tnow->tv_sec - ws->last_tls_rehandshake <
1560 WSCONFIG(ws)->rekey_time / 2) {
1561 oclog(ws, LOG_INFO,
1562 "client requested TLS rehandshake too soon");
1563 ret = -1;
1564 goto cleanup;
1565 }
1566
1567 oclog(ws, LOG_INFO,
1568 "client requested rehandshake on TLS channel");
1569 do {
1570 ret = gnutls_handshake(ws->session);
1571 } while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
1572 DTLS_FATAL_ERR_CMD(ret, exit_worker_reason(ws, REASON_ERROR));
1573
1574 ws->last_tls_rehandshake = tnow->tv_sec;
1575 oclog(ws, LOG_INFO, "TLS rehandshake completed");
1576 }
1577
1578 ret = 0;
1579 cleanup:
1580 packet_deinit(packet);
1581 return ret;
1582 }
1583
tun_mainloop(struct worker_st * ws,struct timespec * tnow)1584 static int tun_mainloop(struct worker_st *ws, struct timespec *tnow)
1585 {
1586 int ret, l, e;
1587 unsigned tls_retry;
1588 int dtls_type = AC_PKT_DATA;
1589 int cstp_type = AC_PKT_DATA;
1590 gnutls_datum_t dtls_to_send;
1591 gnutls_datum_t cstp_to_send;
1592
1593 l = tun_read(ws->tun_fd, ws->buffer + 8, DATA_MTU(ws, ws->link_mtu));
1594 if (l < 0) {
1595 e = errno;
1596
1597 if (e != EAGAIN && e != EINTR) {
1598 oclog(ws, LOG_ERR,
1599 "received corrupt data from tun (%d): %s",
1600 l, strerror(e));
1601 return -1;
1602 }
1603
1604 return 0;
1605 }
1606
1607 if (l == 0) {
1608 oclog(ws, LOG_INFO, "TUN device returned zero");
1609 return 0;
1610 }
1611
1612
1613 dtls_to_send.data = ws->buffer;
1614 dtls_to_send.size = l;
1615
1616 cstp_to_send.data = ws->buffer;
1617 cstp_to_send.size = l;
1618
1619 if (WSCONFIG(ws)->switch_to_tcp_timeout &&
1620 DTLS_ACTIVE(ws)->udp_state == UP_ACTIVE &&
1621 tnow->tv_sec > ws->udp_recv_time + WSCONFIG(ws)->switch_to_tcp_timeout) {
1622 oclog(ws, LOG_DEBUG, "No UDP data received for %li seconds, using TCP instead\n",
1623 tnow->tv_sec - ws->udp_recv_time);
1624 DTLS_ACTIVE(ws)->udp_state = UP_INACTIVE;
1625 }
1626
1627 #ifdef ENABLE_COMPRESSION
1628 if (DTLS_ACTIVE(ws)->udp_state == UP_ACTIVE && ws->dtls_selected_comp != NULL && l > WSCONFIG(ws)->no_compress_limit) {
1629 /* otherwise don't compress */
1630 ret = ws->dtls_selected_comp->compress(ws->decomp+8, sizeof(ws->decomp)-8, ws->buffer+8, l);
1631 oclog(ws, LOG_TRANSFER_DEBUG, "compressed %d to %d\n", (int)l, ret);
1632 if (ret > 0 && ret < l) {
1633 dtls_to_send.data = ws->decomp;
1634 dtls_to_send.size = ret;
1635 dtls_type = AC_PKT_COMPRESSED;
1636
1637 if (ws->cstp_selected_comp) {
1638 if (ws->cstp_selected_comp->id == ws->dtls_selected_comp->id) {
1639 cstp_to_send.data = ws->decomp;
1640 cstp_to_send.size = ret;
1641 cstp_type = AC_PKT_COMPRESSED;
1642 }
1643 }
1644 }
1645 } else if (ws->cstp_selected_comp != NULL && l > WSCONFIG(ws)->no_compress_limit) {
1646 /* otherwise don't compress */
1647 ret = ws->cstp_selected_comp->compress(ws->decomp+8, sizeof(ws->decomp)-8, ws->buffer+8, l);
1648 oclog(ws, LOG_TRANSFER_DEBUG, "compressed %d to %d\n", (int)l, ret);
1649 if (ret > 0 && ret < l) {
1650 cstp_to_send.data = ws->decomp;
1651 cstp_to_send.size = ret;
1652 cstp_type = AC_PKT_COMPRESSED;
1653 }
1654 }
1655 #endif
1656
1657 /* only transmit if allowed */
1658 if (bandwidth_update(&ws->b_tx, dtls_to_send.size, tnow)
1659 != 0) {
1660 tls_retry = 0;
1661
1662 oclog(ws, LOG_TRANSFER_DEBUG, "sending %d byte(s)\n", l);
1663
1664 if (DTLS_ACTIVE(ws)->udp_state == UP_ACTIVE) {
1665
1666 ws->tun_bytes_out += dtls_to_send.size;
1667
1668 dtls_to_send.data[7] = dtls_type;
1669 ret = dtls_send(DTLS_ACTIVE(ws), dtls_to_send.data + 7, dtls_to_send.size + 1);
1670 DTLS_FATAL_ERR_CMD(ret, exit_worker_reason(ws, REASON_ERROR));
1671
1672 if (ret == GNUTLS_E_LARGE_PACKET) {
1673 mtu_not_ok(ws, DTLS_ACTIVE(ws));
1674
1675 oclog(ws, LOG_TRANSFER_DEBUG,
1676 "retrying (TLS) %d\n", l);
1677 tls_retry = 1;
1678 } else if (ret >= 1+DATA_MTU(ws, ws->link_mtu) &&
1679 WSCONFIG(ws)->try_mtu != 0) {
1680 mtu_ok(ws, DTLS_ACTIVE(ws));
1681 }
1682 }
1683
1684 if (DTLS_ACTIVE(ws)->udp_state != UP_ACTIVE || tls_retry != 0) {
1685 cstp_to_send.data[0] = 'S';
1686 cstp_to_send.data[1] = 'T';
1687 cstp_to_send.data[2] = 'F';
1688 cstp_to_send.data[3] = 1;
1689 cstp_to_send.data[4] = cstp_to_send.size >> 8;
1690 cstp_to_send.data[5] = cstp_to_send.size & 0xff;
1691 cstp_to_send.data[6] = cstp_type;
1692 cstp_to_send.data[7] = 0;
1693
1694 ws->tun_bytes_out += cstp_to_send.size;
1695
1696 ret = cstp_send(ws, cstp_to_send.data, cstp_to_send.size + 8);
1697 CSTP_FATAL_ERR_CMD(ws, ret, exit_worker_reason(ws, REASON_ERROR));
1698 }
1699 ws->last_nc_msg = tnow->tv_sec;
1700 }
1701
1702 return 0;
1703 }
1704
1705 static
replace_vals(worker_st * ws,const char * txt)1706 char *replace_vals(worker_st *ws, const char *txt)
1707 {
1708 str_st str;
1709 int ret;
1710 str_rep_tab tab[3];
1711
1712 STR_TAB_SET(0, "%{U}", ws->username);
1713 STR_TAB_SET(1, "%{G}", ws->groupname);
1714 STR_TAB_TERM(2);
1715
1716 str_init(&str, ws);
1717
1718 ret = str_append_str(&str, txt);
1719 if (ret < 0)
1720 return NULL;
1721
1722 ret = str_replace_str(&str, tab);
1723 if (ret < 0) {
1724 str_clear(&str);
1725 return NULL;
1726 }
1727
1728 return (char*)str.data;
1729 }
1730
send_routes(worker_st * ws,struct http_req_st * req,char ** routes,unsigned routes_size,bool include)1731 static int send_routes(worker_st *ws, struct http_req_st *req,
1732 char **routes, unsigned routes_size,
1733 bool include)
1734 {
1735 unsigned i;
1736 unsigned ip6;
1737 const char *txt;
1738 int ret;
1739
1740 if (include)
1741 txt = "Include";
1742 else
1743 txt = "Exclude";
1744
1745 for (i = 0; i < routes_size; i++) {
1746 if (strchr(routes[i], ':') != 0)
1747 ip6 = 1;
1748 else
1749 ip6 = 0;
1750
1751 if (req->no_ipv6 != 0 && ip6 != 0)
1752 continue;
1753 if (req->no_ipv4 != 0 && ip6 == 0)
1754 continue;
1755 oclog(ws, LOG_DEBUG, "%s route %s", txt, routes[i]);
1756
1757 if (ip6 != 0 && ws->full_ipv6) {
1758 ret = cstp_printf(ws,
1759 "X-CSTP-Split-%s-IP6: %s\r\n",
1760 txt, routes[i]);
1761 } else {
1762 ret = cstp_printf(ws,
1763 "X-CSTP-Split-%s: %s\r\n",
1764 txt, routes[i]);
1765 }
1766 if (ret < 0)
1767 return ret;
1768 }
1769 return 0;
1770 }
1771
1772 /* Enforces a socket timeout. That is because, although we
1773 * use poll() to see whether a call to recv() would block,
1774 * there are certain cases in Linux where recv() blocks even
1775 * though poll() notified of data */
set_socket_timeout(worker_st * ws,int fd)1776 static void set_socket_timeout(worker_st * ws, int fd)
1777 {
1778 struct timeval tval;
1779 int ret;
1780
1781 tval.tv_sec = DEFAULT_SOCKET_TIMEOUT;
1782 tval.tv_usec = 0;
1783 ret =
1784 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tval,
1785 sizeof(tval));
1786 if (ret == -1) {
1787 int e = errno;
1788 oclog(ws, LOG_DEBUG,
1789 "setsockopt(%s, SO_RCVTIMEO) failed: %s", (fd==ws->conn_fd)?"ΤCP":"UDP", strerror(e));
1790 }
1791 }
1792
1793 /* wild but conservative guess; this ciphersuite has the largest overhead */
1794 #define MAX_CSTP_CRYPTO_OVERHEAD (CSTP_OVERHEAD+tls_get_overhead(GNUTLS_TLS1_0, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1))
1795 #define MAX_DTLS_CRYPTO_OVERHEAD (CSTP_DTLS_OVERHEAD+tls_get_overhead(GNUTLS_DTLS1_0, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1))
1796 #define MAX_DTLS_PROTO_OVERHEAD(ws) ((ws->proto == AF_INET)?(IP_HEADER_SIZE+UDP_HEADER_SIZE):(IPV6_HEADER_SIZE+UDP_HEADER_SIZE))
1797
1798 /* Calculate MTU for CSTP and DTLS channels.
1799 */
calc_mtu_values(worker_st * ws)1800 static void calc_mtu_values(worker_st * ws)
1801 {
1802 /* assume that if IPv6 is used over TCP then the same would be used over UDP */
1803 if (ws->proto == AF_INET) {
1804 ws->cstp_proto_overhead = IP_HEADER_SIZE;
1805 ws->dtls_proto_overhead = IP_HEADER_SIZE;
1806 } else {
1807 ws->cstp_proto_overhead = IPV6_HEADER_SIZE;
1808 ws->dtls_proto_overhead = IPV6_HEADER_SIZE;
1809 }
1810 ws->cstp_proto_overhead += TCP_HEADER_SIZE;
1811 ws->dtls_proto_overhead += UDP_HEADER_SIZE;
1812
1813 if (ws->session == NULL) {
1814 ws->cstp_crypto_overhead = MAX_CSTP_CRYPTO_OVERHEAD;
1815 } else {
1816 ws->cstp_crypto_overhead = CSTP_OVERHEAD +
1817 tls_get_overhead(gnutls_protocol_get_version(ws->session),
1818 gnutls_cipher_get(ws->session),
1819 gnutls_mac_get(ws->session));
1820 }
1821
1822 /* link MTU is the device MTU */
1823 ws->link_mtu = ws->vinfo.mtu;
1824
1825 if (DTLS_ACTIVE(ws)->udp_state != UP_DISABLED) {
1826 /* crypto overhead for DTLS */
1827 if (ws->req.use_psk) {
1828 if (ws->session == NULL) {
1829 ws->dtls_crypto_overhead = MAX_DTLS_CRYPTO_OVERHEAD;
1830 } else {
1831 ws->dtls_crypto_overhead = tls_get_overhead(
1832 GNUTLS_DTLS1_0,
1833 gnutls_cipher_get(ws->session),
1834 gnutls_mac_get(ws->session));
1835 }
1836 } else if (ws->req.selected_ciphersuite) {
1837 ws->dtls_crypto_overhead =
1838 tls_get_overhead(ws->req.
1839 selected_ciphersuite->gnutls_version,
1840 ws->req.
1841 selected_ciphersuite->gnutls_cipher,
1842 ws->req.selected_ciphersuite->gnutls_mac);
1843 }
1844 ws->dtls_crypto_overhead += CSTP_DTLS_OVERHEAD;
1845
1846 oclog(ws, LOG_DEBUG,
1847 "DTLS overhead is %u",
1848 ws->dtls_proto_overhead + ws->dtls_crypto_overhead);
1849 }
1850
1851 /* This is the data MTU we advertised to peer, we will never exceed this value */
1852 ws->adv_link_mtu = ws->link_mtu;
1853 }
1854
1855 /* connect_handler:
1856 * @ws: an initialized worker structure
1857 *
1858 * This function handles the HTTPS session after a CONNECT
1859 * command has been issued by the peer. The @ws->auth_state
1860 * should be set to %S_AUTH_COMPLETE or the client will be
1861 * disconnected.
1862 *
1863 * If the user is authenticate it handles the TCP and UDP VPN
1864 * tunnels.
1865 *
1866 */
connect_handler(worker_st * ws)1867 static int connect_handler(worker_st * ws)
1868 {
1869 struct http_req_st *req = &ws->req;
1870 int max, ret, t;
1871 char *p;
1872 unsigned rnd;
1873 unsigned i;
1874 unsigned ip6;
1875 time_t now = time(0);
1876
1877 ret = gnutls_rnd(GNUTLS_RND_NONCE, &rnd, sizeof(rnd));
1878 if (ret < 0) {
1879 oclog(ws, LOG_ERR,
1880 "error in the random generator: %s", gnutls_strerror(ret));
1881 cstp_puts(ws, "HTTP/1.1 503 Service Unavailable\r\n");
1882 cstp_puts(ws,
1883 "X-Reason: Server error\r\n\r\n");
1884 return -1;
1885 }
1886
1887 ws->buffer_size = sizeof(ws->buffer);
1888
1889 cookie_authenticate_or_exit(ws);
1890
1891 if (strcmp(req->url, "/CSCOSSLC/tunnel") != 0) {
1892 oclog(ws, LOG_INFO, "bad connect request: '%s'\n", req->url);
1893 response_404(ws, 1);
1894 cstp_fatal_close(ws, GNUTLS_A_ACCESS_DENIED);
1895 exit_worker(ws);
1896 }
1897
1898 if (WSCONFIG(ws)->network.name[0] == 0) {
1899 oclog(ws, LOG_ERR,
1900 "no networks are configured; rejecting client");
1901 cstp_puts(ws, "HTTP/1.1 503 Service Unavailable\r\n");
1902 cstp_puts(ws,
1903 "X-Reason: Server configuration error\r\n\r\n");
1904 return -1;
1905 }
1906
1907 ret = complete_vpn_info(ws, &ws->vinfo);
1908 if (ret < 0) {
1909 oclog(ws, LOG_ERR,
1910 "no networks are configured; rejecting client");
1911 cstp_puts(ws, "HTTP/1.1 503 Service Unavailable\r\n");
1912 cstp_puts(ws,
1913 "X-Reason: Server configuration error\r\n\r\n");
1914 return -1;
1915 }
1916
1917 /* override any hostname sent by the peer if we have one already configured */
1918 if (ws->user_config->hostname) {
1919 strlcpy(ws->req.hostname, ws->user_config->hostname, sizeof(ws->req.hostname));
1920 }
1921
1922 FUZZ(ws->user_config->interim_update_secs, 5, rnd);
1923 FUZZ(WSCONFIG(ws)->rekey_time, 30, rnd);
1924
1925 /* Connected. Turn of the alarm */
1926 if (WSCONFIG(ws)->auth_timeout)
1927 alarm(0);
1928 http_req_deinit(ws);
1929
1930 cstp_cork(ws);
1931 ret = cstp_puts(ws, "HTTP/1.1 200 CONNECTED\r\n");
1932 SEND_ERR(ret);
1933
1934 ret = add_owasp_headers(ws);
1935 SEND_ERR(ret);
1936
1937 ret = cstp_puts(ws, "X-CSTP-Version: 1\r\n");
1938 SEND_ERR(ret);
1939
1940 ret = cstp_puts(ws, "X-CSTP-Server-Name: "PACKAGE_STRING"\r\n");
1941 SEND_ERR(ret);
1942
1943 if (req->is_mobile) {
1944 ws->user_config->dpd = ws->user_config->mobile_dpd;
1945 WSCONFIG(ws)->idle_timeout = WSCONFIG(ws)->mobile_idle_timeout;
1946 }
1947
1948 /* Notify back the client about the accepted hostname */
1949 if (ws->req.hostname[0] != 0) {
1950 ret = cstp_printf(ws, "X-CSTP-Hostname: %s\r\n", ws->req.hostname);
1951 SEND_ERR(ret);
1952 }
1953
1954 oclog(ws, LOG_INFO, "suggesting DPD of %d secs", ws->user_config->dpd);
1955 if (ws->user_config->dpd > 0) {
1956 ret =
1957 cstp_printf(ws, "X-CSTP-DPD: %u\r\n",
1958 ws->user_config->dpd);
1959 SEND_ERR(ret);
1960 }
1961
1962 if (WSCONFIG(ws)->default_domain) {
1963 ret =
1964 cstp_printf(ws, "X-CSTP-Default-Domain: %s\r\n",
1965 WSCONFIG(ws)->default_domain);
1966 SEND_ERR(ret);
1967 }
1968
1969 ws->dtls_active_session = 0;
1970 DTLS_ACTIVE(ws)->udp_state = UP_DISABLED;
1971 DTLS_INACTIVE(ws)->udp_state = UP_DISABLED;
1972
1973 if (WSPCONFIG(ws)->udp_port != 0 && req->master_secret_set != 0) {
1974 memcpy(ws->master_secret, req->master_secret, TLS_MASTER_SIZE);
1975 DTLS_ACTIVE(ws)->udp_state = UP_WAIT_FD;
1976 DTLS_INACTIVE(ws)->udp_state = UP_WAIT_FD;
1977 } else {
1978 oclog(ws, LOG_DEBUG, "disabling UDP (DTLS) connection");
1979 }
1980
1981 if (ws->user_config->mtu > 0)
1982 ws->vinfo.mtu = ws->user_config->mtu;
1983 oclog(ws, LOG_INFO, "configured link MTU is %u", ws->vinfo.mtu);
1984
1985 if (req->link_mtu > 0) {
1986 oclog(ws, LOG_INFO, "peer's link MTU is %u", req->link_mtu);
1987 ws->vinfo.mtu = MIN(ws->vinfo.mtu, req->link_mtu);
1988 } else if (req->tunnel_mtu > 0) {
1989 /* Old clients didn't send their link MTU, they send the plaintext MTU
1990 * they can transfer. */
1991 ws->vinfo.mtu = MIN(ws->vinfo.mtu, req->tunnel_mtu + MAX_DTLS_PROTO_OVERHEAD(ws) + MAX_DTLS_CRYPTO_OVERHEAD);
1992 oclog(ws, LOG_INFO, "peer's data MTU is %u / link is %u", req->tunnel_mtu, ws->vinfo.mtu);
1993 }
1994
1995 /* Attempt to use the TCP connection maximum segment size to set a more
1996 * precise MTU. */
1997 if (ws->conn_type != SOCK_TYPE_UNIX) {
1998 max = get_pmtu_approx(ws);
1999 if (max > 0 && max < ws->vinfo.mtu) {
2000 oclog(ws, LOG_DEBUG, "reducing MTU due to TCP/PMTU to %u",
2001 max);
2002 link_mtu_set(ws, DTLS_ACTIVE(ws), max);
2003 }
2004 }
2005
2006 calc_mtu_values(ws);
2007
2008 if (DATA_MTU(ws, ws->link_mtu) < 1280 && ws->vinfo.ipv6 && req->no_ipv6 == 0) {
2009 oclog(ws, LOG_INFO, "Connection MTU (link: %u, data: %u) is not sufficient for IPv6 (1280)", ws->link_mtu, DATA_MTU(ws, ws->link_mtu));
2010 req->no_ipv6 = 1;
2011 }
2012
2013 /* Send IP addresses */
2014 if (ws->vinfo.ipv4 && req->no_ipv4 == 0) {
2015 oclog(ws, LOG_INFO, "sending IPv4 %s", ws->vinfo.ipv4);
2016 ret =
2017 cstp_printf(ws, "X-CSTP-Address: %s\r\n",
2018 ws->vinfo.ipv4);
2019 SEND_ERR(ret);
2020
2021 if (ws->user_config->ipv4_netmask) {
2022 ret =
2023 cstp_printf(ws, "X-CSTP-Netmask: %s\r\n",
2024 ws->user_config->ipv4_netmask);
2025 SEND_ERR(ret);
2026 }
2027 }
2028
2029 if (ws->vinfo.ipv6 && req->no_ipv6 == 0 && ws->user_config->ipv6_prefix != 0) {
2030 oclog(ws, LOG_INFO, "sending IPv6 %s/%u", ws->vinfo.ipv6, ws->user_config->ipv6_subnet_prefix);
2031 if (ws->full_ipv6 && ws->user_config->ipv6_subnet_prefix) {
2032 ret =
2033 cstp_printf(ws,
2034 "X-CSTP-Address-IP6: %s/%u\r\n",
2035 ws->vinfo.ipv6, ws->user_config->ipv6_subnet_prefix);
2036 SEND_ERR(ret);
2037 } else {
2038 const char *net;
2039
2040 ret =
2041 cstp_printf(ws, "X-CSTP-Address: %s\r\n",
2042 ws->vinfo.ipv6);
2043 SEND_ERR(ret);
2044
2045 net = ws->user_config->ipv6_net;
2046 if (net == NULL)
2047 net = ws->vinfo.ipv6;
2048
2049 ret =
2050 cstp_printf(ws, "X-CSTP-Netmask: %s/%u\r\n",
2051 net, ws->user_config->ipv6_subnet_prefix);
2052 SEND_ERR(ret);
2053 }
2054 }
2055
2056 /* While anyconnect clients can handle the assignment
2057 * of an IPv6 address, they cannot handle routes or DNS
2058 * in IPv6. So we disable IPv6 after an IP is assigned. */
2059 if (ws->full_ipv6 == 0) {
2060 req->no_ipv6 = 1;
2061 oclog(ws, LOG_INFO, "IPv6 routes/DNS disabled because IPv6 support was not requested.");
2062 } else if (req->user_agent_type != AGENT_OPENCONNECT && req->user_agent_type != AGENT_ANYCONNECT) {
2063 req->no_ipv6 = 1;
2064 oclog(ws, LOG_INFO, "IPv6 routes/DNS disabled because the agent is not known.");
2065 }
2066
2067 for (i = 0; i < ws->user_config->n_dns; i++) {
2068 if (strchr(ws->user_config->dns[i], ':') != 0)
2069 ip6 = 1;
2070 else
2071 ip6 = 0;
2072
2073 if (req->no_ipv6 != 0 && ip6 != 0)
2074 continue;
2075 if (req->no_ipv4 != 0 && ip6 == 0)
2076 continue;
2077
2078 oclog(ws, LOG_INFO, "adding DNS %s", ws->user_config->dns[i]);
2079 if (req->user_agent_type == AGENT_ANYCONNECT) {
2080 ret =
2081 cstp_printf(ws, "X-CSTP-%s: %s\r\n",
2082 ip6 ? "DNS-IP6" : "DNS",
2083 ws->user_config->dns[i]);
2084 } else { /* openconnect does not require the split
2085 * of DNS and DNS-IP6 and only recent versions
2086 * understand the IP6 variant. */
2087 ret =
2088 cstp_printf(ws, "X-CSTP-DNS: %s\r\n",
2089 ws->user_config->dns[i]);
2090 }
2091 SEND_ERR(ret);
2092 }
2093
2094 for (i = 0; i < ws->user_config->n_nbns; i++) {
2095 if (strchr(ws->user_config->nbns[i], ':') != 0)
2096 ip6 = 1;
2097 else
2098 ip6 = 0;
2099
2100 if (req->no_ipv6 != 0 && ip6 != 0)
2101 continue;
2102 if (req->no_ipv4 != 0 && ip6 == 0)
2103 continue;
2104
2105 oclog(ws, LOG_INFO, "adding NBNS %s", ws->user_config->nbns[i]);
2106 ret =
2107 cstp_printf(ws, "X-CSTP-NBNS: %s\r\n",
2108 ws->user_config->nbns[i]);
2109 SEND_ERR(ret);
2110 }
2111
2112 for (i = 0; i < ws->user_config->n_split_dns; i++) {
2113 if (strchr(ws->user_config->split_dns[i], ':') != 0)
2114 ip6 = 1;
2115 else
2116 ip6 = 0;
2117
2118 if (req->no_ipv6 != 0 && ip6 != 0)
2119 continue;
2120 if (req->no_ipv4 != 0 && ip6 == 0)
2121 continue;
2122
2123 oclog(ws, LOG_INFO, "adding split DNS %s",
2124 ws->user_config->split_dns[i]);
2125 ret =
2126 cstp_printf(ws, "X-CSTP-Split-DNS: %s\r\n",
2127 ws->user_config->split_dns[i]);
2128 SEND_ERR(ret);
2129 }
2130
2131 /* Anyconnect on IOS requires this route in order to use IPv6 */
2132 if (ws->full_ipv6 && req->is_ios &&
2133 (ws->user_config->n_routes == 0 || ws->default_route == 0)) {
2134 oclog(ws, LOG_INFO, "adding special split DNS for Apple");
2135 ret =
2136 cstp_printf(ws, "X-CSTP-Split-Include-IP6: 2000::/3\r\n");
2137 SEND_ERR(ret);
2138 }
2139
2140 if (ws->default_route == 0) {
2141 ret = send_routes(ws, req, ws->user_config->routes, ws->user_config->n_routes, 1);
2142 SEND_ERR(ret);
2143
2144 } else {
2145 /* default route */
2146 WSCONFIG(ws)->tunnel_all_dns = 1;
2147 }
2148
2149 if (WSCONFIG(ws)->tunnel_all_dns) {
2150 ret = cstp_puts(ws, "X-CSTP-Tunnel-All-DNS: true\r\n");
2151 } else {
2152 ret = cstp_puts(ws, "X-CSTP-Tunnel-All-DNS: false\r\n");
2153 }
2154 SEND_ERR(ret);
2155
2156 if (WSCONFIG(ws)->client_bypass_protocol) {
2157 ret = cstp_puts(ws, "X-CSTP-Client-Bypass-Protocol: true\r\n");
2158 } else {
2159 ret = cstp_puts(ws, "X-CSTP-Client-Bypass-Protocol: false\r\n");
2160 }
2161 SEND_ERR(ret);
2162
2163 ret = send_routes(ws, req, ws->user_config->no_routes, ws->user_config->n_no_routes, 0);
2164 SEND_ERR(ret);
2165
2166 ret =
2167 cstp_printf(ws, "X-CSTP-Keepalive: %u\r\n",
2168 ws->user_config->keepalive);
2169 SEND_ERR(ret);
2170
2171 if (WSCONFIG(ws)->idle_timeout > 0) {
2172 ret =
2173 cstp_printf(ws,
2174 "X-CSTP-Idle-Timeout: %u\r\n",
2175 (unsigned)WSCONFIG(ws)->idle_timeout);
2176 } else {
2177 ret = cstp_puts(ws, "X-CSTP-Idle-Timeout: none\r\n");
2178 }
2179 SEND_ERR(ret);
2180
2181 ret =
2182 cstp_puts(ws,
2183 "X-CSTP-Smartcard-Removal-Disconnect: true\r\n");
2184 SEND_ERR(ret);
2185
2186 if (WSCONFIG(ws)->is_dyndns != 0) {
2187 ret =
2188 cstp_puts(ws,
2189 "X-CSTP-DynDNS: true\r\n");
2190 SEND_ERR(ret);
2191 }
2192
2193 if (WSCONFIG(ws)->rekey_time > 0) {
2194 unsigned method;
2195
2196 ret =
2197 cstp_printf(ws, "X-CSTP-Rekey-Time: %u\r\n",
2198 (unsigned)(WSCONFIG(ws)->rekey_time));
2199 SEND_ERR(ret);
2200
2201 /* if the peer isn't patched for safe renegotiation, always
2202 * require him to open a new tunnel. */
2203 if (ws->session != NULL && gnutls_safe_renegotiation_status(ws->session) != 0)
2204 method = WSCONFIG(ws)->rekey_method;
2205 else
2206 method = REKEY_METHOD_NEW_TUNNEL;
2207
2208 ret = cstp_printf(ws, "X-CSTP-Rekey-Method: %s\r\n",
2209 (method ==
2210 REKEY_METHOD_SSL) ? "ssl" : "new-tunnel");
2211 SEND_ERR(ret);
2212 } else {
2213 ret = cstp_puts(ws, "X-CSTP-Rekey-Method: none\r\n");
2214 SEND_ERR(ret);
2215 }
2216
2217 if (WSCONFIG(ws)->proxy_url != NULL) {
2218 char *url = replace_vals(ws, WSCONFIG(ws)->proxy_url);
2219 if (url != NULL) {
2220 ret =
2221 cstp_printf(ws, "X-CSTP-MSIE-Proxy-Pac-URL: %s\r\n",
2222 url);
2223 SEND_ERR(ret);
2224 talloc_free(url);
2225 }
2226 }
2227
2228 if (!ws->user_config->has_session_timeout_secs) {
2229 ret = cstp_puts(ws, "X-CSTP-Session-Timeout: none\r\n");
2230 SEND_ERR(ret);
2231 } else {
2232 time_t expiration = ws->session_start_time + ws->user_config->session_timeout_secs;
2233 ret = cstp_printf(ws, "X-CSTP-Session-Timeout: %u\r\n"
2234 "X-CSTP-Session-Timeout-Remaining: %ld\r\n",
2235 ws->user_config->session_timeout_secs,
2236 MAX(expiration - now, 0));
2237 SEND_ERR(ret);
2238 }
2239
2240 ret = cstp_puts(ws, "X-CSTP-Disconnected-Timeout: none\r\n"
2241 "X-CSTP-Keep: true\r\n"
2242 "X-CSTP-TCP-Keepalive: true\r\n"
2243 "X-CSTP-License: accept\r\n");
2244 SEND_ERR(ret);
2245
2246 for (i = 0; i < WSCONFIG(ws)->custom_header_size; i++) {
2247 char *h = replace_vals(ws, WSCONFIG(ws)->custom_header[i]);
2248
2249 if (h) {
2250 oclog(ws, LOG_INFO, "adding custom header '%s'", h);
2251 ret =
2252 cstp_printf(ws, "%s\r\n", h);
2253 SEND_ERR(ret);
2254 talloc_free(h);
2255 }
2256 }
2257
2258
2259 /* set TCP socket options */
2260 if (WSCONFIG(ws)->output_buffer > 0) {
2261 t = ws->link_mtu;
2262 t *= WSCONFIG(ws)->output_buffer;
2263
2264 ret =
2265 setsockopt(ws->conn_fd, SOL_SOCKET, SO_SNDBUF, &t,
2266 sizeof(t));
2267 if (ret == -1)
2268 oclog(ws, LOG_DEBUG,
2269 "setsockopt(TCP, SO_SNDBUF) to %u, failed.", t);
2270 }
2271
2272 set_socket_timeout(ws, ws->conn_fd);
2273 set_non_block(ws->conn_fd);
2274 set_net_priority(ws, ws->conn_fd, ws->user_config->net_priority);
2275 set_no_delay(ws, ws->conn_fd);
2276
2277 if (DTLS_ACTIVE(ws)->udp_state != UP_DISABLED) {
2278
2279 if (ws->user_config->dpd > 0) {
2280 ret =
2281 cstp_printf(ws, "X-DTLS-DPD: %u\r\n",
2282 ws->user_config->dpd);
2283 SEND_ERR(ret);
2284 }
2285
2286 ret =
2287 cstp_printf(ws, "X-DTLS-Port: %u\r\n",
2288 WSPCONFIG(ws)->udp_port);
2289 SEND_ERR(ret);
2290
2291 if (WSCONFIG(ws)->rekey_time > 0) {
2292 ret =
2293 cstp_printf(ws, "X-DTLS-Rekey-Time: %u\r\n",
2294 (unsigned)(WSCONFIG(ws)->rekey_time + 10));
2295 SEND_ERR(ret);
2296
2297 /* This is our private extension */
2298 if (WSCONFIG(ws)->rekey_method == REKEY_METHOD_SSL) {
2299 ret =
2300 cstp_puts(ws,
2301 "X-DTLS-Rekey-Method: ssl\r\n");
2302 SEND_ERR(ret);
2303 }
2304 }
2305
2306 ret =
2307 cstp_printf(ws, "X-DTLS-Keepalive: %u\r\n",
2308 ws->user_config->keepalive);
2309 SEND_ERR(ret);
2310
2311 p = (char *)ws->buffer;
2312 for (i = 0; i < sizeof(ws->session_id); i++) {
2313 sprintf(p, "%.2x", (unsigned int)ws->session_id[i]);
2314 p += 2;
2315 }
2316
2317 if (ws->req.use_psk || !WSCONFIG(ws)->dtls_legacy) {
2318 oclog(ws, LOG_INFO, "X-DTLS-App-ID: %s", ws->buffer);
2319
2320 ret =
2321 cstp_printf(ws, "X-DTLS-App-ID: %s\r\n",
2322 ws->buffer);
2323 SEND_ERR(ret);
2324
2325 oclog(ws, LOG_INFO, "DTLS ciphersuite: "DTLS_PROTO_INDICATOR);
2326 ret =
2327 cstp_printf(ws, "X-DTLS-CipherSuite: "DTLS_PROTO_INDICATOR"\r\n");
2328 } else if (ws->req.selected_ciphersuite) {
2329 oclog(ws, LOG_INFO, "X-DTLS-Session-ID: %s", ws->buffer);
2330
2331 ret =
2332 cstp_printf(ws, "X-DTLS-Session-ID: %s\r\n",
2333 ws->buffer);
2334 SEND_ERR(ret);
2335
2336 oclog(ws, LOG_INFO, "DTLS ciphersuite: %s",
2337 ws->req.selected_ciphersuite->oc_name);
2338 ret =
2339 cstp_printf(ws, "X-DTLS%s-CipherSuite: %s\r\n",
2340 (ws->req.selected_ciphersuite->dtls12_mode!=0)?"12":"",
2341 ws->req.selected_ciphersuite->oc_name);
2342 SEND_ERR(ret);
2343
2344 /* only send the X-DTLS-MTU in the legacy protocol, as there
2345 * the DTLS ciphersuite/version is negotiated and we cannot predict
2346 * the actual tunnel size */
2347 ret =
2348 cstp_printf(ws, "X-DTLS-MTU: %u\r\n", DATA_MTU(ws, ws->link_mtu));
2349 SEND_ERR(ret);
2350 oclog(ws, LOG_INFO, "DTLS data MTU %u", DATA_MTU(ws, ws->link_mtu));
2351 }
2352 SEND_ERR(ret);
2353
2354 }
2355
2356 /* hack for openconnect. It uses only a single MTU value */
2357 ret = cstp_printf(ws, "X-CSTP-Base-MTU: %u\r\n", ws->link_mtu);
2358 SEND_ERR(ret);
2359 oclog(ws, LOG_INFO, "Link MTU is %u bytes", ws->link_mtu);
2360
2361 ret = cstp_printf(ws, "X-CSTP-MTU: %u\r\n", DATA_MTU(ws, ws->link_mtu));
2362 SEND_ERR(ret);
2363
2364 if (ws->buffer_size < ws->link_mtu+16) {
2365 oclog(ws, LOG_ERR,
2366 "buffer size is smaller than MTU (%u < %u)",
2367 ws->buffer_size, ws->link_mtu);
2368 goto exit;
2369 }
2370
2371 data_mtu_send(ws, DATA_MTU(ws, ws->link_mtu));
2372
2373 if (WSCONFIG(ws)->banner) {
2374 ret =
2375 cstp_printf(ws, "X-CSTP-Banner: %s\r\n",
2376 WSCONFIG(ws)->banner);
2377 SEND_ERR(ret);
2378 }
2379
2380 /* send any compression methods */
2381 if (ws->dtls_selected_comp) {
2382 oclog(ws, LOG_INFO, "selected DTLS compression method %s\n", ws->dtls_selected_comp->name);
2383 ret =
2384 cstp_printf(ws, "X-DTLS-Content-Encoding: %s\r\n",
2385 ws->dtls_selected_comp->name);
2386 SEND_ERR(ret);
2387 }
2388
2389 if (ws->cstp_selected_comp) {
2390 oclog(ws, LOG_INFO, "selected CSTP compression method %s\n", ws->cstp_selected_comp->name);
2391 ret =
2392 cstp_printf(ws, "X-CSTP-Content-Encoding: %s\r\n",
2393 ws->cstp_selected_comp->name);
2394 SEND_ERR(ret);
2395 }
2396
2397 ret = cstp_puts(ws, "\r\n");
2398 SEND_ERR(ret);
2399
2400 ret = cstp_uncork(ws);
2401 SEND_ERR(ret);
2402
2403 ret = worker_event_loop(ws);
2404 if (ret != 0)
2405 {
2406 goto exit;
2407 }
2408
2409 return 0;
2410
2411 exit:
2412 cstp_close(ws);
2413 /*gnutls_deinit(ws->session); */
2414 if (DTLS_ACTIVE(ws)->udp_state == UP_ACTIVE && DTLS_ACTIVE(ws)->dtls_session) {
2415 dtls_close(DTLS_ACTIVE(ws));
2416 }
2417 if (DTLS_INACTIVE(ws)->udp_state == UP_ACTIVE && DTLS_INACTIVE(ws)->dtls_session) {
2418 dtls_close(DTLS_INACTIVE(ws));
2419 }
2420
2421 exit_worker_reason(ws, terminate_reason);
2422
2423 send_error:
2424 oclog(ws, LOG_DEBUG, "error sending data\n");
2425 exit_worker(ws);
2426
2427 return -1;
2428 }
2429
parse_data(struct worker_st * ws,uint8_t * buf,size_t buf_size,time_t now,unsigned is_dtls)2430 static int parse_data(struct worker_st *ws, uint8_t *buf, size_t buf_size,
2431 time_t now, unsigned is_dtls)
2432 {
2433 int ret, e;
2434 uint8_t *plain;
2435 ssize_t plain_size;
2436 unsigned head;
2437
2438 if (is_dtls == 0) { /* CSTP */
2439 plain = buf + 8;
2440 plain_size = buf_size - 8;
2441 head = buf[6];
2442 } else {
2443 plain = buf + 1;
2444 plain_size = buf_size - 1;
2445 head = buf[0];
2446 }
2447
2448 switch (head) {
2449 case AC_PKT_DPD_RESP:
2450 oclog(ws, LOG_TRANSFER_DEBUG, "received DPD response");
2451 break;
2452 case AC_PKT_KEEPALIVE:
2453 oclog(ws, LOG_TRANSFER_DEBUG, "received keepalive");
2454 break;
2455 case AC_PKT_DPD_OUT:
2456 if (is_dtls == 0) {
2457 buf[6] = AC_PKT_DPD_RESP;
2458 ret = cstp_send(ws, buf, buf_size);
2459
2460 oclog(ws, LOG_TRANSFER_DEBUG,
2461 "received TLS DPD; sent response (%d bytes)",
2462 ret);
2463
2464 if (ret < 0) {
2465 oclog(ws, LOG_ERR, "could not send data: %d", ret);
2466 return -1;
2467 }
2468 } else {
2469 /* Use DPD for MTU discovery in DTLS */
2470 buf[0] = AC_PKT_DPD_RESP;
2471
2472 if (buf_size-CSTP_DTLS_OVERHEAD > DATA_MTU(ws, ws->link_mtu)) {
2473 /* peer is doing MTU discovery */
2474 data_mtu_set(ws, DTLS_ACTIVE(ws), buf_size-CSTP_DTLS_OVERHEAD);
2475 }
2476
2477 ret = dtls_send(DTLS_ACTIVE(ws), buf, buf_size);
2478 if (ret == GNUTLS_E_LARGE_PACKET) {
2479 oclog(ws, LOG_TRANSFER_DEBUG,
2480 "could not send DPD of %d bytes", (int)buf_size);
2481 mtu_not_ok(ws, DTLS_ACTIVE(ws));
2482 ret = dtls_send(DTLS_ACTIVE(ws), buf, 1);
2483 }
2484
2485 oclog(ws, LOG_TRANSFER_DEBUG,
2486 "received DTLS DPD; sent response (%d bytes)",
2487 ret);
2488
2489 if (ret < 0) {
2490 oclog(ws, LOG_ERR, "could not send TLS data: %s",
2491 gnutls_strerror(ret));
2492 return -1;
2493 }
2494 }
2495
2496 break;
2497 case AC_PKT_DISCONN:
2498 oclog(ws, LOG_INFO, "received BYE packet; exiting");
2499 /* In openconnect the BYE packet indicates an explicit
2500 * user disconnect. In anyconnect clients it may indicate
2501 * an intention to reconnect (e.g., because network was
2502 * changed). We separate the error codes to ensure we do
2503 * do not interpret the intention incorrectly (see #281). */
2504 if (plain_size > 0 && plain[0] == 0xb0) {
2505 exit_worker_reason(ws, REASON_USER_DISCONNECT);
2506 } else {
2507 if (plain_size > 0) {
2508 oclog_hex(ws, LOG_DEBUG, "bye packet with unknown payload", plain, plain_size, 0);
2509 return -1;
2510 }
2511
2512 exit_worker_reason(ws, REASON_TEMP_DISCONNECT);
2513 }
2514 break;
2515 case AC_PKT_COMPRESSED:
2516 /* decompress */
2517 if (is_dtls == 0) { /* CSTP */
2518 if (ws->cstp_selected_comp == NULL) {
2519 oclog(ws, LOG_ERR, "received compression data but no compression was negotiated");
2520 return -1;
2521 }
2522
2523 plain_size = ws->cstp_selected_comp->decompress(ws->decomp, sizeof(ws->decomp), plain, plain_size);
2524 oclog(ws, LOG_DEBUG, "decompressed %d to %d\n", (int)buf_size-8, (int)plain_size);
2525 } else { /* DTLS */
2526 if (ws->dtls_selected_comp == NULL) {
2527 oclog(ws, LOG_ERR, "received compression data but no compression was negotiated");
2528 return -1;
2529 }
2530
2531 plain_size = ws->dtls_selected_comp->decompress(ws->decomp, sizeof(ws->decomp), plain, plain_size);
2532 oclog(ws, LOG_DEBUG, "decompressed %d to %d\n", (int)buf_size-1, (int)plain_size);
2533 }
2534
2535 if (plain_size <= 0) {
2536 oclog(ws, LOG_ERR, "decompression error %d", (int)plain_size);
2537 return -1;
2538 }
2539 plain = ws->decomp;
2540 /* fall through */
2541 case AC_PKT_DATA:
2542 oclog(ws, LOG_TRANSFER_DEBUG, "writing %d byte(s) to TUN",
2543 (int)plain_size);
2544 ret = tun_write(ws->tun_fd, plain, plain_size);
2545 if (ret == -1) {
2546 e = errno;
2547 oclog(ws, LOG_ERR, "could not write data to tun: %s",
2548 strerror(e));
2549 return -1;
2550 }
2551 ws->tun_bytes_in += plain_size;
2552 ws->last_nc_msg = now;
2553
2554 break;
2555 default:
2556 oclog(ws, LOG_DEBUG, "received unknown packet %u/size: %u",
2557 (unsigned)head, (unsigned)buf_size);
2558 }
2559
2560 return 0;
2561 }
2562
parse_cstp_data(struct worker_st * ws,uint8_t * buf,size_t buf_size,time_t now)2563 static int parse_cstp_data(struct worker_st *ws,
2564 uint8_t * buf, size_t buf_size, time_t now)
2565 {
2566 int pktlen, ret;
2567
2568 if (buf_size < 8) {
2569 oclog(ws, LOG_INFO,
2570 "can't read CSTP header (only %d bytes are available)",
2571 (int)buf_size);
2572 return -1;
2573 }
2574
2575 if (buf[0] != 'S' || buf[1] != 'T' ||
2576 buf[2] != 'F' || buf[3] != 1 || buf[7]) {
2577 oclog(ws, LOG_INFO, "can't recognise CSTP header");
2578 return -1;
2579 }
2580
2581 pktlen = (buf[4] << 8) + buf[5];
2582 if (buf_size != 8 + pktlen) {
2583 oclog(ws, LOG_INFO, "unexpected CSTP length (have %u, should be %d)",
2584 (unsigned)pktlen, (unsigned)buf_size-8);
2585 return -1;
2586 }
2587
2588 if (buf[6] == AC_PKT_DATA && DTLS_ACTIVE(ws)->udp_state == UP_ACTIVE) {
2589 /* if we received a data packet in the CSTP channel we assume that
2590 * our peer wants to switch to it as the communication channel */
2591 DTLS_ACTIVE(ws)->udp_state = UP_INACTIVE;
2592 }
2593
2594 ret = parse_data(ws, buf, buf_size, now, 0);
2595 /* whatever we received treat it as DPD response.
2596 * it indicates that the channel is alive */
2597 ws->last_msg_tcp = now;
2598
2599 return ret;
2600 }
2601
parse_dtls_data(struct worker_st * ws,uint8_t * buf,size_t buf_size,time_t now)2602 static int parse_dtls_data(struct worker_st *ws,
2603 uint8_t * buf, size_t buf_size, time_t now)
2604 {
2605 int ret;
2606
2607 if (buf_size < 1) {
2608 oclog(ws, LOG_INFO,
2609 "can't read DTLS header (only %d bytes are available)",
2610 (int)buf_size);
2611 return -1;
2612 }
2613
2614 ret =
2615 parse_data(ws, buf, buf_size, now, 1);
2616 ws->last_msg_udp = now;
2617 return ret;
2618 }
2619
test_for_tcp_health_probe(struct worker_st * ws)2620 static int test_for_tcp_health_probe(struct worker_st *ws)
2621 {
2622 int ret;
2623 uint8_t buffer[1];
2624 ret = recv(ws->conn_fd, buffer, sizeof(buffer), MSG_PEEK);
2625
2626 // If we get back an error, assume this was a tcp health probe
2627 if (ret > 0)
2628 return 0;
2629 else
2630 return 1;
2631 }
2632
syserr_cb(const char * msg)2633 static void syserr_cb (const char *msg)
2634 {
2635 struct worker_st * ws = ev_userdata(worker_loop);
2636 int err = errno;
2637
2638 oclog(ws, LOG_ERR, "libev fatal error: %s / %s", msg, strerror(err));
2639
2640 terminate_reason = REASON_ERROR;
2641 exit_worker_reason(ws, terminate_reason);
2642 }
2643
cstp_send_terminate(struct worker_st * ws)2644 static void cstp_send_terminate(struct worker_st * ws)
2645 {
2646 ws->buffer[0] = 'S';
2647 ws->buffer[1] = 'T';
2648 ws->buffer[2] = 'F';
2649 ws->buffer[3] = 1;
2650 ws->buffer[4] = 0;
2651 ws->buffer[5] = 0;
2652 ws->buffer[6] = AC_PKT_DISCONN;
2653 ws->buffer[7] = 0;
2654
2655 oclog(ws, LOG_TRANSFER_DEBUG,
2656 "sending disconnect message in TLS channel");
2657 cstp_send(ws, ws->buffer, 8);
2658 exit_worker_reason(ws, terminate_reason);
2659 }
2660
command_watcher_cb(EV_P_ ev_io * w,int revents)2661 static void command_watcher_cb (EV_P_ ev_io *w, int revents)
2662 {
2663 struct worker_st *ws = ev_userdata(worker_loop);
2664
2665 int ret = handle_commands_from_main(ws);
2666 if (ret == ERR_NO_CMD_FD) {
2667 terminate_reason = REASON_ERROR;
2668 cstp_send_terminate(ws);
2669 }
2670
2671 if (ret < 0) {
2672 terminate_reason = REASON_ERROR;
2673 cstp_send_terminate(ws);
2674 }
2675
2676 if (DTLS_ACTIVE(ws)->udp_state == UP_SETUP) {
2677 ev_invoke(loop, &DTLS_ACTIVE(ws)->io, EV_READ);
2678 }
2679 if (DTLS_INACTIVE(ws)->udp_state == UP_SETUP) {
2680 ev_invoke(loop, &DTLS_INACTIVE(ws)->io, EV_READ);
2681 }
2682 }
2683
tls_watcher_cb(EV_P_ ev_io * w,int revents)2684 static void tls_watcher_cb (EV_P_ ev_io * w, int revents)
2685 {
2686 struct timespec tnow;
2687 struct worker_st *ws = ev_userdata(loop);
2688 int ret;
2689 gettime(&tnow);
2690
2691 ret = tls_mainloop(ws, &tnow);
2692 if (ret < 0) {
2693 oclog(ws, LOG_DEBUG, "tls_mainloop failed %d", ret);
2694 terminate_reason = REASON_ERROR;
2695 cstp_send_terminate(ws);
2696 }
2697 }
2698
tun_watcher_cb(EV_P_ ev_io * w,int revents)2699 static void tun_watcher_cb (EV_P_ ev_io * w, int revents)
2700 {
2701 struct timespec tnow;
2702 struct worker_st *ws = ev_userdata(loop);
2703 int ret;
2704 gettime(&tnow);
2705
2706 ret = tun_mainloop(ws, &tnow);
2707 if (ret < 0) {
2708 oclog(ws, LOG_DEBUG, "tun_mainloop failed %d", ret);
2709 terminate_reason = REASON_ERROR;
2710 cstp_send_terminate(ws);
2711 }
2712 }
2713
dtls_watcher_cb(EV_P_ ev_io * w,int revents)2714 static void dtls_watcher_cb (EV_P_ ev_io * w, int revents)
2715 {
2716 struct timespec tnow;
2717 struct worker_st *ws = ev_userdata(loop);
2718 struct dtls_st * dtls = (struct dtls_st*)w;
2719 int ret;
2720 gettime(&tnow);
2721
2722 ret = dtls_mainloop(ws, dtls, &tnow);
2723 if (ret < 0) {
2724 oclog(ws, LOG_DEBUG, "dtls_mainloop failed %d", ret);
2725 terminate_reason = REASON_ERROR;
2726 cstp_send_terminate(ws);
2727 }
2728
2729 #if defined(CAPTURE_LATENCY_SUPPORT)
2730 if (dtls->dtls_tptr.rx_time.tv_sec != 0) {
2731 capture_latency_sample(ws, &dtls->dtls_tptr.rx_time);
2732 dtls->dtls_tptr.rx_time.tv_sec = 0;
2733 dtls->dtls_tptr.rx_time.tv_nsec = 0;
2734 }
2735 #endif
2736 }
2737
term_sig_watcher_cb(struct ev_loop * loop,ev_signal * w,int revents)2738 static void term_sig_watcher_cb(struct ev_loop *loop, ev_signal *w, int revents)
2739 {
2740 struct worker_st *ws = ev_userdata(loop);
2741 cstp_send_terminate(ws);
2742 }
2743
invoke_dtls_if_needed(struct dtls_st * dtls)2744 static void invoke_dtls_if_needed(struct dtls_st * dtls)
2745 {
2746 if ((dtls->udp_state > UP_WAIT_FD) &&
2747 (dtls->dtls_session != NULL) &&
2748 (gnutls_record_check_pending(dtls->dtls_session))) {
2749 ev_invoke(worker_loop, &dtls->io, EV_READ);
2750 }
2751 }
2752
periodic_check_watcher_cb(EV_P_ ev_timer * w,int revents)2753 static void periodic_check_watcher_cb(EV_P_ ev_timer *w, int revents)
2754 {
2755 struct worker_st *ws = ev_userdata(loop);
2756 struct timespec tnow;
2757
2758 gettime(&tnow);
2759
2760 if (periodic_check(ws, &tnow, ws->user_config->dpd) < 0) {
2761 terminate_reason = REASON_ERROR;
2762 cstp_send_terminate(ws);
2763 return;
2764 }
2765
2766 if (terminate)
2767 cstp_send_terminate(ws);
2768
2769 if (gnutls_record_check_pending(ws->session))
2770 {
2771 ev_invoke(loop, &tls_watcher, EV_READ);
2772 }
2773
2774 invoke_dtls_if_needed(DTLS_ACTIVE(ws));
2775 invoke_dtls_if_needed(DTLS_INACTIVE(ws));
2776 }
2777
worker_event_loop(struct worker_st * ws)2778 static int worker_event_loop(struct worker_st * ws)
2779 {
2780 struct timespec tnow;
2781
2782 #if defined(__linux__) && defined(HAVE_LIBSECCOMP)
2783 worker_loop = ev_default_loop(EVFLAG_NOENV|EVBACKEND_EPOLL);
2784 #else
2785 worker_loop = EV_DEFAULT;
2786 #endif
2787
2788 // Restore the signal handlers
2789 ocsignal(SIGTERM, SIG_DFL);
2790 ocsignal(SIGINT, SIG_DFL);
2791 ocsignal(SIGALRM, SIG_DFL);
2792
2793 ev_init(&alarm_sig_watcher, term_sig_watcher_cb);
2794 ev_signal_set (&alarm_sig_watcher, SIGALRM);
2795 ev_signal_start (worker_loop, &alarm_sig_watcher);
2796
2797 ev_init (&int_sig_watcher, term_sig_watcher_cb);
2798 ev_signal_set (&int_sig_watcher, SIGINT);
2799 ev_signal_start (worker_loop, &int_sig_watcher);
2800
2801 ev_init (&term_sig_watcher, term_sig_watcher_cb);
2802 ev_signal_set (&term_sig_watcher, SIGTERM);
2803 ev_signal_start (worker_loop, &term_sig_watcher);
2804
2805 ev_set_userdata (worker_loop, ws);
2806 ev_set_syserr_cb(syserr_cb);
2807
2808 ev_init(&command_watcher, command_watcher_cb);
2809 ev_io_set(&command_watcher, ws->cmd_fd, EV_READ);
2810 ev_io_start(worker_loop, &command_watcher);
2811
2812 ev_init(&tls_watcher, tls_watcher_cb);
2813 ev_io_set(&tls_watcher, ws->conn_fd, EV_READ);
2814 ev_io_start(worker_loop, &tls_watcher);
2815
2816 ev_init(&DTLS_ACTIVE(ws)->io, dtls_watcher_cb);
2817 ev_init(&DTLS_INACTIVE(ws)->io, dtls_watcher_cb);
2818
2819 ev_init(&tun_watcher, tun_watcher_cb);
2820 ev_io_set(&tun_watcher, ws->tun_fd, EV_READ);
2821 ev_io_start(worker_loop, &tun_watcher);
2822
2823 ev_init (&period_check_watcher, periodic_check_watcher_cb);
2824 ev_timer_set(&period_check_watcher, WORKER_MAINTENANCE_TIME, WORKER_MAINTENANCE_TIME);
2825 ev_timer_start(worker_loop, &period_check_watcher);
2826
2827
2828 /* start dead peer detection */
2829 gettime(&tnow);
2830 ws->last_msg_tcp = ws->last_msg_udp = ws->last_nc_msg = tnow.tv_sec;
2831
2832 bandwidth_init(&ws->b_rx, ws->user_config->rx_per_sec);
2833 bandwidth_init(&ws->b_tx, ws->user_config->tx_per_sec);
2834
2835
2836 ev_run(worker_loop, 0);
2837 if (terminate != 0)
2838 {
2839 goto exit;
2840 }
2841 return 0;
2842
2843 exit:
2844 cstp_close(ws);
2845 /*gnutls_deinit(ws->session); */
2846 if (DTLS_ACTIVE(ws)->udp_state == UP_ACTIVE && DTLS_ACTIVE(ws)->dtls_session) {
2847 dtls_close(DTLS_ACTIVE(ws));
2848 }
2849 if (DTLS_INACTIVE(ws)->udp_state == UP_ACTIVE && DTLS_INACTIVE(ws)->dtls_session) {
2850 dtls_close(DTLS_INACTIVE(ws));
2851 }
2852
2853 exit_worker_reason(ws, terminate_reason);
2854
2855 return 1;
2856 }