session.c revision 0a1907d434839af6a9cb6329bbde60b237bf53dc
1/* $NetBSD: session.c,v 1.7.6.2 2007/08/01 11:52:22 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 63#include <netinet/in.h> 64#include <resolv.h> 65#ifdef ANDROID_CHANGES 66#include <arpa/inet.h> 67#include <arpa_nameser.h> 68#endif 69 70#include "libpfkey.h" 71 72#include "var.h" 73#include "misc.h" 74#include "vmbuf.h" 75#include "plog.h" 76#include "debug.h" 77 78#include "schedule.h" 79#include "session.h" 80#include "grabmyaddr.h" 81#include "evt.h" 82#include "cfparse_proto.h" 83#include "isakmp_var.h" 84#include "isakmp_xauth.h" 85#include "isakmp_cfg.h" 86#include "admin_var.h" 87#include "admin.h" 88#include "privsep.h" 89#include "oakley.h" 90#include "pfkey.h" 91#include "handler.h" 92#include "localconf.h" 93#include "remoteconf.h" 94#include "backupsa.h" 95#ifdef ENABLE_NATT 96#include "nattraversal.h" 97#endif 98 99 100#include "algorithm.h" /* XXX ??? */ 101 102#include "sainfo.h" 103 104static void close_session __P((void)); 105static void check_rtsock __P((void *)); 106static void initfds __P((void)); 107static void init_signal __P((void)); 108static int set_signal __P((int sig, RETSIGTYPE (*func) __P((int)))); 109static void check_sigreq __P((void)); 110static void check_flushsa_stub __P((void *)); 111static void check_flushsa __P((void)); 112static int close_sockets __P((void)); 113 114static fd_set mask0; 115static fd_set maskdying; 116static int nfds = 0; 117static volatile sig_atomic_t sigreq[NSIG + 1]; 118static int dying = 0; 119 120int 121session(void) 122{ 123 fd_set rfds; 124 struct timeval *timeout; 125 int error; 126 struct myaddrs *p; 127 char pid_file[MAXPATHLEN]; 128 FILE *fp; 129 pid_t racoon_pid = 0; 130 int i; 131 132 /* initialize schedular */ 133 sched_init(); 134 135 init_signal(); 136 137#ifdef ENABLE_ADMINPORT 138 if (admin_init() < 0) 139 exit(1); 140#endif 141 142 initmyaddr(); 143 144 if (isakmp_init() < 0) 145 exit(1); 146 147 initfds(); 148 149#ifdef ENABLE_NATT 150 natt_keepalive_init (); 151#endif 152 153 if (privsep_init() != 0) 154 exit(1); 155 156 for (i = 0; i <= NSIG; i++) 157 sigreq[i] = 0; 158 159 /* write .pid file */ 160 racoon_pid = getpid(); 161 if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL) 162 strlcpy(pid_file, _PATH_VARRUN "racoon.pid", MAXPATHLEN); 163 else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/') 164 strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); 165 else { 166 strlcat(pid_file, _PATH_VARRUN, MAXPATHLEN); 167 strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); 168 } 169 fp = fopen(pid_file, "w"); 170 if (fp) { 171 if (fchmod(fileno(fp), 172 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 173 syslog(LOG_ERR, "%s", strerror(errno)); 174 fclose(fp); 175 exit(1); 176 } 177 fprintf(fp, "%ld\n", (long)racoon_pid); 178 fclose(fp); 179 } else { 180 plog(LLV_ERROR, LOCATION, NULL, 181 "cannot open %s", pid_file); 182 } 183 184 while (1) { 185 if (dying) 186 rfds = maskdying; 187 else 188 rfds = mask0; 189 190 /* 191 * asynchronous requests via signal. 192 * make sure to reset sigreq to 0. 193 */ 194 check_sigreq(); 195 196 /* scheduling */ 197 timeout = schedular(); 198 199 error = select(nfds, &rfds, (fd_set *)0, (fd_set *)0, timeout); 200 if (error < 0) { 201 switch (errno) { 202 case EINTR: 203 continue; 204 default: 205 plog(LLV_ERROR, LOCATION, NULL, 206 "failed to select (%s)\n", 207 strerror(errno)); 208 return -1; 209 } 210 /*NOTREACHED*/ 211 } 212 213#ifdef ENABLE_ADMINPORT 214 if ((lcconf->sock_admin != -1) && 215 (FD_ISSET(lcconf->sock_admin, &rfds))) 216 admin_handler(); 217#endif 218 219 for (p = lcconf->myaddrs; p; p = p->next) { 220 if (!p->addr) 221 continue; 222 if (FD_ISSET(p->sock, &rfds)) 223 isakmp_handler(p->sock); 224 } 225 226 if (FD_ISSET(lcconf->sock_pfkey, &rfds)) 227 pfkey_handler(); 228 229 if (lcconf->rtsock >= 0 && FD_ISSET(lcconf->rtsock, &rfds)) { 230 if (update_myaddrs() && lcconf->autograbaddr) 231 check_rtsock(NULL); 232 else 233 initfds(); 234 } 235 } 236} 237 238/* clear all status and exit program. */ 239static void 240close_session() 241{ 242#ifdef ENABLE_FASTQUIT 243 flushph2(); 244#endif 245 flushph1(); 246 close_sockets(); 247 backupsa_clean(); 248 249 plog(LLV_INFO, LOCATION, NULL, "racoon shutdown\n"); 250 exit(0); 251} 252 253static void 254check_rtsock(unused) 255 void *unused; 256{ 257 isakmp_close(); 258 grab_myaddrs(); 259 autoconf_myaddrsport(); 260 isakmp_open(); 261 262 /* initialize socket list again */ 263 initfds(); 264} 265 266static void 267initfds() 268{ 269 struct myaddrs *p; 270 271 nfds = 0; 272 273 FD_ZERO(&mask0); 274 FD_ZERO(&maskdying); 275 276#ifdef ENABLE_ADMINPORT 277 if (lcconf->sock_admin != -1) { 278 if (lcconf->sock_admin >= FD_SETSIZE) { 279 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n"); 280 exit(1); 281 } 282 FD_SET(lcconf->sock_admin, &mask0); 283 /* XXX should we listen on admin socket when dying ? 284 */ 285#if 0 286 FD_SET(lcconf->sock_admin, &maskdying); 287#endif 288 nfds = (nfds > lcconf->sock_admin ? nfds : lcconf->sock_admin); 289 } 290#endif 291 if (lcconf->sock_pfkey >= FD_SETSIZE) { 292 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n"); 293 exit(1); 294 } 295 FD_SET(lcconf->sock_pfkey, &mask0); 296 FD_SET(lcconf->sock_pfkey, &maskdying); 297 nfds = (nfds > lcconf->sock_pfkey ? nfds : lcconf->sock_pfkey); 298 if (lcconf->rtsock >= 0) { 299 if (lcconf->rtsock >= FD_SETSIZE) { 300 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n"); 301 exit(1); 302 } 303 FD_SET(lcconf->rtsock, &mask0); 304 nfds = (nfds > lcconf->rtsock ? nfds : lcconf->rtsock); 305 } 306 307 for (p = lcconf->myaddrs; p; p = p->next) { 308 if (!p->addr) 309 continue; 310 if (p->sock >= FD_SETSIZE) { 311 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n"); 312 exit(1); 313 } 314 FD_SET(p->sock, &mask0); 315 nfds = (nfds > p->sock ? nfds : p->sock); 316 } 317 nfds++; 318} 319 320static int signals[] = { 321 SIGHUP, 322 SIGINT, 323 SIGTERM, 324 SIGUSR1, 325 SIGUSR2, 326 SIGCHLD, 327 0 328}; 329 330/* 331 * asynchronous requests will actually dispatched in the 332 * main loop in session(). 333 */ 334RETSIGTYPE 335signal_handler(sig) 336 int sig; 337{ 338 /* Do not just set it to 1, because we may miss some signals by just setting 339 * values to 0/1 340 */ 341 sigreq[sig]++; 342} 343 344 345/* XXX possible mem leaks and no way to go back for now !!! 346 */ 347static void reload_conf(){ 348 int error; 349 350#ifdef ENABLE_HYBRID 351 if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM)) != 0) { 352 plog(LLV_ERROR, LOCATION, NULL, 353 "ISAKMP mode config structure reset failed, " 354 "not reloading\n"); 355 return; 356 } 357#endif 358 359 save_sainfotree(); 360 361 /* TODO: save / restore / flush old lcconf (?) / rmtree 362 */ 363/* initlcconf();*/ /* racoon_conf ? ! */ 364 365 save_rmconf(); 366 initrmconf(); 367 368 /* Do a part of pfkey_init() ? 369 * SPD reload ? 370 */ 371 372 save_params(); 373 error = cfparse(); 374 if (error != 0){ 375 plog(LLV_ERROR, LOCATION, NULL, "config reload failed\n"); 376 /* We are probably in an inconsistant state... */ 377 return; 378 } 379 restore_params(); 380 381#if 0 382 if (dump_config) 383 dumprmconf (); 384#endif 385 386 /* 387 * init_myaddr() ? 388 * If running in privilege separation, do not reinitialize 389 * the IKE listener, as we will not have the right to 390 * setsockopt(IP_IPSEC_POLICY). 391 */ 392 if (geteuid() == 0) 393 check_rtsock(NULL); 394 395 /* Revalidate ph1 / ph2tree !!! 396 * update ctdtree if removing some ph1 ! 397 */ 398 revalidate_ph12(); 399 /* Update ctdtree ? 400 */ 401 402 save_sainfotree_flush(); 403 save_rmconf_flush(); 404} 405 406static void 407check_sigreq() 408{ 409 int sig; 410 411 /* 412 * XXX We are not able to tell if we got 413 * several time the same signal. This is 414 * not a problem for the current code, 415 * but we shall remember this limitation. 416 */ 417 for (sig = 0; sig <= NSIG; sig++) { 418 if (sigreq[sig] == 0) 419 continue; 420 421 sigreq[sig]--; 422 switch(sig) { 423 case 0: 424 return; 425 426 /* Catch up childs, mainly scripts. 427 */ 428 case SIGCHLD: 429 { 430 pid_t pid; 431 int s; 432 433 pid = wait(&s); 434 } 435 break; 436 437#ifdef DEBUG_RECORD_MALLOCATION 438 /* 439 * XXX This operation is signal handler unsafe and may lead to 440 * crashes and security breaches: See Henning Brauer talk at 441 * EuroBSDCon 2005. Do not run in production with this option 442 * enabled. 443 */ 444 case SIGUSR2: 445 DRM_dump(); 446 break; 447#endif 448 449 case SIGHUP: 450 /* Save old configuration, load new one... */ 451 reload_conf(); 452 break; 453 454 case SIGINT: 455 case SIGTERM: 456 plog(LLV_INFO, LOCATION, NULL, 457 "caught signal %d\n", sig); 458 EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL); 459 pfkey_send_flush(lcconf->sock_pfkey, 460 SADB_SATYPE_UNSPEC); 461#ifdef ENABLE_FASTQUIT 462 close_session(); 463#else 464 sched_new(1, check_flushsa_stub, NULL); 465#endif 466 dying = 1; 467 break; 468 469 default: 470 plog(LLV_INFO, LOCATION, NULL, 471 "caught signal %d\n", sig); 472 break; 473 } 474 } 475} 476 477/* 478 * waiting the termination of processing until sending DELETE message 479 * for all inbound SA will complete. 480 */ 481static void 482check_flushsa_stub(p) 483 void *p; 484{ 485 486 check_flushsa(); 487} 488 489static void 490check_flushsa() 491{ 492 vchar_t *buf; 493 struct sadb_msg *msg, *end, *next; 494 struct sadb_sa *sa; 495 caddr_t mhp[SADB_EXT_MAX + 1]; 496 int n; 497 498 buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC); 499 if (buf == NULL) { 500 plog(LLV_DEBUG, LOCATION, NULL, 501 "pfkey_dump_sadb: returned nothing.\n"); 502 return; 503 } 504 505 msg = (struct sadb_msg *)buf->v; 506 end = (struct sadb_msg *)(buf->v + buf->l); 507 508 /* counting SA except of dead one. */ 509 n = 0; 510 while (msg < end) { 511 if (PFKEY_UNUNIT64(msg->sadb_msg_len) < sizeof(*msg)) 512 break; 513 next = (struct sadb_msg *)((caddr_t)msg + PFKEY_UNUNIT64(msg->sadb_msg_len)); 514 if (msg->sadb_msg_type != SADB_DUMP) { 515 msg = next; 516 continue; 517 } 518 519 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { 520 plog(LLV_ERROR, LOCATION, NULL, 521 "pfkey_check (%s)\n", ipsec_strerror()); 522 msg = next; 523 continue; 524 } 525 526 sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]); 527 if (!sa) { 528 msg = next; 529 continue; 530 } 531 532 if (sa->sadb_sa_state != SADB_SASTATE_DEAD) { 533 n++; 534 msg = next; 535 continue; 536 } 537 538 msg = next; 539 } 540 541 if (buf != NULL) 542 vfree(buf); 543 544 if (n) { 545 sched_new(1, check_flushsa_stub, NULL); 546 return; 547 } 548 549 close_session(); 550} 551 552static void 553init_signal() 554{ 555 int i; 556 557 for (i = 0; signals[i] != 0; i++) 558 if (set_signal(signals[i], signal_handler) < 0) { 559 plog(LLV_ERROR, LOCATION, NULL, 560 "failed to set_signal (%s)\n", 561 strerror(errno)); 562 exit(1); 563 } 564} 565 566static int 567set_signal(sig, func) 568 int sig; 569 RETSIGTYPE (*func) __P((int)); 570{ 571 struct sigaction sa; 572 573 memset((caddr_t)&sa, 0, sizeof(sa)); 574 sa.sa_handler = func; 575 sa.sa_flags = SA_RESTART; 576 577 if (sigemptyset(&sa.sa_mask) < 0) 578 return -1; 579 580 if (sigaction(sig, &sa, (struct sigaction *)0) < 0) 581 return(-1); 582 583 return 0; 584} 585 586static int 587close_sockets() 588{ 589 isakmp_close(); 590 pfkey_close(lcconf->sock_pfkey); 591#ifdef ENABLE_ADMINPORT 592 (void)admin_close(); 593#endif 594 return 0; 595} 596 597