1 /* $OpenBSD: iked.c,v 1.41 2020/01/16 20:05:00 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 40 __dead void usage(void); 41 42 void parent_shutdown(struct iked *); 43 void parent_sig_handler(int, short, void *); 44 int parent_dispatch_ca(int, struct privsep_proc *, struct imsg *); 45 int parent_dispatch_control(int, struct privsep_proc *, struct imsg *); 46 int parent_configure(struct iked *); 47 48 static struct privsep_proc procs[] = { 49 { "ca", PROC_CERT, parent_dispatch_ca, caproc, IKED_CA }, 50 { "control", PROC_CONTROL, parent_dispatch_control, control }, 51 { "ikev2", PROC_IKEV2, NULL, ikev2 } 52 }; 53 54 __dead void 55 usage(void) 56 { 57 extern char *__progname; 58 59 fprintf(stderr, "usage: %s [-dnSTtv] [-D macro=value] " 60 "[-f file] [-p udpencap_port]\n", __progname); 61 exit(1); 62 } 63 64 int 65 main(int argc, char *argv[]) 66 { 67 int c; 68 int debug = 0, verbose = 0; 69 int opts = 0; 70 in_port_t port = IKED_NATT_PORT; 71 const char *conffile = IKED_CONFIG; 72 struct iked *env = NULL; 73 struct privsep *ps; 74 75 log_init(1, LOG_DAEMON); 76 77 while ((c = getopt(argc, argv, "6dD:nf:p:vSTt")) != -1) { 78 switch (c) { 79 case '6': 80 log_warnx("the -6 option is ignored and will be " 81 "removed in the future."); 82 break; 83 case 'd': 84 debug++; 85 break; 86 case 'D': 87 if (cmdline_symset(optarg) < 0) 88 log_warnx("could not parse macro definition %s", 89 optarg); 90 break; 91 case 'n': 92 debug = 1; 93 opts |= IKED_OPT_NOACTION; 94 break; 95 case 'f': 96 conffile = optarg; 97 break; 98 case 'v': 99 verbose++; 100 opts |= IKED_OPT_VERBOSE; 101 break; 102 case 'S': 103 opts |= IKED_OPT_PASSIVE; 104 break; 105 case 'T': 106 opts |= IKED_OPT_NONATT; 107 break; 108 case 't': 109 opts |= IKED_OPT_NATT; 110 break; 111 case 'p': 112 port = atoi(optarg); 113 opts |= IKED_OPT_NATT; 114 break; 115 default: 116 usage(); 117 } 118 } 119 120 argc -= optind; 121 argv += optind; 122 if (argc > 0) 123 usage(); 124 125 if ((env = calloc(1, sizeof(*env))) == NULL) 126 fatal("calloc: env"); 127 128 env->sc_opts = opts; 129 env->sc_nattport = port; 130 131 ps = &env->sc_ps; 132 ps->ps_env = env; 133 TAILQ_INIT(&ps->ps_rcsocks); 134 135 if ((opts & (IKED_OPT_NONATT|IKED_OPT_NATT)) == 136 (IKED_OPT_NONATT|IKED_OPT_NATT)) 137 errx(1, "conflicting NAT-T options"); 138 139 if (strlcpy(env->sc_conffile, conffile, PATH_MAX) >= PATH_MAX) 140 errx(1, "config file exceeds PATH_MAX"); 141 142 ca_sslinit(); 143 policy_init(env); 144 145 /* check for root privileges */ 146 if (geteuid()) 147 errx(1, "need root privileges"); 148 149 if ((ps->ps_pw = getpwnam(IKED_USER)) == NULL) 150 errx(1, "unknown user %s", IKED_USER); 151 152 /* Configure the control socket */ 153 ps->ps_csock.cs_name = IKED_SOCKET; 154 155 log_init(debug, LOG_DAEMON); 156 log_setverbose(verbose); 157 158 if (opts & IKED_OPT_NOACTION) 159 ps->ps_noaction = 1; 160 161 if (!debug && daemon(0, 0) == -1) 162 err(1, "failed to daemonize"); 163 164 group_init(); 165 166 ps->ps_ninstances = 1; 167 proc_init(ps, procs, nitems(procs)); 168 169 setproctitle("parent"); 170 log_procinit("parent"); 171 172 event_init(); 173 174 signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps); 175 signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps); 176 signal_set(&ps->ps_evsigchld, SIGCHLD, parent_sig_handler, ps); 177 signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps); 178 signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps); 179 signal_set(&ps->ps_evsigusr1, SIGUSR1, parent_sig_handler, ps); 180 181 signal_add(&ps->ps_evsigint, NULL); 182 signal_add(&ps->ps_evsigterm, NULL); 183 signal_add(&ps->ps_evsigchld, NULL); 184 signal_add(&ps->ps_evsighup, NULL); 185 signal_add(&ps->ps_evsigpipe, NULL); 186 signal_add(&ps->ps_evsigusr1, NULL); 187 188 proc_listen(ps, procs, nitems(procs)); 189 190 if (parent_configure(env) == -1) 191 fatalx("configuration failed"); 192 193 event_dispatch(); 194 195 log_debug("%d parent exiting", getpid()); 196 197 return (0); 198 } 199 200 int 201 parent_configure(struct iked *env) 202 { 203 struct sockaddr_storage ss; 204 205 if (parse_config(env->sc_conffile, env) == -1) { 206 proc_kill(&env->sc_ps); 207 exit(1); 208 } 209 210 if (env->sc_opts & IKED_OPT_NOACTION) { 211 fprintf(stderr, "configuration OK\n"); 212 proc_kill(&env->sc_ps); 213 exit(0); 214 } 215 216 env->sc_pfkey = -1; 217 config_setpfkey(env, PROC_IKEV2); 218 219 /* Send private and public keys to cert after forking the children */ 220 if (config_setkeys(env) == -1) 221 fatalx("%s: failed to send keys", __func__); 222 config_setreset(env, RESET_CA, PROC_CERT); 223 224 /* Now compile the policies and calculate skip steps */ 225 config_setcompile(env, PROC_IKEV2); 226 227 bzero(&ss, sizeof(ss)); 228 ss.ss_family = AF_INET; 229 230 if ((env->sc_opts & IKED_OPT_NATT) == 0 && env->sc_nattport == IKED_NATT_PORT) 231 config_setsocket(env, &ss, ntohs(IKED_IKE_PORT), PROC_IKEV2); 232 if ((env->sc_opts & IKED_OPT_NONATT) == 0) 233 config_setsocket(env, &ss, ntohs(env->sc_nattport), PROC_IKEV2); 234 235 bzero(&ss, sizeof(ss)); 236 ss.ss_family = AF_INET6; 237 238 if ((env->sc_opts & IKED_OPT_NATT) == 0 && env->sc_nattport == IKED_NATT_PORT) 239 config_setsocket(env, &ss, ntohs(IKED_IKE_PORT), PROC_IKEV2); 240 if ((env->sc_opts & IKED_OPT_NONATT) == 0) 241 config_setsocket(env, &ss, ntohs(env->sc_nattport), PROC_IKEV2); 242 243 /* 244 * pledge in the parent process: 245 * It has to run fairly late to allow forking the processes and 246 * opening the PFKEY socket and the listening UDP sockets (once) 247 * that need the bypass ioctls that are never allowed by pledge. 248 * 249 * Other flags: 250 * stdio - for malloc and basic I/O including events. 251 * rpath - for reload to open and read the configuration files. 252 * proc - run kill to terminate its children safely. 253 * dns - for reload and ocsp connect. 254 * inet - for ocsp connect. 255 * route - for using interfaces in iked.conf (SIOCGIFGMEMB) 256 * sendfd - for ocsp sockets. 257 */ 258 if (pledge("stdio rpath proc dns inet route sendfd", NULL) == -1) 259 fatal("pledge"); 260 261 config_setmobike(env); 262 config_setfragmentation(env); 263 config_setnattport(env); 264 config_setcoupled(env, env->sc_decoupled ? 0 : 1); 265 config_setocsp(env); 266 /* Must be last */ 267 config_setmode(env, env->sc_passive ? 1 : 0); 268 269 return (0); 270 } 271 272 void 273 parent_reload(struct iked *env, int reset, const char *filename) 274 { 275 /* Switch back to the default config file */ 276 if (filename == NULL || *filename == '\0') 277 filename = env->sc_conffile; 278 279 log_debug("%s: level %d config file %s", __func__, reset, filename); 280 281 if (reset == RESET_RELOAD) { 282 config_setreset(env, RESET_POLICY, PROC_IKEV2); 283 if (config_setkeys(env) == -1) 284 fatalx("%s: failed to send keys", __func__); 285 config_setreset(env, RESET_CA, PROC_CERT); 286 287 if (parse_config(filename, env) == -1) { 288 log_debug("%s: failed to load config file %s", 289 __func__, filename); 290 } 291 292 /* Re-compile policies and skip steps */ 293 config_setcompile(env, PROC_IKEV2); 294 295 config_setmobike(env); 296 config_setfragmentation(env); 297 config_setnattport(env); 298 config_setcoupled(env, env->sc_decoupled ? 0 : 1); 299 config_setocsp(env); 300 /* Must be last */ 301 config_setmode(env, env->sc_passive ? 1 : 0); 302 } else { 303 config_setreset(env, reset, PROC_IKEV2); 304 config_setreset(env, reset, PROC_CERT); 305 } 306 } 307 308 void 309 parent_sig_handler(int sig, short event, void *arg) 310 { 311 struct privsep *ps = arg; 312 int die = 0, status, fail, id; 313 pid_t pid; 314 char *cause; 315 316 switch (sig) { 317 case SIGHUP: 318 log_info("%s: reload requested with SIGHUP", __func__); 319 320 /* 321 * This is safe because libevent uses async signal handlers 322 * that run in the event loop and not in signal context. 323 */ 324 parent_reload(ps->ps_env, 0, NULL); 325 break; 326 case SIGPIPE: 327 log_info("%s: ignoring SIGPIPE", __func__); 328 break; 329 case SIGUSR1: 330 log_info("%s: ignoring SIGUSR1", __func__); 331 break; 332 case SIGTERM: 333 case SIGINT: 334 die = 1; 335 /* FALLTHROUGH */ 336 case SIGCHLD: 337 do { 338 int len; 339 340 pid = waitpid(-1, &status, WNOHANG); 341 if (pid <= 0) 342 continue; 343 344 fail = 0; 345 if (WIFSIGNALED(status)) { 346 fail = 1; 347 len = asprintf(&cause, "terminated; signal %d", 348 WTERMSIG(status)); 349 } else if (WIFEXITED(status)) { 350 if (WEXITSTATUS(status) != 0) { 351 fail = 1; 352 len = asprintf(&cause, 353 "exited abnormally"); 354 } else 355 len = asprintf(&cause, "exited okay"); 356 } else 357 fatalx("unexpected cause of SIGCHLD"); 358 359 if (len == -1) 360 fatal("asprintf"); 361 362 die = 1; 363 364 for (id = 0; id < PROC_MAX; id++) 365 if (pid == ps->ps_pid[id]) { 366 if (fail) 367 log_warnx("lost child: %s %s", 368 ps->ps_title[id], cause); 369 break; 370 } 371 372 free(cause); 373 } while (pid > 0 || (pid == -1 && errno == EINTR)); 374 375 if (die) 376 parent_shutdown(ps->ps_env); 377 break; 378 default: 379 fatalx("unexpected signal"); 380 } 381 } 382 383 int 384 parent_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg) 385 { 386 struct iked *env = p->p_ps->ps_env; 387 388 switch (imsg->hdr.type) { 389 case IMSG_OCSP_FD: 390 ocsp_connect(env); 391 break; 392 default: 393 return (-1); 394 } 395 396 return (0); 397 } 398 399 int 400 parent_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) 401 { 402 struct iked *env = p->p_ps->ps_env; 403 int v; 404 char *str = NULL; 405 unsigned int type = imsg->hdr.type; 406 407 switch (type) { 408 case IMSG_CTL_RESET: 409 IMSG_SIZE_CHECK(imsg, &v); 410 memcpy(&v, imsg->data, sizeof(v)); 411 parent_reload(env, v, NULL); 412 break; 413 case IMSG_CTL_COUPLE: 414 case IMSG_CTL_DECOUPLE: 415 case IMSG_CTL_ACTIVE: 416 case IMSG_CTL_PASSIVE: 417 proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0); 418 break; 419 case IMSG_CTL_RELOAD: 420 if (IMSG_DATA_SIZE(imsg) > 0) 421 str = get_string(imsg->data, IMSG_DATA_SIZE(imsg)); 422 parent_reload(env, 0, str); 423 free(str); 424 break; 425 case IMSG_CTL_VERBOSE: 426 proc_forward_imsg(&env->sc_ps, imsg, PROC_IKEV2, -1); 427 proc_forward_imsg(&env->sc_ps, imsg, PROC_CERT, -1); 428 429 /* return 1 to let proc.c handle it locally */ 430 return (1); 431 default: 432 return (-1); 433 } 434 435 return (0); 436 } 437 438 void 439 parent_shutdown(struct iked *env) 440 { 441 proc_kill(&env->sc_ps); 442 443 free(env); 444 445 log_warnx("parent terminating"); 446 exit(0); 447 } 448