1 /* $OpenBSD: iked.c,v 1.31 2016/09/04 16:55:43 reyk Exp $ */ 2 3 /* 4 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/queue.h> 20 #include <sys/socket.h> 21 #include <sys/wait.h> 22 #include <sys/uio.h> 23 24 #include <stdlib.h> 25 #include <stdio.h> 26 #include <unistd.h> 27 #include <string.h> 28 #include <getopt.h> 29 #include <signal.h> 30 #include <syslog.h> 31 #include <errno.h> 32 #include <err.h> 33 #include <pwd.h> 34 #include <event.h> 35 36 #include "iked.h" 37 #include "ikev2.h" 38 39 __dead void usage(void); 40 41 void parent_shutdown(struct iked *); 42 void parent_sig_handler(int, short, void *); 43 int parent_dispatch_ca(int, struct privsep_proc *, struct imsg *); 44 int parent_dispatch_control(int, struct privsep_proc *, struct imsg *); 45 int parent_configure(struct iked *); 46 47 static struct privsep_proc procs[] = { 48 { "ca", PROC_CERT, parent_dispatch_ca, caproc, IKED_CA }, 49 { "control", PROC_CONTROL, parent_dispatch_control, control }, 50 { "ikev2", PROC_IKEV2, NULL, ikev2 } 51 }; 52 53 __dead void 54 usage(void) 55 { 56 extern char *__progname; 57 58 fprintf(stderr, "usage: %s [-6dnSTtv] [-D macro=value] " 59 "[-f file]\n", __progname); 60 exit(1); 61 } 62 63 int 64 main(int argc, char *argv[]) 65 { 66 int c; 67 int debug = 0, verbose = 0; 68 int opts = 0; 69 const char *conffile = IKED_CONFIG; 70 struct iked *env = NULL; 71 struct privsep *ps; 72 73 log_init(1, LOG_DAEMON); 74 75 while ((c = getopt(argc, argv, "6dD:nf:vSTt")) != -1) { 76 switch (c) { 77 case '6': 78 opts |= IKED_OPT_NOIPV6BLOCKING; 79 break; 80 case 'd': 81 debug++; 82 break; 83 case 'D': 84 if (cmdline_symset(optarg) < 0) 85 log_warnx("could not parse macro definition %s", 86 optarg); 87 break; 88 case 'n': 89 debug = 1; 90 opts |= IKED_OPT_NOACTION; 91 break; 92 case 'f': 93 conffile = optarg; 94 break; 95 case 'v': 96 verbose++; 97 opts |= IKED_OPT_VERBOSE; 98 break; 99 case 'S': 100 opts |= IKED_OPT_PASSIVE; 101 break; 102 case 'T': 103 opts |= IKED_OPT_NONATT; 104 break; 105 case 't': 106 opts |= IKED_OPT_NATT; 107 break; 108 default: 109 usage(); 110 } 111 } 112 113 if ((env = calloc(1, sizeof(*env))) == NULL) 114 fatal("calloc: env"); 115 116 env->sc_opts = opts; 117 118 ps = &env->sc_ps; 119 ps->ps_env = env; 120 TAILQ_INIT(&ps->ps_rcsocks); 121 122 if ((opts & (IKED_OPT_NONATT|IKED_OPT_NATT)) == 123 (IKED_OPT_NONATT|IKED_OPT_NATT)) 124 errx(1, "conflicting NAT-T options"); 125 126 if (strlcpy(env->sc_conffile, conffile, PATH_MAX) >= PATH_MAX) 127 errx(1, "config file exceeds PATH_MAX"); 128 129 ca_sslinit(); 130 policy_init(env); 131 132 /* check for root privileges */ 133 if (geteuid()) 134 errx(1, "need root privileges"); 135 136 if ((ps->ps_pw = getpwnam(IKED_USER)) == NULL) 137 errx(1, "unknown user %s", IKED_USER); 138 139 /* Configure the control socket */ 140 ps->ps_csock.cs_name = IKED_SOCKET; 141 142 log_init(debug, LOG_DAEMON); 143 log_verbose(verbose); 144 145 if (!debug && daemon(0, 0) == -1) 146 err(1, "failed to daemonize"); 147 148 group_init(); 149 150 ps->ps_ninstances = 1; 151 proc_init(ps, procs, nitems(procs)); 152 153 setproctitle("parent"); 154 log_procinit("parent"); 155 156 event_init(); 157 158 signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps); 159 signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps); 160 signal_set(&ps->ps_evsigchld, SIGCHLD, parent_sig_handler, ps); 161 signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps); 162 signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps); 163 signal_set(&ps->ps_evsigusr1, SIGUSR1, parent_sig_handler, ps); 164 165 signal_add(&ps->ps_evsigint, NULL); 166 signal_add(&ps->ps_evsigterm, NULL); 167 signal_add(&ps->ps_evsigchld, NULL); 168 signal_add(&ps->ps_evsighup, NULL); 169 signal_add(&ps->ps_evsigpipe, NULL); 170 signal_add(&ps->ps_evsigusr1, NULL); 171 172 proc_listen(ps, procs, nitems(procs)); 173 174 if (parent_configure(env) == -1) 175 fatalx("configuration failed"); 176 177 event_dispatch(); 178 179 log_debug("%d parent exiting", getpid()); 180 181 return (0); 182 } 183 184 int 185 parent_configure(struct iked *env) 186 { 187 struct sockaddr_storage ss; 188 189 if (parse_config(env->sc_conffile, env) == -1) { 190 proc_kill(&env->sc_ps); 191 exit(1); 192 } 193 194 if (env->sc_opts & IKED_OPT_NOACTION) { 195 fprintf(stderr, "configuration OK\n"); 196 proc_kill(&env->sc_ps); 197 exit(0); 198 } 199 200 env->sc_pfkey = -1; 201 config_setpfkey(env, PROC_IKEV2); 202 203 /* Now compile the policies and calculate skip steps */ 204 config_setcompile(env, PROC_IKEV2); 205 206 bzero(&ss, sizeof(ss)); 207 ss.ss_family = AF_INET; 208 209 if ((env->sc_opts & IKED_OPT_NATT) == 0) 210 config_setsocket(env, &ss, ntohs(IKED_IKE_PORT), PROC_IKEV2); 211 if ((env->sc_opts & IKED_OPT_NONATT) == 0) 212 config_setsocket(env, &ss, ntohs(IKED_NATT_PORT), PROC_IKEV2); 213 214 bzero(&ss, sizeof(ss)); 215 ss.ss_family = AF_INET6; 216 217 if ((env->sc_opts & IKED_OPT_NATT) == 0) 218 config_setsocket(env, &ss, ntohs(IKED_IKE_PORT), PROC_IKEV2); 219 if ((env->sc_opts & IKED_OPT_NONATT) == 0) 220 config_setsocket(env, &ss, ntohs(IKED_NATT_PORT), PROC_IKEV2); 221 222 /* 223 * pledge in the parent process: 224 * It has to run fairly late to allow forking the processes and 225 * opening the PFKEY socket and the listening UDP sockets (once) 226 * that need the bypass ioctls that are never allowed by pledge. 227 * 228 * Other flags: 229 * stdio - for malloc and basic I/O including events. 230 * rpath - for reload to open and read the configuration files. 231 * proc - run kill to terminate its children safely. 232 * dns - for reload and ocsp connect. 233 * inet - for ocsp connect. 234 * route - for using interfaces in iked.conf (SIOCGIFGMEMB) 235 * sendfd - for ocsp sockets. 236 */ 237 if (pledge("stdio rpath proc dns inet route sendfd", NULL) == -1) 238 fatal("pledge"); 239 240 config_setcoupled(env, env->sc_decoupled ? 0 : 1); 241 config_setmode(env, env->sc_passive ? 1 : 0); 242 config_setocsp(env); 243 244 return (0); 245 } 246 247 void 248 parent_reload(struct iked *env, int reset, const char *filename) 249 { 250 /* Switch back to the default config file */ 251 if (filename == NULL || *filename == '\0') 252 filename = env->sc_conffile; 253 254 log_debug("%s: level %d config file %s", __func__, reset, filename); 255 256 if (reset == RESET_RELOAD) { 257 config_setreset(env, RESET_POLICY, PROC_IKEV2); 258 config_setreset(env, RESET_CA, PROC_CERT); 259 260 if (parse_config(filename, env) == -1) { 261 log_debug("%s: failed to load config file %s", 262 __func__, filename); 263 } 264 265 /* Re-compile policies and skip steps */ 266 config_setcompile(env, PROC_IKEV2); 267 268 config_setcoupled(env, env->sc_decoupled ? 0 : 1); 269 config_setmode(env, env->sc_passive ? 1 : 0); 270 config_setocsp(env); 271 } else { 272 config_setreset(env, reset, PROC_IKEV2); 273 config_setreset(env, reset, PROC_CERT); 274 } 275 } 276 277 void 278 parent_sig_handler(int sig, short event, void *arg) 279 { 280 struct privsep *ps = arg; 281 int die = 0, status, fail, id; 282 pid_t pid; 283 char *cause; 284 285 switch (sig) { 286 case SIGHUP: 287 log_info("%s: reload requested with SIGHUP", __func__); 288 289 /* 290 * This is safe because libevent uses async signal handlers 291 * that run in the event loop and not in signal context. 292 */ 293 parent_reload(ps->ps_env, 0, NULL); 294 break; 295 case SIGPIPE: 296 log_info("%s: ignoring SIGPIPE", __func__); 297 break; 298 case SIGUSR1: 299 log_info("%s: ignoring SIGUSR1", __func__); 300 break; 301 case SIGTERM: 302 case SIGINT: 303 die = 1; 304 /* FALLTHROUGH */ 305 case SIGCHLD: 306 do { 307 int len; 308 309 pid = waitpid(-1, &status, WNOHANG); 310 if (pid <= 0) 311 continue; 312 313 fail = 0; 314 if (WIFSIGNALED(status)) { 315 fail = 1; 316 len = asprintf(&cause, "terminated; signal %d", 317 WTERMSIG(status)); 318 } else if (WIFEXITED(status)) { 319 if (WEXITSTATUS(status) != 0) { 320 fail = 1; 321 len = asprintf(&cause, 322 "exited abnormally"); 323 } else 324 len = asprintf(&cause, "exited okay"); 325 } else 326 fatalx("unexpected cause of SIGCHLD"); 327 328 if (len == -1) 329 fatal("asprintf"); 330 331 die = 1; 332 333 for (id = 0; id < PROC_MAX; id++) 334 if (pid == ps->ps_pid[id]) { 335 if (fail) 336 log_warnx("lost child: %s %s", 337 ps->ps_title[id], cause); 338 break; 339 } 340 341 free(cause); 342 } while (pid > 0 || (pid == -1 && errno == EINTR)); 343 344 if (die) 345 parent_shutdown(ps->ps_env); 346 break; 347 default: 348 fatalx("unexpected signal"); 349 } 350 } 351 352 int 353 parent_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg) 354 { 355 struct iked *env = p->p_ps->ps_env; 356 357 switch (imsg->hdr.type) { 358 case IMSG_OCSP_FD: 359 ocsp_connect(env); 360 break; 361 default: 362 return (-1); 363 } 364 365 return (0); 366 } 367 368 int 369 parent_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) 370 { 371 struct iked *env = p->p_ps->ps_env; 372 int v; 373 char *str = NULL; 374 unsigned int type = imsg->hdr.type; 375 376 switch (type) { 377 case IMSG_CTL_RESET: 378 IMSG_SIZE_CHECK(imsg, &v); 379 memcpy(&v, imsg->data, sizeof(v)); 380 parent_reload(env, v, NULL); 381 break; 382 case IMSG_CTL_COUPLE: 383 case IMSG_CTL_DECOUPLE: 384 case IMSG_CTL_ACTIVE: 385 case IMSG_CTL_PASSIVE: 386 proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0); 387 break; 388 case IMSG_CTL_RELOAD: 389 if (IMSG_DATA_SIZE(imsg) > 0) 390 str = get_string(imsg->data, IMSG_DATA_SIZE(imsg)); 391 parent_reload(env, 0, str); 392 free(str); 393 break; 394 case IMSG_CTL_VERBOSE: 395 proc_forward_imsg(&env->sc_ps, imsg, PROC_IKEV2, -1); 396 proc_forward_imsg(&env->sc_ps, imsg, PROC_CERT, -1); 397 398 /* return 1 to let proc.c handle it locally */ 399 return (1); 400 default: 401 return (-1); 402 } 403 404 return (0); 405 } 406 407 void 408 parent_shutdown(struct iked *env) 409 { 410 proc_kill(&env->sc_ps); 411 412 free(env); 413 414 log_warnx("parent terminating"); 415 exit(0); 416 } 417