1 /*
2  *  Copyright (C) 2015 Adrien Vergé
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  *  In addition, as a special exception, the copyright holders give permission
18  *  to link the code of portions of this program with the OpenSSL library under
19  *  certain conditions as described in each individual source file, and
20  *  distribute linked combinations including the two.
21  *  You must obey the GNU General Public License in all respects for all of the
22  *  code used other than OpenSSL.  If you modify file(s) with this exception,
23  *  you may extend this exception to your version of the file(s), but you are
24  *  not obligated to do so.  If you do not wish to do so, delete this exception
25  *  statement from your version.  If you delete this exception statement from
26  *  all source files in the program, then also delete it here.
27  */
28 
29 #include "tunnel.h"
30 #include "http.h"
31 #include "log.h"
32 #include "userinput.h"
33 #ifndef HAVE_X509_CHECK_HOST
34 #include "openssl_hostname_validation.h"
35 #endif
36 
37 #include <openssl/err.h>
38 #ifndef OPENSSL_NO_ENGINE
39 #include <openssl/engine.h>
40 #endif
41 #include <openssl/ui.h>
42 #include <openssl/x509v3.h>
43 #if HAVE_SYSTEMD
44 #include <systemd/sd-daemon.h>
45 #endif
46 
47 #include <unistd.h>
48 #include <arpa/inet.h>
49 #include <fcntl.h>
50 #include <ifaddrs.h>
51 #include <netdb.h>
52 #if HAVE_PTY_H
53 #include <pty.h>
54 #elif HAVE_UTIL_H
55 #include <util.h>
56 #endif
57 #include <sys/types.h>
58 #include <sys/socket.h>
59 #include <sys/wait.h>
60 #include <sys/ioctl.h>
61 #include <termios.h>
62 #if HAVE_LIBUTIL_H
63 #include <libutil.h>
64 #endif
65 
66 #include <errno.h>
67 #include <signal.h>
68 #include <string.h>
69 #include <assert.h>
70 
71 
72 struct ofv_varr {
73 	unsigned int cap;	// current capacity
74 	unsigned int off;	// next slot to write, always < max(cap - 1, 1)
75 	const char **data;	// NULL terminated
76 };
77 
ofv_append_varr(struct ofv_varr * p,const char * x)78 static int ofv_append_varr(struct ofv_varr *p, const char *x)
79 {
80 	if (p->off + 1 >= p->cap) {
81 		const char **ndata;
82 		unsigned int ncap = (p->off + 1) * 2;
83 
84 		if (p->off + 1 >= ncap) {
85 			log_error("%s: ncap exceeded\n", __func__);
86 			return 1;
87 		};
88 		ndata = realloc(p->data, ncap * sizeof(const char *));
89 		if (ndata) {
90 			p->data = ndata;
91 			p->cap = ncap;
92 		} else {
93 			log_error("realloc: %s\n", strerror(errno));
94 			return 1;
95 		}
96 	}
97 	if (p->data == NULL) {
98 		log_error("%s: NULL data\n", __func__);
99 		return 1;
100 	}
101 	if (p->off + 1 >= p->cap) {
102 		log_error("%s: cap exceeded in p\n", __func__);
103 		return 1;
104 	}
105 	p->data[p->off] = x;
106 	p->data[++p->off] = NULL;
107 	return 0;
108 }
109 
on_ppp_if_up(struct tunnel * tunnel)110 static int on_ppp_if_up(struct tunnel *tunnel)
111 {
112 	log_info("Interface %s is UP.\n", tunnel->ppp_iface);
113 
114 	if (tunnel->config->set_routes) {
115 		int ret;
116 
117 		log_info("Setting new routes...\n");
118 
119 		ret = ipv4_set_tunnel_routes(tunnel);
120 
121 		if (ret != 0)
122 			log_warn("Adding route table is incomplete. Please check route table.\n");
123 	}
124 
125 	if (tunnel->config->set_dns) {
126 		log_info("Adding VPN nameservers...\n");
127 		ipv4_add_nameservers_to_resolv_conf(tunnel);
128 	}
129 
130 	log_info("Tunnel is up and running.\n");
131 
132 #if HAVE_SYSTEMD
133 	sd_notify(0, "READY=1");
134 #endif
135 
136 	return 0;
137 }
138 
on_ppp_if_down(struct tunnel * tunnel)139 static int on_ppp_if_down(struct tunnel *tunnel)
140 {
141 #if HAVE_SYSTEMD
142 	sd_notify(0, "STOPPING=1");
143 #endif
144 
145 	log_info("Setting %s interface down.\n", tunnel->ppp_iface);
146 
147 	if (tunnel->config->set_routes) {
148 		log_info("Restoring routes...\n");
149 		ipv4_restore_routes(tunnel);
150 	}
151 
152 	if (tunnel->config->set_dns) {
153 		log_info("Removing VPN nameservers...\n");
154 		ipv4_del_nameservers_from_resolv_conf(tunnel);
155 	}
156 
157 	return 0;
158 }
159 
pppd_run(struct tunnel * tunnel)160 static int pppd_run(struct tunnel *tunnel)
161 {
162 	pid_t pid;
163 	int amaster;
164 	int slave_stderr;
165 
166 #ifdef HAVE_STRUCT_TERMIOS
167 	struct termios termp = {
168 		.c_cflag = B9600,
169 		.c_cc[VTIME] = 0,
170 		.c_cc[VMIN] = 1
171 	};
172 #endif
173 
174 	static const char ppp_path[] = PPP_PATH;
175 
176 	if (access(ppp_path, F_OK) != 0) {
177 		log_error("%s: %s.\n", ppp_path, strerror(errno));
178 		return 1;
179 	}
180 	log_debug("ppp_path: %s\n", ppp_path);
181 
182 	slave_stderr = dup(STDERR_FILENO);
183 
184 	if (slave_stderr < 0) {
185 		log_error("slave stderr: %s\n", strerror(errno));
186 		return 1;
187 	}
188 
189 #ifdef HAVE_STRUCT_TERMIOS
190 	pid = forkpty(&amaster, NULL, &termp, NULL);
191 #else
192 	pid = forkpty(&amaster, NULL, NULL, NULL);
193 #endif
194 
195 	if (pid == 0) { // child process
196 
197 		struct ofv_varr pppd_args = { 0, 0, NULL };
198 
199 		dup2(slave_stderr, STDERR_FILENO);
200 		if (close(slave_stderr))
201 			log_warn("Could not close slave stderr (%s).\n", strerror(errno));
202 
203 #if HAVE_USR_SBIN_PPP
204 		/*
205 		 * assume there is a default configuration to start.
206 		 * Support for taking options from the command line
207 		 * e.g. the name of the configuration or options
208 		 * to send interactively to ppp will be added later
209 		 */
210 		static const char *const v[] = {
211 			ppp_path,
212 			"-direct"
213 		};
214 		for (unsigned int i = 0; i < ARRAY_SIZE(v); i++)
215 			if (ofv_append_varr(&pppd_args, v[i])) {
216 				free(pppd_args.data);
217 				return 1;
218 			}
219 #endif
220 #if HAVE_USR_SBIN_PPPD
221 		if (tunnel->config->pppd_call) {
222 			if (ofv_append_varr(&pppd_args, ppp_path)) {
223 				free(pppd_args.data);
224 				return 1;
225 			}
226 			if (ofv_append_varr(&pppd_args, "call")) {
227 				free(pppd_args.data);
228 				return 1;
229 			}
230 			if (ofv_append_varr(&pppd_args, tunnel->config->pppd_call)) {
231 				free(pppd_args.data);
232 				return 1;
233 			}
234 		} else {
235 			static const char *const v[] = {
236 				ppp_path,
237 				"230400", // speed
238 				":169.254.2.1", // <local_IP_address>:<remote_IP_address>
239 				"noipdefault",
240 				"noaccomp",
241 				"noauth",
242 				"default-asyncmap",
243 				"nopcomp",
244 				"receive-all",
245 				"nodefaultroute",
246 				"nodetach",
247 				"lcp-max-configure", "40",
248 				"mru", "1354"
249 			};
250 			for (unsigned int i = 0; i < ARRAY_SIZE(v); i++)
251 				if (ofv_append_varr(&pppd_args, v[i])) {
252 					free(pppd_args.data);
253 					return 1;
254 				}
255 		}
256 		if (tunnel->config->pppd_use_peerdns)
257 			if (ofv_append_varr(&pppd_args, "usepeerdns")) {
258 				free(pppd_args.data);
259 				return 1;
260 			}
261 		if (tunnel->config->pppd_log) {
262 			if (ofv_append_varr(&pppd_args, "debug")) {
263 				free(pppd_args.data);
264 				return 1;
265 			}
266 			if (ofv_append_varr(&pppd_args, "logfile")) {
267 				free(pppd_args.data);
268 				return 1;
269 			}
270 			if (ofv_append_varr(&pppd_args, tunnel->config->pppd_log)) {
271 				free(pppd_args.data);
272 				return 1;
273 			}
274 		} else {
275 			/*
276 			 * pppd defaults to logging to fd=1, clobbering the
277 			 * actual PPP data
278 			 */
279 			if (ofv_append_varr(&pppd_args, "logfd")) {
280 				free(pppd_args.data);
281 				return 1;
282 			}
283 			if (ofv_append_varr(&pppd_args, "2")) {
284 				free(pppd_args.data);
285 				return 1;
286 			}
287 		}
288 		if (tunnel->config->pppd_plugin) {
289 			if (ofv_append_varr(&pppd_args, "plugin")) {
290 				free(pppd_args.data);
291 				return 1;
292 			}
293 			if (ofv_append_varr(&pppd_args, tunnel->config->pppd_plugin)) {
294 				free(pppd_args.data);
295 				return 1;
296 			}
297 		}
298 		if (tunnel->config->pppd_ipparam) {
299 			if (ofv_append_varr(&pppd_args, "ipparam")) {
300 				free(pppd_args.data);
301 				return 1;
302 			}
303 			if (ofv_append_varr(&pppd_args, tunnel->config->pppd_ipparam)) {
304 				free(pppd_args.data);
305 				return 1;
306 			}
307 		}
308 		if (tunnel->config->pppd_ifname) {
309 			if (ofv_append_varr(&pppd_args, "ifname")) {
310 				free(pppd_args.data);
311 				return 1;
312 			}
313 			if (ofv_append_varr(&pppd_args, tunnel->config->pppd_ifname)) {
314 				free(pppd_args.data);
315 				return 1;
316 			}
317 		}
318 #endif
319 #if HAVE_USR_SBIN_PPP
320 		if (tunnel->config->ppp_system) {
321 			if (ofv_append_varr(&pppd_args, tunnel->config->ppp_system)) {
322 				free(pppd_args.data);
323 				return 1;
324 			}
325 		}
326 #endif
327 
328 		if (close(tunnel->ssl_socket))
329 			log_warn("Could not close ssl socket (%s).\n", strerror(errno));
330 		tunnel->ssl_socket = -1;
331 		execv(pppd_args.data[0], (char *const *)pppd_args.data);
332 		free(pppd_args.data);
333 
334 		fprintf(stderr, "execv: %s\n", strerror(errno));
335 		_exit(EXIT_FAILURE);
336 	} else {
337 		if (close(slave_stderr))
338 			log_error("Could not close slave stderr (%s).\n",
339 			          strerror(errno));
340 		if (pid == -1) {
341 			log_error("forkpty: %s\n", strerror(errno));
342 			return 1;
343 		}
344 	}
345 
346 	// Set non-blocking
347 	int flags = fcntl(amaster, F_GETFL, 0);
348 
349 	if (flags == -1)
350 		flags = 0;
351 	if (fcntl(amaster, F_SETFL, flags | O_NONBLOCK) == -1) {
352 		log_error("fcntl: %s\n", strerror(errno));
353 		return 1;
354 	}
355 
356 	tunnel->pppd_pid = pid;
357 	tunnel->pppd_pty = amaster;
358 
359 	return 0;
360 }
361 
362 static const char * const ppp_message[] = {
363 #if HAVE_USR_SBIN_PPPD // pppd(8) - https://ppp.samba.org/pppd.html
364 	"Has detached, or otherwise the connection was successfully established and terminated at the peer's request.",
365 	"An immediately fatal error of some kind occurred, such as an essential system call failing, or running out of virtual memory.",
366 	"An error was detected in processing the options given, such as two mutually exclusive options being used.",
367 	"Is not setuid-root and the invoking user is not root.",
368 	"The kernel does not support PPP, for example, the PPP kernel driver is not included or cannot be loaded.",
369 	"Terminated because it was sent a SIGINT, SIGTERM or SIGHUP signal.",
370 	"The serial port could not be locked.",
371 	"The serial port could not be opened.",
372 	"The connect script failed (returned a non-zero exit status).",
373 	"The command specified as the argument to the pty option could not be run.",
374 	"The PPP negotiation failed, that is, it didn't reach the point where at least one network protocol (e.g. IP) was running.",
375 	"The peer system failed (or refused) to authenticate itself.",
376 	"The link was established successfully and terminated because it was idle.",
377 	"The link was established successfully and terminated because the connect time limit was reached.",
378 	"Callback was negotiated and an incoming call should arrive shortly.",
379 	"The link was terminated because the peer is not responding to echo requests.",
380 	"The link was terminated by the modem hanging up.",
381 	"The PPP negotiation failed because serial loopback was detected.",
382 	"The init script failed (returned a non-zero exit status).",
383 	"We failed to authenticate ourselves to the peer."
384 #else // sysexits(3) - https://www.freebsd.org/cgi/man.cgi?query=sysexits
385 	// EX_NORMAL = EX_OK (0)
386 	"Successful exit.",
387 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 1-9
388 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	// 10-19
389 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 20-29
390 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 30-39
391 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 40-49
392 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 50-59
393 	NULL, NULL, NULL, NULL, // 60-63
394 	// EX_USAGE (64)
395 	"The command was used incorrectly, e.g., with the wrong number of arguments, a bad flag, a bad syntax in a parameter, or whatever.",
396 	NULL, NULL, NULL, NULL, // 65-68
397 	// EX_UNAVAILABLE (69)
398 	"A service is unavailable. This can occur if a support program or file does not exist.",
399 	// EX_ERRDEAD = EX_SOFTWARE (70)
400 	"An internal software error has been detected.",
401 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 71-77
402 	// EX_CONFIG (78)
403 	"Something was found in an unconfigured or misconfigured state.",
404 	NULL, // 79
405 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 80-89
406 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 90-98
407 	NULL // EX_TERMINATE (99), PPP internal pseudo-code
408 #endif
409 };
410 
pppd_terminate(struct tunnel * tunnel)411 static int pppd_terminate(struct tunnel *tunnel)
412 {
413 	if (close(tunnel->pppd_pty))
414 		log_warn("Could not close pppd pty (%s).\n", strerror(errno));
415 
416 	log_debug("Waiting for %s to exit...\n", PPP_DAEMON);
417 
418 	int status;
419 
420 	/*
421 	 * Errors outside of the PPP process are returned as negative integers.
422 	 */
423 	if (waitpid(tunnel->pppd_pid, &status, 0) == -1) {
424 		log_error("waitpid: %s\n", strerror(errno));
425 		return -1;
426 	}
427 
428 	/*
429 	 * Errors in the PPP process are returned as positive integers.
430 	 */
431 	if (WIFEXITED(status)) {
432 		int exit_status = WEXITSTATUS(status);
433 
434 		/*
435 		 * PPP exit status codes are positive integers. The way we interpret
436 		 * their value is not straightforward:
437 		 * - in the case of "normal" exit, the PPP process may return 0,
438 		 *   but also a strictly positive integer such as 16 in the case of
439 		 *   pppd,
440 		 * - in the case of failure, the PPP process will return a strictly
441 		 *   positive integer.
442 		 * For now we process PPP exit status codes as follows:
443 		 * - exit status codes synonym of success are logged and then
444 		 *   translated to 0 before they are returned to the calling function,
445 		 * - other exit status codes are considered synonyms of failure and
446 		 *   returned to the calling function as is.
447 		 */
448 		log_debug("waitpid: %s exit status code %d\n",
449 		          PPP_DAEMON, exit_status);
450 		if (exit_status >= ARRAY_SIZE(ppp_message)) {
451 			log_error("%s: Returned an unknown exit status code: %d\n",
452 			          PPP_DAEMON, exit_status);
453 		} else {
454 			switch (exit_status) {
455 			/*
456 			 * PPP exit status codes considered as success
457 			 */
458 			case 0:
459 				log_debug("%s: %s\n",
460 				          PPP_DAEMON, ppp_message[exit_status]);
461 				break;
462 #if HAVE_USR_SBIN_PPPD
463 			case 16: // emitted by Ctrl+C or "kill -15"
464 				if (get_sig_received() == SIGINT
465 				    || get_sig_received() == SIGTERM) {
466 					log_info("%s: %s\n",
467 					         PPP_DAEMON, ppp_message[exit_status]);
468 					exit_status = 0;
469 					break;
470 				}
471 #endif
472 			/*
473 			 * PPP exit status codes considered as failure
474 			 */
475 			default:
476 				if (ppp_message[exit_status])
477 					log_error("%s: %s\n",
478 					          PPP_DAEMON, ppp_message[exit_status]);
479 				else
480 					log_error("%s: Returned an unexpected exit status code: %d\n",
481 					          PPP_DAEMON, exit_status);
482 				break;
483 			}
484 		}
485 		return exit_status;
486 	} else if (WIFSIGNALED(status)) {
487 		int signal_number = WTERMSIG(status);
488 
489 		/*
490 		 * For now we do not consider interruption of the PPP process by
491 		 * a signal as a failure. Should we?
492 		 */
493 		log_debug("waitpid: %s terminated by signal %d\n",
494 		          PPP_DAEMON, signal_number);
495 		log_error("%s: terminated by signal: %s\n",
496 		          PPP_DAEMON, strsignal(signal_number));
497 	}
498 
499 	return 0;
500 }
501 
ppp_interface_is_up(struct tunnel * tunnel)502 int ppp_interface_is_up(struct tunnel *tunnel)
503 {
504 	struct ifaddrs *ifap, *ifa;
505 
506 	log_debug("Got Address: %s\n", inet_ntoa(tunnel->ipv4.ip_addr));
507 
508 	if (getifaddrs(&ifap)) {
509 		log_error("getifaddrs: %s\n", strerror(errno));
510 		return 0;
511 	}
512 
513 	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
514 		if (
515 #if HAVE_USR_SBIN_PPPD
516 		        ((tunnel->config->pppd_ifname &&
517 		          strstr(ifa->ifa_name, tunnel->config->pppd_ifname) != NULL) ||
518 		         strstr(ifa->ifa_name, "ppp") != NULL) &&
519 #endif
520 #if HAVE_USR_SBIN_PPP
521 		        strstr(ifa->ifa_name, "tun") != NULL &&
522 #endif
523 		        ifa->ifa_flags & IFF_UP) {
524 			if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
525 				struct in_addr if_ip_addr =
526 				        cast_addr(ifa->ifa_addr)->sin_addr;
527 
528 				log_debug("Interface Name: %s\n", ifa->ifa_name);
529 				log_debug("Interface Addr: %s\n", inet_ntoa(if_ip_addr));
530 
531 				if (tunnel->ipv4.ip_addr.s_addr == if_ip_addr.s_addr) {
532 					strncpy(tunnel->ppp_iface, ifa->ifa_name,
533 					        ROUTE_IFACE_LEN - 1);
534 					freeifaddrs(ifap);
535 					return 1;
536 				}
537 			}
538 		}
539 	}
540 	freeifaddrs(ifap);
541 
542 	return 0;
543 }
544 
get_gateway_host_ip(struct tunnel * tunnel)545 static int get_gateway_host_ip(struct tunnel *tunnel)
546 {
547 	const struct addrinfo hints = { .ai_family = AF_INET };
548 	struct addrinfo *result = NULL;
549 
550 	int ret = getaddrinfo(tunnel->config->gateway_host, NULL, &hints, &result);
551 
552 	if (ret) {
553 		if (ret == EAI_SYSTEM)
554 			log_error("getaddrinfo: %s\n", strerror(errno));
555 		else
556 			log_error("getaddrinfo: %s\n", gai_strerror(ret));
557 		return 1;
558 	}
559 
560 	tunnel->config->gateway_ip = ((struct sockaddr_in *)
561 	                              result->ai_addr)->sin_addr;
562 	freeaddrinfo(result);
563 
564 	setenv("VPN_GATEWAY", inet_ntoa(tunnel->config->gateway_ip), 0);
565 
566 	return 0;
567 }
568 
tcp_getsockopt(int sockfd,int optname)569 static int tcp_getsockopt(int sockfd, int optname)
570 {
571 	int optval;
572 	socklen_t optlen = sizeof(optval);
573 
574 	if (getsockopt(sockfd, IPPROTO_TCP, optname,
575 	               (void *)&optval, &optlen))
576 		return -1;
577 	assert(optlen == sizeof(optval));
578 	return optval;
579 }
580 
581 /*
582  * Establish a regular TCP connection.
583  */
tcp_connect(struct tunnel * tunnel)584 static int tcp_connect(struct tunnel *tunnel)
585 {
586 	int ret, handle;
587 	struct sockaddr_in server;
588 	char *env_proxy;
589 	const int iface_len = strnlen(tunnel->config->iface_name, IF_NAMESIZE);
590 
591 	handle = socket(AF_INET, SOCK_STREAM, 0);
592 
593 	if (handle == -1) {
594 		log_error("socket: %s\n", strerror(errno));
595 		goto err_socket;
596 	}
597 
598 	/*
599 	 * Attempt to find default TCP socket options on different platforms.
600 	 */
601 #ifdef SO_KEEPALIVE
602 	ret = tcp_getsockopt(handle, SO_KEEPALIVE);
603 	if (ret < 0)
604 		log_warn("getsockopt: %s: %s\n", "SO_KEEPALIVE", strerror(errno));
605 	else
606 		log_debug("SO_KEEPALIVE: %d\n", ret);
607 #endif
608 #ifdef TCP_KEEPIDLE
609 	ret = tcp_getsockopt(handle, TCP_KEEPIDLE);
610 	if (ret < 0)
611 		log_warn("getsockopt: %s: %s\n", "TCP_KEEPIDLE", strerror(errno));
612 	else
613 		log_debug("TCP_KEEPIDLE: %d\n", ret);
614 #endif
615 #ifdef TCP_KEEPALIVE
616 	ret = tcp_getsockopt(handle, TCP_KEEPALIVE);
617 	if (ret < 0)
618 		log_warn("getsockopt: %s: %s\n", "TCP_KEEPALIVE", strerror(errno));
619 	else
620 		log_debug("TCP_KEEPALIVE: %d\n", ret);
621 #endif
622 #ifdef TCP_KEEPINTVL
623 	ret = tcp_getsockopt(handle, TCP_KEEPINTVL);
624 	if (ret < 0)
625 		log_warn("getsockopt: %s: %s\n", "TCP_KEEPINTVL", strerror(errno));
626 	else
627 		log_debug("TCP_KEEPINTVL: %d\n", ret);
628 #endif
629 #ifdef TCP_KEEPCNT
630 	ret = tcp_getsockopt(handle, TCP_KEEPCNT);
631 	if (ret < 0)
632 		log_warn("getsockopt: %s: %s\n", "TCP_KEEPCNT", strerror(errno));
633 	else
634 		log_debug("TCP_KEEPCNT: %d\n", ret);
635 #endif
636 #ifdef SO_SNDBUF
637 	ret = tcp_getsockopt(handle, SO_SNDBUF);
638 	if (ret < 0)
639 #ifndef __APPLE__
640 		log_warn("getsockopt: %s: %s\n", "SO_SNDBUF", strerror(errno));
641 	else
642 #endif
643 		log_debug("SO_SNDBUF: %d\n", ret);
644 #endif
645 #ifdef SO_RCVBUF
646 	ret = tcp_getsockopt(handle, SO_RCVBUF);
647 	if (ret < 0)
648 #ifndef __APPLE__
649 		log_warn("getsockopt: %s: %s\n", "SO_RCVBUF", strerror(errno));
650 	else
651 #endif
652 		log_debug("SO_RCVBUF: %d\n", ret);
653 #endif
654 
655 	if (iface_len == IF_NAMESIZE) {
656 		log_error("socket: Too long iface name\n");
657 		goto err_post_socket;
658 	}
659 	if (iface_len > 0) {
660 #if HAVE_SO_BINDTODEVICE
661 		ret = setsockopt(handle, SOL_SOCKET, SO_BINDTODEVICE,
662 		                 tunnel->config->iface_name, iface_len);
663 #else
664 		struct ifreq ifr;
665 
666 		memset(&ifr, 0, sizeof(ifr));
667 		if (strlcpy(ifr.ifr_name, tunnel->config->iface_name, IF_NAMESIZE)
668 		    >= IF_NAMESIZE) {
669 			log_error("interface name too long\n");
670 			goto err_post_socket;
671 		}
672 		ifr.ifr_addr.sa_family = AF_INET;
673 		if (ioctl(handle, SIOCGIFADDR, &ifr) == -1) {
674 			log_error("ioctl(%d,SIOCGIFADDR,\"%s\") failed\n", handle,
675 			          ifr.ifr_name);
676 			goto err_post_socket;
677 		}
678 		ret = bind(handle, &ifr.ifr_addr, ifr.ifr_addr.sa_len);
679 #endif
680 		if (ret) {
681 			log_error("socket: setting interface name failed with error: %d\n",
682 			          errno);
683 			goto err_post_socket;
684 		}
685 	}
686 
687 	env_proxy = getenv("https_proxy");
688 	if (env_proxy == NULL)
689 		env_proxy = getenv("HTTPS_PROXY");
690 	if (env_proxy == NULL)
691 		env_proxy = getenv("all_proxy");
692 	if (env_proxy == NULL)
693 		env_proxy = getenv("ALL_PROXY");
694 	if (env_proxy != NULL) {
695 		char *proxy_host, *proxy_port;
696 		// protect the original environment from modifications
697 		env_proxy = strdup(env_proxy);
698 		if (env_proxy == NULL) {
699 			log_error("strdup: %s\n", strerror(errno));
700 			goto err_strdup;
701 		}
702 		// get rid of a trailing slash
703 		if (*env_proxy && env_proxy[strlen(env_proxy) - 1] == '/')
704 			env_proxy[strlen(env_proxy) - 1] = '\0';
705 		// get rid of a http(s):// prefix in env_proxy
706 		proxy_host = strstr(env_proxy, "://");
707 		if (proxy_host == NULL)
708 			proxy_host = env_proxy;
709 		else
710 			proxy_host += 3;
711 		// split host and port
712 		proxy_port = strchr(proxy_host, ':');
713 		if (proxy_port != NULL) {
714 			proxy_port[0] = '\0';
715 			proxy_port++;
716 			server.sin_port = htons(strtoul(proxy_port, NULL, 10));
717 		} else {
718 			server.sin_port = htons(tunnel->config->gateway_port);
719 		}
720 		// get rid of a trailing slash
721 		if (*proxy_host && proxy_host[strlen(proxy_host) - 1] == '/')
722 			proxy_host[strlen(proxy_host) - 1] = '\0';
723 		log_debug("proxy_host: %s\n", proxy_host);
724 		log_debug("proxy_port: %s\n", proxy_port);
725 		server.sin_addr.s_addr = inet_addr(proxy_host);
726 		// if host is given as a FQDN we have to do a DNS lookup
727 		if (server.sin_addr.s_addr == INADDR_NONE) {
728 			const struct addrinfo hints = { .ai_family = AF_INET };
729 			struct addrinfo *result = NULL;
730 
731 			ret = getaddrinfo(proxy_host, NULL, &hints, &result);
732 			if (ret) {
733 				if (ret == EAI_SYSTEM)
734 					log_error("getaddrinfo: %s\n", strerror(errno));
735 				else
736 					log_error("getaddrinfo: %s\n", gai_strerror(ret));
737 				goto err_connect;
738 			}
739 
740 			server.sin_addr = ((struct sockaddr_in *)
741 			                   result->ai_addr)->sin_addr;
742 			freeaddrinfo(result);
743 		}
744 	} else {
745 		server.sin_port = htons(tunnel->config->gateway_port);
746 		server.sin_addr = tunnel->config->gateway_ip;
747 	}
748 
749 	log_debug("server_addr: %s\n", inet_ntoa(server.sin_addr));
750 	log_debug("server_port: %u\n", ntohs(server.sin_port));
751 	server.sin_family = AF_INET;
752 	memset(&(server.sin_zero), '\0', 8);
753 	log_debug("gateway_addr: %s\n", inet_ntoa(tunnel->config->gateway_ip));
754 	log_debug("gateway_port: %u\n", tunnel->config->gateway_port);
755 
756 	ret = connect(handle, (struct sockaddr *) &server, sizeof(server));
757 	if (ret) {
758 		log_error("connect: %s\n", strerror(errno));
759 		goto err_connect;
760 	}
761 
762 	if (env_proxy != NULL) {
763 		char request[128];
764 
765 		// https://tools.ietf.org/html/rfc7231#section-4.3.6
766 		sprintf(request, "CONNECT %s:%u HTTP/1.1\r\nHost: %s:%u\r\n\r\n",
767 		        inet_ntoa(tunnel->config->gateway_ip),
768 		        tunnel->config->gateway_port,
769 		        inet_ntoa(tunnel->config->gateway_ip),
770 		        tunnel->config->gateway_port);
771 
772 		ssize_t bytes_written = write(handle, request, strlen(request));
773 
774 		if (bytes_written != strlen(request)) {
775 			log_error("write error while talking to proxy: %s\n",
776 			          strerror(errno));
777 			goto err_connect;
778 		}
779 
780 		// wait for a "200 OK" reply from the proxy,
781 		// be careful not to fetch too many bytes at once
782 		const char *response = NULL;
783 
784 		memset(&(request), '\0', sizeof(request));
785 		for (int j = 0; response == NULL; j++) {
786 			if (j >= ARRAY_SIZE(request) - 1) {
787 				log_error("Proxy response is unexpectedly large and cannot fit in the %lu-bytes buffer.\n",
788 				          ARRAY_SIZE(request));
789 				goto err_proxy_response;
790 			}
791 
792 			ssize_t bytes_read = read(handle, &(request[j]), 1);
793 			static const char HTTP_STATUS_200[] = "200";
794 
795 			// we have reached the end of the data sent by the proxy
796 			// and have not seen HTTP status code 200
797 			if (bytes_read < 1) {
798 				log_error("Proxy response does not contain \"%s\" as expected.\n",
799 				          HTTP_STATUS_200);
800 				goto err_proxy_response;
801 			}
802 
803 			// detect "200"
804 			response = strstr(request, HTTP_STATUS_200);
805 
806 			// detect end-of-line after "200"
807 			if (response != NULL) {
808 				/*
809 				 * RFC 2616 states in section 2.2 Basic Rules:
810 				 *      CR     = <US-ASCII CR, carriage return (13)>
811 				 *      LF     = <US-ASCII LF, linefeed (10)>
812 				 *      HTTP/1.1 defines the sequence CR LF as the
813 				 *      end-of-line marker for all protocol elements
814 				 *      except the entity-body (see appendix 19.3
815 				 *      for tolerant applications).
816 				 *              CRLF   = CR LF
817 				 *
818 				 * RFC 2616 states in section 19.3 Tolerant Applications:
819 				 *      The line terminator for message-header fields
820 				 *      is the sequence CRLF. However, we recommend
821 				 *      that applications, when parsing such headers,
822 				 *      recognize a single LF as a line terminator
823 				 *      and ignore the leading CR.
824 				 */
825 				static const char *const HTTP_EOL[] = {
826 					"\r\n\r\n",
827 					"\n\n"
828 				};
829 				const char *eol = NULL;
830 
831 				for (int i = 0; (i < ARRAY_SIZE(HTTP_EOL)) &&
832 				     (eol == NULL); i++)
833 					eol = strstr(response, HTTP_EOL[i]);
834 				response = eol;
835 			}
836 		}
837 
838 		free(env_proxy); // release memory allocated by strdup()
839 	}
840 
841 	return handle;
842 
843 err_proxy_response:
844 err_connect:
845 	free(env_proxy); // release memory allocated by strdup()
846 err_strdup:
847 err_post_socket:
848 	if (close(handle))
849 		log_warn("Could not close socket (%s).\n", strerror(errno));
850 err_socket:
851 	return -1;
852 }
853 
ssl_verify_cert(struct tunnel * tunnel)854 static int ssl_verify_cert(struct tunnel *tunnel)
855 {
856 	int ret = -1;
857 	int cert_valid = 0;
858 	unsigned char digest[SHA256LEN];
859 	unsigned int len;
860 	struct x509_digest *elem;
861 	char digest_str[SHA256STRLEN], *subject, *issuer;
862 	char *line;
863 	int i;
864 	X509_NAME *subj;
865 	char *saveptr = NULL;
866 
867 	SSL_set_verify(tunnel->ssl_handle, SSL_VERIFY_PEER, NULL);
868 
869 	X509 *cert = SSL_get_peer_certificate(tunnel->ssl_handle);
870 
871 	if (cert == NULL) {
872 		log_error("Unable to get gateway certificate.\n");
873 		return 1;
874 	}
875 
876 	subj = X509_get_subject_name(cert);
877 
878 #ifdef HAVE_X509_CHECK_HOST
879 	// Use OpenSSL native host validation if v >= 1.0.2.
880 	// compare against gateway_host and correctly check return value
881 	// to fix prior incorrect use of X509_check_host
882 	if (X509_check_host(cert, tunnel->config->gateway_host,
883 	                    0, 0, NULL) == 1)
884 		cert_valid = 1;
885 #else
886 	// Use validate_hostname form iSECPartners if native validation not available
887 	// in order to avoid TLS Certificate CommonName NULL Byte Vulnerability
888 	if (validate_hostname(tunnel->config->gateway_host, cert) == MatchFound)
889 		cert_valid = 1;
890 #endif
891 
892 	// Try to validate certificate using local PKI
893 	if (cert_valid
894 	    && SSL_get_verify_result(tunnel->ssl_handle) == X509_V_OK) {
895 		log_debug("Gateway certificate validation succeeded.\n");
896 		ret = 0;
897 		goto free_cert;
898 	}
899 	log_debug("Gateway certificate validation failed.\n");
900 
901 	// If validation failed, check if cert is in the white list
902 	if (X509_digest(cert, EVP_sha256(), digest, &len) <= 0
903 	    || len != SHA256LEN) {
904 		log_error("Could not compute certificate sha256 digest.\n");
905 		goto free_cert;
906 	}
907 	// Encode digest in base16
908 	for (i = 0; i < SHA256LEN; i++)
909 		sprintf(&digest_str[2 * i], "%02x", digest[i]);
910 	digest_str[SHA256STRLEN - 1] = '\0';
911 	// Is it in whitelist?
912 	for (elem = tunnel->config->cert_whitelist; elem != NULL;
913 	     elem = elem->next)
914 		if (memcmp(digest_str, elem->data, SHA256STRLEN - 1) == 0)
915 			break;
916 	if (elem != NULL) { // break before end of loop
917 		log_debug("Gateway certificate digest found in white list.\n");
918 		ret = 0;
919 		goto free_cert;
920 	}
921 
922 	log_error("Gateway certificate validation failed, and the certificate digest is not in the local whitelist. If you trust it, rerun with:\n");
923 	log_error("    --trusted-cert %s\n", digest_str);
924 	log_error("or add this line to your configuration file:\n");
925 	log_error("    trusted-cert = %s\n", digest_str);
926 	log_error("Gateway certificate:\n");
927 	log_error("    subject:\n");
928 	subject = X509_NAME_oneline(subj, NULL, 0);
929 	if (subject) {
930 		for (line = strtok_r(subject, "/", &saveptr); line != NULL;
931 		     line = strtok_r(NULL, "/", &saveptr))
932 			log_error("        %s\n", line);
933 		free(subject);
934 	}
935 	log_error("    issuer:\n");
936 	issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
937 	if (issuer) {
938 		for (line = strtok_r(issuer, "/", &saveptr); line != NULL;
939 		     line = strtok_r(NULL, "/", &saveptr))
940 			log_error("        %s\n", line);
941 		free(issuer);
942 	}
943 	log_error("    sha256 digest:\n");
944 	log_error("        %s\n", digest_str);
945 
946 free_cert:
947 	X509_free(cert);
948 	return ret;
949 }
950 
951 /*
952  * Destroy and free the SSL connection to the gateway.
953  */
ssl_disconnect(struct tunnel * tunnel)954 static void ssl_disconnect(struct tunnel *tunnel)
955 {
956 	if (!tunnel->ssl_handle)
957 		return;
958 
959 	SSL_shutdown(tunnel->ssl_handle);
960 	SSL_free(tunnel->ssl_handle);
961 	tunnel->ssl_handle = NULL;
962 
963 	SSL_CTX_free(tunnel->ssl_context);
964 	tunnel->ssl_context = NULL;
965 
966 	if (close(tunnel->ssl_socket))
967 		log_warn("Could not close ssl socket (%s).\n", strerror(errno));
968 	tunnel->ssl_socket = -1;
969 }
970 
971 /*
972  * Query for the pass phrase used for encrypted PEM structures
973  * (normally only private keys).
974  */
pem_passphrase_cb(char * buf,int size,int rwflag,void * u)975 static int pem_passphrase_cb(char *buf, int size, int rwflag, void *u)
976 {
977 	struct vpn_config *cfg = (struct vpn_config *)u;
978 
979 	/* We expect to only read PEM pass phrases, not write them. */
980 	if (rwflag == 0) {
981 		if (!cfg->pem_passphrase_set) {
982 			if (size > PEM_PASSPHRASE_SIZE) {
983 				read_password(NULL, NULL,
984 				              "Enter PEM pass phrase: ",
985 				              cfg->pem_passphrase,
986 				              PEM_PASSPHRASE_SIZE + 1);
987 				cfg->pem_passphrase_set =  1;
988 			} else {
989 				log_error("Buffer too small for PEM pass phrase: %d.",
990 				          size);
991 			}
992 		}
993 		if (cfg->pem_passphrase_set) {
994 			assert(strlen(cfg->pem_passphrase) < size);
995 			strncpy(buf, cfg->pem_passphrase, size);
996 			buf[size - 1] = '\0';
997 			return strlen(buf);
998 		}
999 	} else {
1000 		log_error("We refuse to write PEM pass phrases!");
1001 	}
1002 
1003 	return -1;
1004 }
1005 
1006 /*
1007  * Connects to the gateway and initiate an SSL session.
1008  */
ssl_connect(struct tunnel * tunnel)1009 int ssl_connect(struct tunnel *tunnel)
1010 {
1011 	ssl_disconnect(tunnel);
1012 
1013 	tunnel->ssl_socket = tcp_connect(tunnel);
1014 	if (tunnel->ssl_socket == -1)
1015 		goto err_tcp_connect;
1016 
1017 	// https://wiki.openssl.org/index.php/Library_Initialization
1018 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1019 	// Register the error strings for libcrypto & libssl
1020 	SSL_load_error_strings();
1021 	// Register the available ciphers and digests
1022 	SSL_library_init();
1023 
1024 	tunnel->ssl_context = SSL_CTX_new(SSLv23_client_method());
1025 #else
1026 	tunnel->ssl_context = SSL_CTX_new(TLS_client_method());
1027 #endif
1028 	if (tunnel->ssl_context == NULL) {
1029 		log_error("SSL_CTX_new: %s\n",
1030 		          ERR_error_string(ERR_peek_last_error(), NULL));
1031 		goto err_ssl_socket;
1032 	}
1033 
1034 	/* Load the OS default CA files */
1035 	if (!SSL_CTX_set_default_verify_paths(tunnel->ssl_context))
1036 		log_error("Could not load OS OpenSSL files.\n");
1037 
1038 	if (tunnel->config->ca_file) {
1039 		if (!SSL_CTX_load_verify_locations(tunnel->ssl_context,
1040 		                                   tunnel->config->ca_file, NULL)) {
1041 			log_error("SSL_CTX_load_verify_locations: %s\n",
1042 			          ERR_error_string(ERR_peek_last_error(), NULL));
1043 			goto err_ssl_context;
1044 		}
1045 	}
1046 
1047 	/* Disable vulnerable TLS protocols and ciphers by default*/
1048 	if (!tunnel->config->cipher_list) {
1049 		if (!tunnel->config->insecure_ssl) {
1050 			const char *cipher_list;
1051 
1052 			if (tunnel->config->seclevel_1)
1053 				cipher_list = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4@SECLEVEL=1";
1054 			else
1055 				cipher_list = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4";
1056 			tunnel->config->cipher_list = strdup(cipher_list);
1057 		} else if (tunnel->config->seclevel_1) {
1058 			const char *cipher_list = "DEFAULT@SECLEVEL=1";
1059 
1060 			tunnel->config->cipher_list = strdup(cipher_list);
1061 		}
1062 	}
1063 
1064 	/* Set the password callback for PEM certificates with encryption. */
1065 	SSL_CTX_set_default_passwd_cb(tunnel->ssl_context, &pem_passphrase_cb);
1066 	SSL_CTX_set_default_passwd_cb_userdata(tunnel->ssl_context, tunnel->config);
1067 
1068 	if (tunnel->config->cipher_list) {
1069 		log_debug("Setting cipher list to: %s\n", tunnel->config->cipher_list);
1070 		if (!SSL_CTX_set_cipher_list(tunnel->ssl_context,
1071 		                             tunnel->config->cipher_list)) {
1072 			log_error("SSL_CTX_set_cipher_list failed: %s\n",
1073 			          ERR_error_string(ERR_peek_last_error(), NULL));
1074 			goto err_ssl_context;
1075 		}
1076 	}
1077 
1078 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1079 	if (tunnel->config->min_tls > 0) {
1080 		log_debug("Setting minimum protocol version to: 0x%x.\n",
1081 		          tunnel->config->min_tls);
1082 		if (!SSL_CTX_set_min_proto_version(tunnel->ssl_context,
1083 		                                   tunnel->config->min_tls)) {
1084 			log_error("Cannot set minimum protocol version (%s).\n",
1085 			          ERR_error_string(ERR_peek_last_error(), NULL));
1086 			goto err_ssl_context;
1087 		}
1088 	}
1089 #else
1090 	if (!tunnel->config->insecure_ssl || tunnel->config->min_tls > 0) {
1091 		long sslctxopt = 0;
1092 		long checkopt;
1093 
1094 		if (!tunnel->config->insecure_ssl)
1095 			sslctxopt |= SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
1096 #ifdef TLS1_VERSION
1097 		if (tunnel->config->min_tls > TLS1_VERSION)
1098 			sslctxopt |= SSL_OP_NO_TLSv1;
1099 #endif
1100 #ifdef TLS1_1_VERSION
1101 		if (tunnel->config->min_tls > TLS1_1_VERSION)
1102 			sslctxopt |= SSL_OP_NO_TLSv1_1;
1103 #endif
1104 #ifdef TLS1_2_VERSION
1105 		if (tunnel->config->min_tls > TLS1_2_VERSION)
1106 			sslctxopt |= SSL_OP_NO_TLSv1_2;
1107 #endif
1108 		checkopt = SSL_CTX_set_options(tunnel->ssl_context, sslctxopt);
1109 		if ((checkopt & sslctxopt) != sslctxopt) {
1110 			log_error("SSL_CTX_set_options didn't set opt: %s\n",
1111 			          ERR_error_string(ERR_peek_last_error(), NULL));
1112 			goto err_ssl_context;
1113 		}
1114 	}
1115 #endif
1116 
1117 	/* Use engine for PIV if user-cert config starts with pkcs11 URI: */
1118 #ifndef OPENSSL_NO_ENGINE
1119 	if (tunnel->config->use_engine > 0) {
1120 		ENGINE *e;
1121 
1122 		ENGINE_load_builtin_engines();
1123 		e = ENGINE_by_id("pkcs11");
1124 		if (!e) {
1125 			log_error("Could not load pkcs11 Engine: %s\n",
1126 			          ERR_error_string(ERR_peek_last_error(), NULL));
1127 			goto err_ssl_context;
1128 		}
1129 		if (!ENGINE_init(e)) {
1130 			log_error("Could not init pkcs11 Engine: %s\n",
1131 			          ERR_error_string(ERR_peek_last_error(), NULL));
1132 			ENGINE_free(e);
1133 			goto err_ssl_context;
1134 		}
1135 		if (!ENGINE_set_default_RSA(e))
1136 			abort();
1137 
1138 		ENGINE_finish(e);
1139 		ENGINE_free(e);
1140 
1141 		struct token parms;
1142 
1143 		parms.uri = tunnel->config->user_cert;
1144 		parms.cert = NULL;
1145 
1146 		if (!ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1)) {
1147 			log_error("PKCS11 ENGINE_ctrl_cmd: %s\n",
1148 			          ERR_error_string(ERR_peek_last_error(), NULL));
1149 			goto err_ssl_context;
1150 		}
1151 
1152 		if (!SSL_CTX_use_certificate(tunnel->ssl_context, parms.cert)) {
1153 			log_error("PKCS11 SSL_CTX_use_certificate: %s\n",
1154 			          ERR_error_string(ERR_peek_last_error(), NULL));
1155 			goto err_ssl_context;
1156 		}
1157 
1158 		EVP_PKEY * privkey = ENGINE_load_private_key(
1159 		                             e, parms.uri, UI_OpenSSL(), NULL);
1160 		if (!privkey) {
1161 			log_error("PKCS11 ENGINE_load_private_key: %s\n",
1162 			          ERR_error_string(ERR_peek_last_error(), NULL));
1163 			goto err_ssl_context;
1164 		}
1165 
1166 		if (!SSL_CTX_use_PrivateKey(tunnel->ssl_context, privkey)) {
1167 			log_error("PKCS11 SSL_CTX_use_PrivateKey_file: %s\n",
1168 			          ERR_error_string(ERR_peek_last_error(), NULL));
1169 			goto err_ssl_context;
1170 		}
1171 
1172 		if (!SSL_CTX_check_private_key(tunnel->ssl_context)) {
1173 			log_error("PKCS11 SSL_CTX_check_private_key: %s\n",
1174 			          ERR_error_string(ERR_peek_last_error(), NULL));
1175 			goto err_ssl_context;
1176 		}
1177 
1178 	} else {        /* end PKCS11-engine */
1179 #endif
1180 
1181 		if (tunnel->config->user_cert) {
1182 			if (!SSL_CTX_use_certificate_chain_file(
1183 			            tunnel->ssl_context, tunnel->config->user_cert)) {
1184 				log_error("SSL_CTX_use_certificate_chain_file: %s\n",
1185 				          ERR_error_string(ERR_peek_last_error(), NULL));
1186 				goto err_ssl_context;
1187 			}
1188 		}
1189 
1190 		if (tunnel->config->user_key) {
1191 			if (!SSL_CTX_use_PrivateKey_file(tunnel->ssl_context,
1192 			                                 tunnel->config->user_key,
1193 			                                 SSL_FILETYPE_PEM)) {
1194 				log_error("SSL_CTX_use_PrivateKey_file: %s\n",
1195 				          ERR_error_string(ERR_peek_last_error(), NULL));
1196 				goto err_ssl_context;
1197 			}
1198 		}
1199 
1200 		if (tunnel->config->user_cert && tunnel->config->user_key) {
1201 			if (!SSL_CTX_check_private_key(tunnel->ssl_context)) {
1202 				log_error("SSL_CTX_check_private_key: %s\n",
1203 				          ERR_error_string(ERR_peek_last_error(), NULL));
1204 				goto err_ssl_context;
1205 			}
1206 		}
1207 #ifndef OPENSSL_NO_ENGINE
1208 	}
1209 #endif
1210 
1211 	tunnel->ssl_handle = SSL_new(tunnel->ssl_context);
1212 	if (tunnel->ssl_handle == NULL) {
1213 		log_error("SSL_new: %s\n",
1214 		          ERR_error_string(ERR_peek_last_error(), NULL));
1215 		goto err_ssl_context;
1216 	}
1217 
1218 	if (!SSL_set_fd(tunnel->ssl_handle, tunnel->ssl_socket)) {
1219 		log_error("SSL_set_fd: %s\n",
1220 		          ERR_error_string(ERR_peek_last_error(), NULL));
1221 		goto err_ssl_handle;
1222 	}
1223 	SSL_set_mode(tunnel->ssl_handle, SSL_MODE_AUTO_RETRY);
1224 
1225 	// Initiate SSL handshake
1226 	if (SSL_connect(tunnel->ssl_handle) != 1) {
1227 		log_error("SSL_connect: %s\n"
1228 		          "You might want to try --insecure-ssl or specify a different --cipher-list\n",
1229 		          ERR_error_string(ERR_peek_last_error(), NULL));
1230 		goto err_ssl_handle;
1231 	}
1232 	SSL_set_mode(tunnel->ssl_handle, SSL_MODE_AUTO_RETRY);
1233 
1234 	if (ssl_verify_cert(tunnel))
1235 		goto err_ssl_handle;
1236 
1237 	// Disable SIGPIPE (occurs when trying to write to an already-closed
1238 	// socket).
1239 	signal(SIGPIPE, SIG_IGN);
1240 
1241 	return 0;
1242 
1243 err_ssl_handle:
1244 	SSL_shutdown(tunnel->ssl_handle);
1245 	SSL_free(tunnel->ssl_handle);
1246 	tunnel->ssl_handle = NULL;
1247 err_ssl_context:
1248 	SSL_CTX_free(tunnel->ssl_context);
1249 	tunnel->ssl_context = NULL;
1250 err_ssl_socket:
1251 	if (close(tunnel->ssl_socket))
1252 		log_warn("Could not close ssl socket (%s).\n", strerror(errno));
1253 	tunnel->ssl_socket = -1;
1254 err_tcp_connect:
1255 	return 1;
1256 }
1257 
run_tunnel(struct vpn_config * config)1258 int run_tunnel(struct vpn_config *config)
1259 {
1260 	int ret;
1261 	struct tunnel tunnel = {
1262 		.config = config,
1263 		.state = STATE_DOWN,
1264 		.ssl_socket = -1,
1265 		.ssl_context = NULL,
1266 		.ssl_handle = NULL,
1267 		.ipv4.ns1_addr.s_addr = 0,
1268 		.ipv4.ns2_addr.s_addr = 0,
1269 		.ipv4.dns_suffix = NULL,
1270 		.on_ppp_if_up = on_ppp_if_up,
1271 		.on_ppp_if_down = on_ppp_if_down
1272 	};
1273 
1274 	// Step 0: get gateway host IP
1275 	log_debug("Resolving gateway host ip\n");
1276 	ret = get_gateway_host_ip(&tunnel);
1277 	if (ret)
1278 		goto err_tunnel;
1279 
1280 	// Step 1: open a SSL connection to the gateway
1281 	log_debug("Establishing ssl connection\n");
1282 	ret = ssl_connect(&tunnel);
1283 	if (ret)
1284 		goto err_tunnel;
1285 	log_info("Connected to gateway.\n");
1286 
1287 	// Step 2: connect to the HTTP interface and authenticate to get a
1288 	// cookie
1289 	ret = auth_log_in(&tunnel);
1290 	if (ret != 1) {
1291 		log_error("Could not authenticate to gateway. Please check the password, client certificate, etc.\n");
1292 		log_debug("%s (%d)\n", err_http_str(ret), ret);
1293 		ret = 1;
1294 		goto err_tunnel;
1295 	}
1296 	log_info("Authenticated.\n");
1297 	log_debug("Cookie: %s\n", tunnel.cookie);
1298 
1299 	ret = auth_request_vpn_allocation(&tunnel);
1300 	if (ret != 1) {
1301 		log_error("VPN allocation request failed (%s).\n",
1302 		          err_http_str(ret));
1303 		ret = 1;
1304 		goto err_tunnel;
1305 	}
1306 	log_info("Remote gateway has allocated a VPN.\n");
1307 
1308 	ret = ssl_connect(&tunnel);
1309 	if (ret)
1310 		goto err_tunnel;
1311 
1312 	// Step 3: get configuration
1313 	log_debug("Retrieving configuration\n");
1314 	ret = auth_get_config(&tunnel);
1315 	if (ret != 1) {
1316 		log_error("Could not get VPN configuration (%s).\n",
1317 		          err_http_str(ret));
1318 		ret = 1;
1319 		goto err_tunnel;
1320 	}
1321 
1322 	// Step 4: run a pppd process
1323 	log_debug("Establishing the tunnel\n");
1324 	ret = pppd_run(&tunnel);
1325 	if (ret)
1326 		goto err_tunnel;
1327 
1328 	// Step 5: ask gateway to start tunneling
1329 	log_debug("Switch to tunneling mode\n");
1330 	ret = http_send(&tunnel,
1331 	                "GET /remote/sslvpn-tunnel HTTP/1.1\r\n"
1332 	                "Host: sslvpn\r\n"
1333 	                "Cookie: %s\r\n\r\n",
1334 	                tunnel.cookie);
1335 	if (ret != 1) {
1336 		log_error("Could not start tunnel (%s).\n", err_http_str(ret));
1337 		goto err_start_tunnel;
1338 	}
1339 
1340 	tunnel.state = STATE_CONNECTING;
1341 
1342 	// Step 6: perform io between pppd and the gateway, while tunnel is up
1343 	log_debug("Starting IO through the tunnel\n");
1344 	io_loop(&tunnel);
1345 
1346 	log_debug("disconnecting\n");
1347 	if (tunnel.state == STATE_UP)
1348 		if (tunnel.on_ppp_if_down != NULL)
1349 			tunnel.on_ppp_if_down(&tunnel);
1350 
1351 	tunnel.state = STATE_DISCONNECTING;
1352 
1353 err_start_tunnel:
1354 	ret = pppd_terminate(&tunnel);
1355 	log_info("Terminated %s.\n", PPP_DAEMON);
1356 err_tunnel:
1357 	log_info("Closed connection to gateway.\n");
1358 	tunnel.state = STATE_DOWN;
1359 
1360 	if (ssl_connect(&tunnel)) {
1361 		log_info("Could not log out.\n");
1362 	} else {
1363 		auth_log_out(&tunnel);
1364 		log_info("Logged out.\n");
1365 	}
1366 
1367 	// explicitly free the buffer allocated for split routes of the ipv4 configuration
1368 	if (tunnel.ipv4.split_rt != NULL) {
1369 		free(tunnel.ipv4.split_rt);
1370 		tunnel.ipv4.split_rt = NULL;
1371 	}
1372 	return ret;
1373 }
1374