1 /* $OpenBSD: iked.c,v 1.64 2023/03/05 22:17:22 tobhe Exp $ */ 2 3 /* 4 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de> 5 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/queue.h> 21 #include <sys/socket.h> 22 #include <sys/wait.h> 23 #include <sys/uio.h> 24 25 #include <stdlib.h> 26 #include <stdio.h> 27 #include <unistd.h> 28 #include <string.h> 29 #include <getopt.h> 30 #include <signal.h> 31 #include <syslog.h> 32 #include <errno.h> 33 #include <err.h> 34 #include <pwd.h> 35 #include <event.h> 36 37 #include "iked.h" 38 #include "ikev2.h" 39 #include "version.h" 40 41 __dead void usage(void); 42 43 void parent_shutdown(struct iked *); 44 void parent_sig_handler(int, short, void *); 45 int parent_dispatch_ca(int, struct privsep_proc *, struct imsg *); 46 int parent_dispatch_control(int, struct privsep_proc *, struct imsg *); 47 int parent_dispatch_ikev2(int, struct privsep_proc *, struct imsg *); 48 int parent_configure(struct iked *); 49 50 struct iked *iked_env; 51 52 static struct privsep_proc procs[] = { 53 { "ca", PROC_CERT, parent_dispatch_ca, caproc, IKED_CA }, 54 { "control", PROC_CONTROL, parent_dispatch_control, control }, 55 { "ikev2", PROC_IKEV2, parent_dispatch_ikev2, ikev2 } 56 }; 57 58 __dead void 59 usage(void) 60 { 61 extern char *__progname; 62 63 fprintf(stderr, "usage: %s [-dnSTtVv] [-D macro=value] " 64 "[-f file] [-p udpencap_port] [-s socket]\n", __progname); 65 exit(1); 66 } 67 68 int 69 main(int argc, char *argv[]) 70 { 71 int c; 72 int debug = 0, verbose = 0; 73 int opts = 0; 74 enum natt_mode natt_mode = NATT_DEFAULT; 75 in_port_t port = IKED_NATT_PORT; 76 const char *conffile = IKED_CONFIG; 77 const char *sock = IKED_SOCKET; 78 const char *errstr, *title = NULL; 79 struct iked *env = NULL; 80 struct privsep *ps; 81 enum privsep_procid proc_id = PROC_PARENT; 82 int proc_instance = 0; 83 int argc0 = argc; 84 85 log_init(1, LOG_DAEMON); 86 87 while ((c = getopt(argc, argv, "6D:df:I:nP:p:Ss:TtvV")) != -1) { 88 switch (c) { 89 case '6': 90 log_warnx("the -6 option is ignored and will be " 91 "removed in the future."); 92 break; 93 case 'D': 94 if (cmdline_symset(optarg) < 0) 95 log_warnx("could not parse macro definition %s", 96 optarg); 97 break; 98 case 'd': 99 debug++; 100 break; 101 case 'f': 102 conffile = optarg; 103 break; 104 case 'I': 105 proc_instance = strtonum(optarg, 0, 106 PROC_MAX_INSTANCES, &errstr); 107 if (errstr) 108 fatalx("invalid process instance"); 109 break; 110 case 'n': 111 debug = 1; 112 opts |= IKED_OPT_NOACTION; 113 break; 114 case 'P': 115 title = optarg; 116 proc_id = proc_getid(procs, nitems(procs), title); 117 if (proc_id == PROC_MAX) 118 fatalx("invalid process name"); 119 break; 120 case 'p': 121 if (natt_mode == NATT_DISABLE) 122 errx(1, "-T and -p are mutually exclusive"); 123 port = strtonum(optarg, 1, UINT16_MAX, &errstr); 124 if (errstr != NULL) 125 errx(1, "port is %s: %s", errstr, optarg); 126 natt_mode = NATT_FORCE; 127 break; 128 case 'S': 129 opts |= IKED_OPT_PASSIVE; 130 break; 131 case 's': 132 sock = optarg; 133 break; 134 case 'T': 135 if (natt_mode == NATT_FORCE) 136 errx(1, "-T and -t/-p are mutually exclusive"); 137 natt_mode = NATT_DISABLE; 138 break; 139 case 't': 140 if (natt_mode == NATT_DISABLE) 141 errx(1, "-T and -t are mutually exclusive"); 142 natt_mode = NATT_FORCE; 143 break; 144 case 'v': 145 verbose++; 146 opts |= IKED_OPT_VERBOSE; 147 break; 148 case 'V': 149 fprintf(stderr, "OpenIKED %s\n", IKED_VERSION); 150 return 0; 151 default: 152 usage(); 153 } 154 } 155 156 /* log to stderr until daemonized */ 157 log_init(debug ? debug : 1, LOG_DAEMON); 158 159 argc -= optind; 160 if (argc > 0) 161 usage(); 162 163 if ((env = calloc(1, sizeof(*env))) == NULL) 164 fatal("calloc: env"); 165 166 iked_env = env; 167 env->sc_opts = opts; 168 env->sc_nattmode = natt_mode; 169 env->sc_nattport = port; 170 171 ps = &env->sc_ps; 172 ps->ps_env = env; 173 TAILQ_INIT(&ps->ps_rcsocks); 174 175 if (strlcpy(env->sc_conffile, conffile, PATH_MAX) >= PATH_MAX) 176 errx(1, "config file exceeds PATH_MAX"); 177 178 ca_sslinit(); 179 group_init(); 180 policy_init(env); 181 182 /* check for root privileges */ 183 if (geteuid()) 184 errx(1, "need root privileges"); 185 186 if ((ps->ps_pw = getpwnam(IKED_USER)) == NULL) 187 errx(1, "unknown user %s", IKED_USER); 188 189 /* Configure the control socket */ 190 ps->ps_csock.cs_name = sock; 191 192 log_init(debug, LOG_DAEMON); 193 log_setverbose(verbose); 194 195 if (opts & IKED_OPT_NOACTION) 196 ps->ps_noaction = 1; 197 198 ps->ps_instance = proc_instance; 199 if (title != NULL) 200 ps->ps_title[proc_id] = title; 201 202 /* only the parent returns */ 203 proc_init(ps, procs, nitems(procs), debug, argc0, argv, proc_id); 204 205 setproctitle("parent"); 206 log_procinit("parent"); 207 if (!debug && daemon(0, 0) == -1) 208 err(1, "failed to daemonize"); 209 210 event_init(); 211 212 signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps); 213 signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps); 214 signal_set(&ps->ps_evsigchld, SIGCHLD, parent_sig_handler, ps); 215 signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps); 216 signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps); 217 signal_set(&ps->ps_evsigusr1, SIGUSR1, parent_sig_handler, ps); 218 219 signal_add(&ps->ps_evsigint, NULL); 220 signal_add(&ps->ps_evsigterm, NULL); 221 signal_add(&ps->ps_evsigchld, NULL); 222 signal_add(&ps->ps_evsighup, NULL); 223 signal_add(&ps->ps_evsigpipe, NULL); 224 signal_add(&ps->ps_evsigusr1, NULL); 225 226 proc_connect(ps); 227 228 vroute_init(env); 229 230 if (parent_configure(env) == -1) 231 fatalx("configuration failed"); 232 233 event_dispatch(); 234 235 log_debug("%d parent exiting", getpid()); 236 parent_shutdown(env); 237 238 return (0); 239 } 240 241 int 242 parent_configure(struct iked *env) 243 { 244 struct sockaddr_storage ss; 245 246 if (parse_config(env->sc_conffile, env) == -1) { 247 proc_kill(&env->sc_ps); 248 exit(1); 249 } 250 251 if (env->sc_opts & IKED_OPT_NOACTION) { 252 fprintf(stderr, "configuration OK\n"); 253 proc_kill(&env->sc_ps); 254 exit(0); 255 } 256 257 env->sc_pfkey = -1; 258 config_setpfkey(env); 259 260 /* Send private and public keys to cert after forking the children */ 261 if (config_setkeys(env) == -1) 262 fatalx("%s: failed to send keys", __func__); 263 config_setreset(env, RESET_CA, PROC_CERT); 264 265 /* Now compile the policies and calculate skip steps */ 266 config_setcompile(env, PROC_IKEV2); 267 268 bzero(&ss, sizeof(ss)); 269 ss.ss_family = AF_INET; 270 271 /* see comment on config_setsocket() */ 272 if (env->sc_nattmode != NATT_FORCE) 273 config_setsocket(env, &ss, htons(IKED_IKE_PORT), PROC_IKEV2); 274 if (env->sc_nattmode != NATT_DISABLE) 275 config_setsocket(env, &ss, htons(env->sc_nattport), PROC_IKEV2); 276 277 bzero(&ss, sizeof(ss)); 278 ss.ss_family = AF_INET6; 279 280 if (env->sc_nattmode != NATT_FORCE) 281 config_setsocket(env, &ss, htons(IKED_IKE_PORT), PROC_IKEV2); 282 if (env->sc_nattmode != NATT_DISABLE) 283 config_setsocket(env, &ss, htons(env->sc_nattport), PROC_IKEV2); 284 285 /* 286 * pledge in the parent process: 287 * It has to run fairly late to allow forking the processes and 288 * opening the PFKEY socket and the listening UDP sockets (once) 289 * that need the bypass ioctls that are never allowed by pledge. 290 * 291 * Other flags: 292 * stdio - for malloc and basic I/O including events. 293 * rpath - for reload to open and read the configuration files. 294 * proc - run kill to terminate its children safely. 295 * dns - for reload and ocsp connect. 296 * inet - for ocsp connect. 297 * route - for using interfaces in iked.conf (SIOCGIFGMEMB) 298 * wroute - for adding and removing addresses (SIOCAIFGMEMB) 299 * sendfd - for ocsp sockets. 300 */ 301 if (pledge("stdio rpath proc dns inet route wroute sendfd", NULL) == -1) 302 fatal("pledge"); 303 304 config_setstatic(env); 305 config_setcoupled(env, env->sc_decoupled ? 0 : 1); 306 config_setocsp(env); 307 config_setcertpartialchain(env); 308 /* Must be last */ 309 config_setmode(env, env->sc_passive ? 1 : 0); 310 311 return (0); 312 } 313 314 void 315 parent_reload(struct iked *env, int reset, const char *filename) 316 { 317 /* Switch back to the default config file */ 318 if (filename == NULL || *filename == '\0') 319 filename = env->sc_conffile; 320 321 log_debug("%s: level %d config file %s", __func__, reset, filename); 322 323 if (reset == RESET_RELOAD) { 324 config_setreset(env, RESET_POLICY, PROC_IKEV2); 325 if (config_setkeys(env) == -1) 326 fatalx("%s: failed to send keys", __func__); 327 config_setreset(env, RESET_CA, PROC_CERT); 328 329 if (parse_config(filename, env) == -1) { 330 log_debug("%s: failed to load config file %s", 331 __func__, filename); 332 } 333 334 /* Re-compile policies and skip steps */ 335 config_setcompile(env, PROC_IKEV2); 336 337 config_setstatic(env); 338 config_setcoupled(env, env->sc_decoupled ? 0 : 1); 339 config_setocsp(env); 340 config_setcertpartialchain(env); 341 /* Must be last */ 342 config_setmode(env, env->sc_passive ? 1 : 0); 343 } else { 344 config_setreset(env, reset, PROC_IKEV2); 345 config_setreset(env, reset, PROC_CERT); 346 } 347 } 348 349 void 350 parent_sig_handler(int sig, short event, void *arg) 351 { 352 struct privsep *ps = arg; 353 int die = 0, status, fail, id; 354 pid_t pid; 355 char *cause; 356 357 switch (sig) { 358 case SIGHUP: 359 log_info("%s: reload requested with SIGHUP", __func__); 360 361 /* 362 * This is safe because libevent uses async signal handlers 363 * that run in the event loop and not in signal context. 364 */ 365 parent_reload(ps->ps_env, 0, NULL); 366 break; 367 case SIGPIPE: 368 log_info("%s: ignoring SIGPIPE", __func__); 369 break; 370 case SIGUSR1: 371 log_info("%s: ignoring SIGUSR1", __func__); 372 break; 373 case SIGTERM: 374 case SIGINT: 375 die = 1; 376 /* FALLTHROUGH */ 377 case SIGCHLD: 378 do { 379 int len = 0; 380 381 pid = waitpid(-1, &status, WNOHANG); 382 if (pid <= 0) 383 continue; 384 385 fail = 0; 386 if (WIFSIGNALED(status)) { 387 fail = 1; 388 len = asprintf(&cause, "terminated; signal %d", 389 WTERMSIG(status)); 390 } else if (WIFEXITED(status)) { 391 if (WEXITSTATUS(status) != 0) { 392 fail = 1; 393 len = asprintf(&cause, 394 "exited abnormally"); 395 } else 396 len = asprintf(&cause, "exited okay"); 397 } else 398 fatalx("unexpected cause of SIGCHLD"); 399 400 if (len == -1) 401 fatal("asprintf"); 402 403 die = 1; 404 405 for (id = 0; id < PROC_MAX; id++) 406 if (pid == ps->ps_pid[id]) { 407 if (fail) 408 log_warnx("lost child: %s %s", 409 ps->ps_title[id], cause); 410 break; 411 } 412 413 free(cause); 414 } while (pid > 0 || (pid == -1 && errno == EINTR)); 415 416 if (die) 417 parent_shutdown(ps->ps_env); 418 break; 419 default: 420 fatalx("unexpected signal"); 421 } 422 } 423 424 int 425 parent_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg) 426 { 427 struct iked *env = iked_env; 428 429 switch (imsg->hdr.type) { 430 case IMSG_OCSP_FD: 431 ocsp_connect(env, imsg); 432 break; 433 default: 434 return (-1); 435 } 436 437 return (0); 438 } 439 440 int 441 parent_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) 442 { 443 struct iked *env = iked_env; 444 int v; 445 char *str = NULL; 446 unsigned int type = imsg->hdr.type; 447 448 switch (type) { 449 case IMSG_CTL_RESET: 450 IMSG_SIZE_CHECK(imsg, &v); 451 memcpy(&v, imsg->data, sizeof(v)); 452 parent_reload(env, v, NULL); 453 break; 454 case IMSG_CTL_COUPLE: 455 case IMSG_CTL_DECOUPLE: 456 case IMSG_CTL_ACTIVE: 457 case IMSG_CTL_PASSIVE: 458 proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0); 459 break; 460 case IMSG_CTL_RELOAD: 461 if (IMSG_DATA_SIZE(imsg) > 0) 462 str = get_string(imsg->data, IMSG_DATA_SIZE(imsg)); 463 parent_reload(env, 0, str); 464 free(str); 465 break; 466 case IMSG_CTL_VERBOSE: 467 proc_forward_imsg(&env->sc_ps, imsg, PROC_IKEV2, -1); 468 proc_forward_imsg(&env->sc_ps, imsg, PROC_CERT, -1); 469 470 /* return 1 to let proc.c handle it locally */ 471 return (1); 472 default: 473 return (-1); 474 } 475 476 return (0); 477 } 478 479 int 480 parent_dispatch_ikev2(int fd, struct privsep_proc *p, struct imsg *imsg) 481 { 482 struct iked *env = iked_env; 483 484 switch (imsg->hdr.type) { 485 case IMSG_IF_ADDADDR: 486 case IMSG_IF_DELADDR: 487 return (vroute_getaddr(env, imsg)); 488 case IMSG_VDNS_ADD: 489 case IMSG_VDNS_DEL: 490 return (vroute_getdns(env, imsg)); 491 case IMSG_VROUTE_ADD: 492 case IMSG_VROUTE_DEL: 493 return (vroute_getroute(env, imsg)); 494 case IMSG_VROUTE_CLONE: 495 return (vroute_getcloneroute(env, imsg)); 496 default: 497 return (-1); 498 } 499 500 return (0); 501 } 502 503 void 504 parent_shutdown(struct iked *env) 505 { 506 proc_kill(&env->sc_ps); 507 508 vroute_cleanup(env); 509 free(env->sc_vroute); 510 free(env); 511 512 log_warnx("parent terminating"); 513 exit(0); 514 } 515