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 }