xref: /openbsd/sbin/isakmpd/isakmpd.c (revision 274d7c50)
1 /* $OpenBSD: isakmpd.c,v 1.107 2018/01/15 09:54:48 mpi Exp $	 */
2 /* $EOM: isakmpd.c,v 1.54 2000/10/05 09:28:22 niklas Exp $	 */
3 
4 /*
5  * Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist.  All rights reserved.
6  * Copyright (c) 1999, 2000 Angelos D. Keromytis.  All rights reserved.
7  * Copyright (c) 1999, 2000, 2001 H�kan Olsson.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * This code was written under funding by Ericsson Radio Systems.
32  */
33 
34 #include <errno.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <signal.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <time.h>
42 #include <netdb.h>
43 #include <unistd.h>
44 #include <fcntl.h>
45 #include <paths.h>
46 
47 #include "app.h"
48 #include "conf.h"
49 #include "connection.h"
50 #include "init.h"
51 #include "libcrypto.h"
52 #include "log.h"
53 #include "message.h"
54 #include "monitor.h"
55 #include "nat_traversal.h"
56 #include "sa.h"
57 #include "timer.h"
58 #include "transport.h"
59 #include "udp.h"
60 #include "udp_encap.h"
61 #include "ui.h"
62 #include "util.h"
63 #include "cert.h"
64 
65 #include "policy.h"
66 
67 static void     usage(void);
68 
69 /*
70  * Set if -d is given, currently just for running in the foreground and log
71  * to stderr instead of syslog.
72  */
73 int             debug = 0;
74 
75 /* Set when no policy file shall be used. */
76 int		acquire_only = 0;
77 
78 /* Set when SAs shall be deleted on shutdown. */
79 int		delete_sas = 1;
80 
81 /*
82  * If we receive a SIGHUP signal, this flag gets set to show we need to
83  * reconfigure ASAP.
84  */
85 volatile sig_atomic_t sighupped = 0;
86 
87 /*
88  * If we receive a USR1 signal, this flag gets set to show we need to dump
89  * a report over our internal state ASAP.  The file to report to is settable
90  * via the -R parameter.
91  */
92 volatile sig_atomic_t sigusr1ed = 0;
93 static char    *report_file = "/var/run/isakmpd.report";
94 
95 /*
96  * If we receive a TERM signal, perform a "clean shutdown" of the daemon.
97  * This includes to send DELETE notifications for all our active SAs.
98  * Also on recv of an INT signal (Ctrl-C out of an '-d' session, typically).
99  */
100 volatile sig_atomic_t sigtermed = 0;
101 void            daemon_shutdown_now(int);
102 void		set_slave_signals(void);
103 void		sanitise_stdfd(void);
104 
105 /* The default path of the PID file.  */
106 char	       *pid_file = "/var/run/isakmpd.pid";
107 
108 /* The path of the IKE packet capture log file.  */
109 static char    *pcap_file = 0;
110 
111 static void
112 usage(void)
113 {
114 	extern char *__progname;
115 
116 	fprintf(stderr,
117 	    "usage: %s [-46adKLnSTv] [-c config-file] [-D class=level] [-f fifo]\n"
118 	    "          [-i pid-file] [-l packetlog-file] [-N udpencap-port]\n"
119 	    "          [-p listen-port] [-R report-file]\n",
120 	    __progname);
121 	exit(1);
122 }
123 
124 static void
125 parse_args(int argc, char *argv[])
126 {
127 	int             ch;
128 	int             cls, level;
129 	int             do_packetlog = 0;
130 
131 	while ((ch = getopt(argc, argv, "46ac:dD:f:i:KnN:p:Ll:R:STv")) != -1) {
132 		switch (ch) {
133 		case '4':
134 			bind_family |= BIND_FAMILY_INET4;
135 			break;
136 
137 		case '6':
138 			bind_family |= BIND_FAMILY_INET6;
139 			break;
140 
141 		case 'a':
142 			acquire_only = 1;
143 			break;
144 
145 		case 'c':
146 			conf_path = optarg;
147 			break;
148 
149 		case 'd':
150 			debug++;
151 			break;
152 
153 		case 'D':
154 			if (sscanf(optarg, "%d=%d", &cls, &level) != 2) {
155 				if (sscanf(optarg, "A=%d", &level) == 1) {
156 					for (cls = 0; cls < LOG_ENDCLASS;
157 					    cls++)
158 						log_debug_cmd(cls, level);
159 				} else
160 					log_print("parse_args: -D argument "
161 					    "unparseable: %s", optarg);
162 			} else
163 				log_debug_cmd(cls, level);
164 			break;
165 
166 		case 'f':
167 			ui_fifo = optarg;
168 			break;
169 
170 		case 'i':
171 			pid_file = optarg;
172 			break;
173 
174 		case 'K':
175 			ignore_policy++;
176 			break;
177 
178 		case 'n':
179 			app_none++;
180 			break;
181 
182 		case 'N':
183 			udp_encap_default_port = optarg;
184 			break;
185 
186 		case 'p':
187 			udp_default_port = optarg;
188 			break;
189 
190 		case 'l':
191 			pcap_file = optarg;
192 			/* FALLTHROUGH */
193 
194 		case 'L':
195 			do_packetlog++;
196 			break;
197 
198 		case 'R':
199 			report_file = optarg;
200 			break;
201 
202 		case 'S':
203 			delete_sas = 0;
204 			ui_daemon_passive = 1;
205 			break;
206 
207 		case 'T':
208 			disable_nat_t = 1;
209 			break;
210 
211 		case 'v':
212 			verbose_logging = 1;
213 			break;
214 
215 		case '?':
216 		default:
217 			usage();
218 		}
219 	}
220 	argc -= optind;
221 	argv += optind;
222 
223 	if (argc > 0)
224 		usage();
225 
226 	if (do_packetlog && !pcap_file)
227 		pcap_file = PCAP_FILE_DEFAULT;
228 }
229 
230 /* ARGSUSED */
231 static void
232 sighup(int sig)
233 {
234 	sighupped = 1;
235 }
236 
237 /* Report internal state on SIGUSR1.  */
238 static void
239 report(void)
240 {
241 	FILE	*rfp, *old;
242 	mode_t	old_umask;
243 
244 	old_umask = umask(S_IRWXG | S_IRWXO);
245 	rfp = monitor_fopen(report_file, "w");
246 	umask(old_umask);
247 
248 	if (!rfp) {
249 		log_error("report: fopen (\"%s\", \"w\") failed", report_file);
250 		return;
251 	}
252 	/* Divert the log channel to the report file during the report.  */
253 	old = log_current();
254 	log_to(rfp);
255 	ui_report("r");
256 	log_to(old);
257 	fclose(rfp);
258 }
259 
260 static void
261 sigusr1(int sig)
262 {
263 	sigusr1ed = 1;
264 }
265 
266 static int
267 phase2_sa_check(struct sa *sa, void *arg)
268 {
269 	return sa->phase == 2;
270 }
271 
272 static int
273 phase1_sa_check(struct sa *sa, void *arg)
274 {
275 	return sa->phase == 1;
276 }
277 
278 void
279 set_slave_signals(void)
280 {
281 	int n;
282 
283 	for (n = 1; n < _NSIG; n++)
284 		signal(n, SIG_DFL);
285 
286 	/*
287 	 * Do a clean daemon shutdown on TERM/INT. These signals must be
288 	 * initialized before monitor_init(). INT is only used with '-d'.
289 	 */
290 	signal(SIGTERM, daemon_shutdown_now);
291 	if (debug == 1)		/* i.e '-dd' will skip this.  */
292 		signal(SIGINT, daemon_shutdown_now);
293 
294 	/* Reinitialize on HUP reception.  */
295 	signal(SIGHUP, sighup);
296 
297 	/* Report state on USR1 reception.  */
298 	signal(SIGUSR1, sigusr1);
299 }
300 
301 static void
302 daemon_shutdown(void)
303 {
304 	/* Perform a (protocol-wise) clean shutdown of the daemon.  */
305 	struct sa	*sa;
306 
307 	if (sigtermed == 1) {
308 		log_print("isakmpd: shutting down...");
309 
310 		if (delete_sas &&
311 		    strncmp("no", conf_get_str("General", "Delete-SAs"), 2)) {
312 			/*
313 			 * Delete all active SAs.  First IPsec SAs, then
314 			 * ISAKMPD.  Each DELETE is another (outgoing) message.
315 			 */
316 			while ((sa = sa_find(phase2_sa_check, NULL)))
317 				sa_delete(sa, 1);
318 
319 			while ((sa = sa_find(phase1_sa_check, NULL)))
320 				sa_delete(sa, 1);
321 		}
322 
323 		/* We only want to do this once. */
324 		sigtermed++;
325 	}
326 	if (transport_prio_sendqs_empty()) {
327 		/*
328 		 * When the prioritized transport sendq:s are empty, i.e all
329 		 * the DELETE notifications have been sent, we can shutdown.
330 		 */
331 
332 		log_packet_stop();
333 		log_print("isakmpd: exit");
334 		exit(0);
335 	}
336 }
337 
338 /* Called on SIGTERM, SIGINT or by ui_shutdown_daemon().  */
339 /* ARGSUSED */
340 void
341 daemon_shutdown_now(int sig)
342 {
343 	sigtermed = 1;
344 }
345 
346 /* Write pid file.  */
347 static void
348 write_pid_file(void)
349 {
350 	FILE	*fp;
351 
352 	unlink(pid_file);
353 
354 	fp = fopen(pid_file, "w");
355 	if (fp != NULL) {
356 		if (fprintf(fp, "%ld\n", (long) getpid()) < 0)
357 			log_error("write_pid_file: failed to write PID to "
358 			    "\"%.100s\"", pid_file);
359 		fclose(fp);
360 	} else
361 		log_fatal("write_pid_file: fopen (\"%.100s\", \"w\") failed",
362 		    pid_file);
363 }
364 
365 void
366 sanitise_stdfd(void)
367 {
368 	int nullfd, dupfd;
369 
370 	if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
371 		fprintf(stderr, "Couldn't open /dev/null: %s\n",
372 		    strerror(errno));
373 		exit(1);
374 	}
375 	while (++dupfd <= STDERR_FILENO) {
376 		/* Only populate closed fds */
377 		if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) {
378 			if (dup2(nullfd, dupfd) == -1) {
379 				fprintf(stderr, "dup2: %s\n", strerror(errno));
380 				exit(1);
381 			}
382 		}
383 	}
384 	if (nullfd > STDERR_FILENO)
385 		close(nullfd);
386 }
387 
388 int
389 main(int argc, char *argv[])
390 {
391 	fd_set         *rfds, *wfds;
392 	int             n, m;
393 	size_t          mask_size;
394 	struct timespec ts, *timeout;
395 
396 	closefrom(STDERR_FILENO + 1);
397 
398 	/*
399 	 * Make sure init() won't alloc fd 0, 1 or 2, as daemon() will close
400 	 * them.
401 	 */
402 	sanitise_stdfd();
403 
404 	/* Log cmd line parsing and initialization errors to stderr.  */
405 	log_to(stderr);
406 	parse_args(argc, argv);
407 	log_init(debug);
408 	log_print("isakmpd: starting");
409 
410 	/* Open protocols and services databases.  */
411 	setprotoent(1);
412 	setservent(1);
413 
414 	/* Open command fifo */
415 	ui_init();
416 
417 	set_slave_signals();
418 	/* Daemonize before forking unpriv'ed child */
419 	if (!debug)
420 		if (daemon(0, 0))
421 			log_fatal("main: daemon (0, 0) failed");
422 
423 	/* Set timezone before priv'separation */
424 	tzset();
425 
426 	write_pid_file();
427 
428 	if (monitor_init(debug)) {
429 		/* The parent, with privileges enters infinite monitor loop. */
430 		monitor_loop(debug);
431 		exit(0);	/* Never reached.  */
432 	}
433 	/* Child process only from this point on, no privileges left.  */
434 
435 	init();
436 
437 	/* If we wanted IKE packet capture to file, initialize it now.  */
438 	if (pcap_file != 0)
439 		log_packet_init(pcap_file);
440 
441 	/* Allocate the file descriptor sets just big enough.  */
442 	n = getdtablesize();
443 	mask_size = howmany(n, NFDBITS) * sizeof(fd_mask);
444 	rfds = malloc(mask_size);
445 	if (!rfds)
446 		log_fatal("main: malloc (%lu) failed",
447 		    (unsigned long)mask_size);
448 	wfds = malloc(mask_size);
449 	if (!wfds)
450 		log_fatal("main: malloc (%lu) failed",
451 		    (unsigned long)mask_size);
452 
453 	monitor_init_done();
454 
455 	while (1) {
456 		/* If someone has sent SIGHUP to us, reconfigure.  */
457 		if (sighupped) {
458 			sighupped = 0;
459 			log_print("SIGHUP received");
460 			reinit();
461 		}
462 		/* and if someone sent SIGUSR1, do a state report.  */
463 		if (sigusr1ed) {
464 			sigusr1ed = 0;
465 			log_print("SIGUSR1 received");
466 			report();
467 		}
468 		/*
469 		 * and if someone set 'sigtermed' (SIGTERM, SIGINT or via the
470 		 * UI), this indicates we should start a controlled shutdown
471 		 * of the daemon.
472 		 *
473 		 * Note: Since _one_ message is sent per iteration of this
474 		 * enclosing while-loop, and we want to send a number of
475 		 * DELETE notifications, we must loop atleast this number of
476 		 * times. The daemon_shutdown() function starts by queueing
477 		 * the DELETEs, all other calls just increments the
478 		 * 'sigtermed' variable until it reaches a "safe" value, and
479 		 * the daemon exits.
480 		 */
481 		if (sigtermed)
482 			daemon_shutdown();
483 
484 		/* Setup the descriptors to look for incoming messages at.  */
485 		bzero(rfds, mask_size);
486 		n = transport_fd_set(rfds);
487 		FD_SET(ui_socket, rfds);
488 		if (ui_socket + 1 > n)
489 			n = ui_socket + 1;
490 
491 		/*
492 		 * XXX Some day we might want to deal with an abstract
493 		 * application class instead, with many instantiations
494 		 * possible.
495 		 */
496 		if (!app_none && app_socket >= 0) {
497 			FD_SET(app_socket, rfds);
498 			if (app_socket + 1 > n)
499 				n = app_socket + 1;
500 		}
501 		/* Setup the descriptors that have pending messages to send. */
502 		bzero(wfds, mask_size);
503 		m = transport_pending_wfd_set(wfds);
504 		if (m > n)
505 			n = m;
506 
507 		/* Find out when the next timed event is.  */
508 		timeout = &ts;
509 		timer_next_event(&timeout);
510 
511 		n = pselect(n, rfds, wfds, NULL, timeout, NULL);
512 		if (n == -1) {
513 			if (errno != EINTR) {
514 				log_error("main: select");
515 
516 				/*
517 				 * In order to give the unexpected error
518 				 * condition time to resolve without letting
519 				 * this process eat up all available CPU
520 				 * we sleep for a short while.
521 				 */
522 				sleep(1);
523 			}
524 		} else if (n) {
525 			transport_handle_messages(rfds);
526 			transport_send_messages(wfds);
527 			if (FD_ISSET(ui_socket, rfds))
528 				ui_handler();
529 			if (!app_none && app_socket >= 0 &&
530 			    FD_ISSET(app_socket, rfds))
531 				app_handler();
532 		}
533 		timer_handle_expirations();
534 	}
535 }
536