1 /* $NetBSD: session.c,v 1.32 2011/03/02 15:09:16 vanhu Exp $ */ 2 3 /* $KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $ */ 4 5 /* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * 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 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "config.h" 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/time.h> 39 #include <sys/socket.h> 40 #if HAVE_SYS_WAIT_H 41 # include <sys/wait.h> 42 #endif 43 #ifndef WEXITSTATUS 44 # define WEXITSTATUS(s) ((unsigned)(s) >> 8) 45 #endif 46 #ifndef WIFEXITED 47 # define WIFEXITED(s) (((s) & 255) == 0) 48 #endif 49 50 #include PATH_IPSEC_H 51 52 #include <stdlib.h> 53 #include <stdio.h> 54 #include <string.h> 55 #include <errno.h> 56 #ifdef HAVE_UNISTD_H 57 #include <unistd.h> 58 #endif 59 #include <signal.h> 60 #include <sys/stat.h> 61 #include <paths.h> 62 #include <err.h> 63 64 #include <netinet/in.h> 65 #include <resolv.h> 66 67 #include "libpfkey.h" 68 69 #include "var.h" 70 #include "misc.h" 71 #include "vmbuf.h" 72 #include "plog.h" 73 #include "debug.h" 74 75 #include "schedule.h" 76 #include "session.h" 77 #include "grabmyaddr.h" 78 #include "evt.h" 79 #include "cfparse_proto.h" 80 #include "isakmp_var.h" 81 #include "isakmp.h" 82 #include "isakmp_var.h" 83 #include "isakmp_xauth.h" 84 #include "isakmp_cfg.h" 85 #include "admin_var.h" 86 #include "admin.h" 87 #include "privsep.h" 88 #include "oakley.h" 89 #include "pfkey.h" 90 #include "handler.h" 91 #include "localconf.h" 92 #include "remoteconf.h" 93 #include "backupsa.h" 94 #include "remoteconf.h" 95 #ifdef ENABLE_NATT 96 #include "nattraversal.h" 97 #endif 98 99 #include "algorithm.h" /* XXX ??? */ 100 101 #include "sainfo.h" 102 103 struct fd_monitor { 104 int (*callback)(void *ctx, int fd); 105 void *ctx; 106 int prio; 107 int fd; 108 TAILQ_ENTRY(fd_monitor) chain; 109 }; 110 111 #define NUM_PRIORITIES 2 112 113 static void close_session __P((void)); 114 static void initfds __P((void)); 115 static void init_signal __P((void)); 116 static int set_signal __P((int sig, RETSIGTYPE (*func) __P((int)))); 117 static void check_sigreq __P((void)); 118 static void check_flushsa __P((void)); 119 static int close_sockets __P((void)); 120 121 static fd_set preset_mask, active_mask; 122 static struct fd_monitor fd_monitors[FD_SETSIZE]; 123 static TAILQ_HEAD(fd_monitor_list, fd_monitor) fd_monitor_tree[NUM_PRIORITIES]; 124 static int nfds = 0; 125 126 static volatile sig_atomic_t sigreq[NSIG + 1]; 127 static struct sched scflushsa = SCHED_INITIALIZER(); 128 129 void 130 monitor_fd(int fd, int (*callback)(void *, int), void *ctx, int priority) 131 { 132 if (fd < 0 || fd >= FD_SETSIZE) { 133 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun"); 134 exit(1); 135 } 136 137 FD_SET(fd, &preset_mask); 138 if (fd > nfds) 139 nfds = fd; 140 if (priority <= 0) 141 priority = 0; 142 if (priority >= NUM_PRIORITIES) 143 priority = NUM_PRIORITIES - 1; 144 145 fd_monitors[fd].callback = callback; 146 fd_monitors[fd].ctx = ctx; 147 fd_monitors[fd].prio = priority; 148 fd_monitors[fd].fd = fd; 149 TAILQ_INSERT_TAIL(&fd_monitor_tree[priority], 150 &fd_monitors[fd], chain); 151 } 152 153 void 154 unmonitor_fd(int fd) 155 { 156 if (fd < 0 || fd >= FD_SETSIZE) { 157 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun"); 158 exit(1); 159 } 160 161 if (fd_monitors[fd].callback == NULL) 162 return; 163 164 FD_CLR(fd, &preset_mask); 165 FD_CLR(fd, &active_mask); 166 fd_monitors[fd].callback = NULL; 167 fd_monitors[fd].ctx = NULL; 168 TAILQ_REMOVE(&fd_monitor_tree[fd_monitors[fd].prio], 169 &fd_monitors[fd], chain); 170 } 171 172 int 173 session(void) 174 { 175 struct timeval *timeout; 176 int error; 177 char pid_file[MAXPATHLEN]; 178 FILE *fp; 179 pid_t racoon_pid = 0; 180 int i, count; 181 struct fd_monitor *fdm; 182 183 nfds = 0; 184 FD_ZERO(&preset_mask); 185 186 for (i = 0; i < NUM_PRIORITIES; i++) 187 TAILQ_INIT(&fd_monitor_tree[i]); 188 189 /* initialize schedular */ 190 sched_init(); 191 init_signal(); 192 193 if (pfkey_init() < 0) 194 errx(1, "failed to initialize pfkey socket"); 195 196 if (isakmp_init() < 0) 197 errx(1, "failed to initialize ISAKMP structures"); 198 199 #ifdef ENABLE_HYBRID 200 if (isakmp_cfg_init(ISAKMP_CFG_INIT_COLD)) 201 errx(1, "could not initialize ISAKMP mode config structures"); 202 #endif 203 204 #ifdef HAVE_LIBLDAP 205 if (xauth_ldap_init_conf() != 0) 206 errx(1, "could not initialize ldap config"); 207 #endif 208 209 #ifdef HAVE_LIBRADIUS 210 if (xauth_radius_init_conf(0) != 0) 211 errx(1, "could not initialize radius config"); 212 #endif 213 214 myaddr_init_lists(); 215 216 /* 217 * in order to prefer the parameters by command line, 218 * saving some parameters before parsing configuration file. 219 */ 220 save_params(); 221 if (cfparse() != 0) 222 errx(1, "failed to parse configuration file."); 223 restore_params(); 224 225 #ifdef ENABLE_ADMINPORT 226 if (admin_init() < 0) 227 errx(1, "failed to initialize admin port socket"); 228 #endif 229 230 231 #ifdef ENABLE_HYBRID 232 if(isakmp_cfg_config.network4 && isakmp_cfg_config.pool_size == 0) 233 if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0) 234 return error; 235 #endif 236 237 if (dump_config) 238 dumprmconf(); 239 240 #ifdef HAVE_LIBRADIUS 241 if (xauth_radius_init() != 0) 242 errx(1, "could not initialize libradius"); 243 #endif 244 245 if (myaddr_init() != 0) 246 errx(1, "failed to listen to configured addresses"); 247 myaddr_sync(); 248 249 #ifdef ENABLE_NATT 250 natt_keepalive_init (); 251 #endif 252 253 /* write .pid file */ 254 if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL) 255 strlcpy(pid_file, _PATH_VARRUN "racoon.pid", MAXPATHLEN); 256 else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/') 257 strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); 258 else { 259 strlcat(pid_file, _PATH_VARRUN, MAXPATHLEN); 260 strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); 261 } 262 fp = fopen(pid_file, "w"); 263 if (fp) { 264 if (fchmod(fileno(fp), 265 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 266 syslog(LOG_ERR, "%s", strerror(errno)); 267 fclose(fp); 268 exit(1); 269 } 270 } else { 271 plog(LLV_ERROR, LOCATION, NULL, 272 "cannot open %s", pid_file); 273 } 274 275 if (privsep_init() != 0) 276 exit(1); 277 278 /* 279 * The fork()'ed privileged side will close its copy of fp. We wait 280 * until here to get the correct child pid. 281 */ 282 racoon_pid = getpid(); 283 fprintf(fp, "%ld\n", (long)racoon_pid); 284 fclose(fp); 285 286 for (i = 0; i <= NSIG; i++) 287 sigreq[i] = 0; 288 289 while (1) { 290 /* 291 * asynchronous requests via signal. 292 * make sure to reset sigreq to 0. 293 */ 294 check_sigreq(); 295 296 /* scheduling */ 297 timeout = schedular(); 298 299 /* schedular can change select() mask, so we reset 300 * the working copy here */ 301 active_mask = preset_mask; 302 303 error = select(nfds + 1, &active_mask, NULL, NULL, timeout); 304 if (error < 0) { 305 switch (errno) { 306 case EINTR: 307 continue; 308 default: 309 plog(LLV_ERROR, LOCATION, NULL, 310 "failed to select (%s)\n", 311 strerror(errno)); 312 return -1; 313 } 314 /*NOTREACHED*/ 315 } 316 317 count = 0; 318 for (i = 0; i < NUM_PRIORITIES; i++) { 319 TAILQ_FOREACH(fdm, &fd_monitor_tree[i], chain) { 320 if (!FD_ISSET(fdm->fd, &active_mask)) 321 continue; 322 323 FD_CLR(fdm->fd, &active_mask); 324 if (fdm->callback != NULL) { 325 fdm->callback(fdm->ctx, fdm->fd); 326 count++; 327 } else 328 plog(LLV_ERROR, LOCATION, NULL, 329 "fd %d set, but no active callback\n", i); 330 } 331 if (count != 0) 332 break; 333 } 334 335 } 336 } 337 338 /* clear all status and exit program. */ 339 static void 340 close_session() 341 { 342 evt_generic(EVT_RACOON_QUIT, NULL); 343 pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC); 344 flushph2(); 345 flushph1(); 346 flushrmconf(); 347 flushsainfo(); 348 close_sockets(); 349 backupsa_clean(); 350 351 plog(LLV_INFO, LOCATION, NULL, "racoon process %d shutdown\n", getpid()); 352 353 exit(0); 354 } 355 356 static int signals[] = { 357 SIGHUP, 358 SIGINT, 359 SIGTERM, 360 SIGUSR1, 361 SIGUSR2, 362 SIGCHLD, 363 0 364 }; 365 366 /* 367 * asynchronous requests will actually dispatched in the 368 * main loop in session(). 369 */ 370 RETSIGTYPE 371 signal_handler(sig) 372 int sig; 373 { 374 sigreq[sig] = 1; 375 } 376 377 378 /* XXX possible mem leaks and no way to go back for now !!! 379 */ 380 static void reload_conf(){ 381 int error; 382 383 #ifdef ENABLE_HYBRID 384 if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM)) != 0) { 385 plog(LLV_ERROR, LOCATION, NULL, 386 "ISAKMP mode config structure reset failed, " 387 "not reloading\n"); 388 return; 389 } 390 #endif 391 392 sainfo_start_reload(); 393 394 /* TODO: save / restore / flush old lcconf (?) / rmtree 395 */ 396 rmconf_start_reload(); 397 398 #ifdef HAVE_LIBRADIUS 399 /* free and init radius configuration */ 400 xauth_radius_init_conf(1); 401 #endif 402 403 pfkey_reload(); 404 405 save_params(); 406 flushlcconf(); 407 error = cfparse(); 408 if (error != 0){ 409 plog(LLV_ERROR, LOCATION, NULL, "config reload failed\n"); 410 /* We are probably in an inconsistant state... */ 411 return; 412 } 413 restore_params(); 414 415 #if 0 416 if (dump_config) 417 dumprmconf (); 418 #endif 419 420 myaddr_sync(); 421 422 #ifdef HAVE_LIBRADIUS 423 /* re-initialize radius state */ 424 xauth_radius_init(); 425 #endif 426 427 /* Revalidate ph1 / ph2tree !!! 428 * update ctdtree if removing some ph1 ! 429 */ 430 revalidate_ph12(); 431 /* Update ctdtree ? 432 */ 433 434 sainfo_finish_reload(); 435 rmconf_finish_reload(); 436 } 437 438 static void 439 check_sigreq() 440 { 441 int sig, s; 442 443 for (sig = 0; sig <= NSIG; sig++) { 444 if (sigreq[sig] == 0) 445 continue; 446 sigreq[sig] = 0; 447 448 switch(sig) { 449 case 0: 450 return; 451 452 case SIGCHLD: 453 /* Reap all pending children */ 454 while (waitpid(-1, &s, WNOHANG) > 0) 455 ; 456 break; 457 458 #ifdef DEBUG_RECORD_MALLOCATION 459 /* 460 * XXX This operation is signal handler unsafe and may lead to 461 * crashes and security breaches: See Henning Brauer talk at 462 * EuroBSDCon 2005. Do not run in production with this option 463 * enabled. 464 */ 465 case SIGUSR2: 466 DRM_dump(); 467 break; 468 #endif 469 470 case SIGHUP: 471 /* Save old configuration, load new one... */ 472 reload_conf(); 473 break; 474 475 case SIGINT: 476 case SIGTERM: 477 plog(LLV_INFO, LOCATION, NULL, 478 "caught signal %d\n", sig); 479 close_session(); 480 break; 481 482 default: 483 plog(LLV_INFO, LOCATION, NULL, 484 "caught signal %d\n", sig); 485 break; 486 } 487 } 488 } 489 490 static void 491 init_signal() 492 { 493 int i; 494 495 /* 496 * Ignore SIGPIPE as we check the return value of system calls 497 * that write to pipe-like fds. 498 */ 499 signal(SIGPIPE, SIG_IGN); 500 501 for (i = 0; signals[i] != 0; i++) 502 if (set_signal(signals[i], signal_handler) < 0) { 503 plog(LLV_ERROR, LOCATION, NULL, 504 "failed to set_signal (%s)\n", 505 strerror(errno)); 506 exit(1); 507 } 508 } 509 510 static int 511 set_signal(sig, func) 512 int sig; 513 RETSIGTYPE (*func) __P((int)); 514 { 515 struct sigaction sa; 516 517 memset((caddr_t)&sa, 0, sizeof(sa)); 518 sa.sa_handler = func; 519 sa.sa_flags = SA_RESTART; 520 521 if (sigemptyset(&sa.sa_mask) < 0) 522 return -1; 523 524 if (sigaction(sig, &sa, (struct sigaction *)0) < 0) 525 return(-1); 526 527 return 0; 528 } 529 530 static int 531 close_sockets() 532 { 533 myaddr_close(); 534 pfkey_close(lcconf->sock_pfkey); 535 #ifdef ENABLE_ADMINPORT 536 (void)admin_close(); 537 #endif 538 return 0; 539 } 540 541