1 /* $NetBSD: session.c,v 1.5 2005/11/21 14:20:29 manu 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 #ifndef HAVE_NETINET6_IPSEC 51 #include <netinet/ipsec.h> 52 #else 53 #include <netinet6/ipsec.h> 54 #endif 55 56 #include <stdlib.h> 57 #include <stdio.h> 58 #include <string.h> 59 #include <errno.h> 60 #ifdef HAVE_UNISTD_H 61 #include <unistd.h> 62 #endif 63 #include <signal.h> 64 #include <sys/stat.h> 65 #include <paths.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 "admin_var.h" 82 #include "admin.h" 83 #include "privsep.h" 84 #include "oakley.h" 85 #include "pfkey.h" 86 #include "handler.h" 87 #include "localconf.h" 88 #include "remoteconf.h" 89 #include "backupsa.h" 90 #ifdef ENABLE_NATT 91 #include "nattraversal.h" 92 #endif 93 94 static void close_session __P((void)); 95 static void check_rtsock __P((void *)); 96 static void initfds __P((void)); 97 static void init_signal __P((void)); 98 static int set_signal __P((int sig, RETSIGTYPE (*func) __P((int)))); 99 static void check_sigreq __P((void)); 100 static void check_flushsa_stub __P((void *)); 101 static void check_flushsa __P((void)); 102 static int close_sockets __P((void)); 103 104 static fd_set mask0; 105 static fd_set maskdying; 106 static int nfds = 0; 107 static int sigreq = 0; 108 static int dying = 0; 109 110 int 111 session(void) 112 { 113 fd_set rfds; 114 struct timeval *timeout; 115 int error; 116 struct myaddrs *p; 117 char pid_file[MAXPATHLEN]; 118 FILE *fp; 119 pid_t racoon_pid = 0; 120 121 /* initialize schedular */ 122 sched_init(); 123 124 init_signal(); 125 126 #ifdef ENABLE_ADMINPORT 127 if (admin_init() < 0) 128 exit(1); 129 #endif 130 131 initmyaddr(); 132 133 if (isakmp_init() < 0) 134 exit(1); 135 136 initfds(); 137 138 #ifdef ENABLE_NATT 139 natt_keepalive_init (); 140 #endif 141 142 if (privsep_init() != 0) 143 exit(1); 144 145 sigreq = 0; 146 147 /* write .pid file */ 148 racoon_pid = getpid(); 149 if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE] == NULL) 150 strlcpy(pid_file, _PATH_VARRUN "racoon.pid", MAXPATHLEN); 151 else if (lcconf->pathinfo[LC_PATHTYPE_PIDFILE][0] == '/') 152 strlcpy(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); 153 else { 154 strlcat(pid_file, _PATH_VARRUN, MAXPATHLEN); 155 strlcat(pid_file, lcconf->pathinfo[LC_PATHTYPE_PIDFILE], MAXPATHLEN); 156 } 157 fp = fopen(pid_file, "w"); 158 if (fp) { 159 if (fchmod(fileno(fp), 160 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 161 syslog(LOG_ERR, "%s", strerror(errno)); 162 fclose(fp); 163 exit(1); 164 } 165 fprintf(fp, "%ld\n", (long)racoon_pid); 166 fclose(fp); 167 } else { 168 plog(LLV_ERROR, LOCATION, NULL, 169 "cannot open %s", pid_file); 170 } 171 172 while (1) { 173 if (dying) 174 rfds = maskdying; 175 else 176 rfds = mask0; 177 178 /* 179 * asynchronous requests via signal. 180 * make sure to reset sigreq to 0. 181 */ 182 check_sigreq(); 183 184 /* scheduling */ 185 timeout = schedular(); 186 187 error = select(nfds, &rfds, (fd_set *)0, (fd_set *)0, timeout); 188 if (error < 0) { 189 switch (errno) { 190 case EINTR: 191 continue; 192 default: 193 plog(LLV_ERROR, LOCATION, NULL, 194 "failed to select (%s)\n", 195 strerror(errno)); 196 return -1; 197 } 198 /*NOTREACHED*/ 199 } 200 201 #ifdef ENABLE_ADMINPORT 202 if ((lcconf->sock_admin != -1) && 203 (FD_ISSET(lcconf->sock_admin, &rfds))) 204 admin_handler(); 205 #endif 206 207 for (p = lcconf->myaddrs; p; p = p->next) { 208 if (!p->addr) 209 continue; 210 if (FD_ISSET(p->sock, &rfds)) 211 isakmp_handler(p->sock); 212 } 213 214 if (FD_ISSET(lcconf->sock_pfkey, &rfds)) 215 pfkey_handler(); 216 217 if (lcconf->rtsock >= 0 && FD_ISSET(lcconf->rtsock, &rfds)) { 218 if (update_myaddrs() && lcconf->autograbaddr) 219 sched_new(5, check_rtsock, NULL); 220 initfds(); 221 } 222 } 223 } 224 225 /* clear all status and exit program. */ 226 static void 227 close_session() 228 { 229 flushph1(); 230 close_sockets(); 231 backupsa_clean(); 232 233 plog(LLV_INFO, LOCATION, NULL, "racoon shutdown\n"); 234 exit(0); 235 } 236 237 static void 238 check_rtsock(p) 239 void *p; 240 { 241 isakmp_close(); 242 grab_myaddrs(); 243 autoconf_myaddrsport(); 244 isakmp_open(); 245 246 /* initialize socket list again */ 247 initfds(); 248 } 249 250 static void 251 initfds() 252 { 253 struct myaddrs *p; 254 255 nfds = 0; 256 257 FD_ZERO(&mask0); 258 FD_ZERO(&maskdying); 259 260 #ifdef ENABLE_ADMINPORT 261 if (lcconf->sock_admin != -1) { 262 if (lcconf->sock_admin >= FD_SETSIZE) { 263 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n"); 264 exit(1); 265 } 266 FD_SET(lcconf->sock_admin, &mask0); 267 /* XXX should we listen on admin socket when dying ? 268 */ 269 #if 0 270 FD_SET(lcconf->sock_admin, &maskdying); 271 #endif 272 nfds = (nfds > lcconf->sock_admin ? nfds : lcconf->sock_admin); 273 } 274 #endif 275 if (lcconf->sock_pfkey >= FD_SETSIZE) { 276 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n"); 277 exit(1); 278 } 279 FD_SET(lcconf->sock_pfkey, &mask0); 280 FD_SET(lcconf->sock_pfkey, &maskdying); 281 nfds = (nfds > lcconf->sock_pfkey ? nfds : lcconf->sock_pfkey); 282 if (lcconf->rtsock >= 0) { 283 if (lcconf->rtsock >= FD_SETSIZE) { 284 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n"); 285 exit(1); 286 } 287 FD_SET(lcconf->rtsock, &mask0); 288 nfds = (nfds > lcconf->rtsock ? nfds : lcconf->rtsock); 289 } 290 291 for (p = lcconf->myaddrs; p; p = p->next) { 292 if (!p->addr) 293 continue; 294 if (p->sock >= FD_SETSIZE) { 295 plog(LLV_ERROR, LOCATION, NULL, "fd_set overrun\n"); 296 exit(1); 297 } 298 FD_SET(p->sock, &mask0); 299 nfds = (nfds > p->sock ? nfds : p->sock); 300 } 301 nfds++; 302 } 303 304 static int signals[] = { 305 SIGHUP, 306 SIGINT, 307 SIGTERM, 308 SIGUSR1, 309 SIGUSR2, 310 SIGCHLD, 311 0 312 }; 313 314 /* 315 * asynchronous requests will actually dispatched in the 316 * main loop in session(). 317 */ 318 RETSIGTYPE 319 signal_handler(sig) 320 int sig; 321 { 322 switch (sig) { 323 case SIGCHLD: 324 { 325 pid_t pid; 326 int s; 327 328 pid = wait(&s); 329 } 330 break; 331 332 #ifdef DEBUG_RECORD_MALLOCATION 333 case SIGUSR2: 334 DRM_dump(); 335 break; 336 #endif 337 default: 338 /* XXX should be blocked any signal ? */ 339 sigreq = sig; 340 break; 341 } 342 } 343 344 static void 345 check_sigreq() 346 { 347 switch (sigreq) { 348 case 0: 349 return; 350 351 case SIGHUP: 352 isakmp_close(); 353 close(lcconf->rtsock); 354 if (cfreparse()) { 355 plog(LLV_ERROR, LOCATION, NULL, 356 "configuration read failed\n"); 357 exit(1); 358 } 359 initmyaddr(); 360 isakmp_init(); 361 initfds(); 362 sigreq = 0; 363 break; 364 365 default: 366 plog(LLV_INFO, LOCATION, NULL, "caught signal %d\n", sigreq); 367 EVT_PUSH(NULL, NULL, EVTT_RACOON_QUIT, NULL); 368 pfkey_send_flush(lcconf->sock_pfkey, SADB_SATYPE_UNSPEC); 369 sched_new(1, check_flushsa_stub, NULL); 370 sigreq = 0; 371 dying = 1; 372 break; 373 } 374 } 375 376 /* 377 * waiting the termination of processing until sending DELETE message 378 * for all inbound SA will complete. 379 */ 380 static void 381 check_flushsa_stub(p) 382 void *p; 383 { 384 385 check_flushsa(); 386 } 387 388 static void 389 check_flushsa() 390 { 391 vchar_t *buf; 392 struct sadb_msg *msg, *end, *next; 393 struct sadb_sa *sa; 394 caddr_t mhp[SADB_EXT_MAX + 1]; 395 int n; 396 397 buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC); 398 if (buf == NULL) { 399 plog(LLV_DEBUG, LOCATION, NULL, 400 "pfkey_dump_sadb: returned nothing.\n"); 401 return; 402 } 403 404 msg = (struct sadb_msg *)buf->v; 405 end = (struct sadb_msg *)(buf->v + buf->l); 406 407 /* counting SA except of dead one. */ 408 n = 0; 409 while (msg < end) { 410 if (PFKEY_UNUNIT64(msg->sadb_msg_len) < sizeof(*msg)) 411 break; 412 next = (struct sadb_msg *)((caddr_t)msg + PFKEY_UNUNIT64(msg->sadb_msg_len)); 413 if (msg->sadb_msg_type != SADB_DUMP) { 414 msg = next; 415 continue; 416 } 417 418 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { 419 plog(LLV_ERROR, LOCATION, NULL, 420 "pfkey_check (%s)\n", ipsec_strerror()); 421 msg = next; 422 continue; 423 } 424 425 sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]); 426 if (!sa) { 427 msg = next; 428 continue; 429 } 430 431 if (sa->sadb_sa_state != SADB_SASTATE_DEAD) { 432 n++; 433 msg = next; 434 continue; 435 } 436 437 msg = next; 438 } 439 440 if (buf != NULL) 441 vfree(buf); 442 443 if (n) { 444 sched_new(1, check_flushsa_stub, NULL); 445 return; 446 } 447 448 close_session(); 449 } 450 451 static void 452 init_signal() 453 { 454 int i; 455 456 for (i = 0; signals[i] != 0; i++) 457 if (set_signal(signals[i], signal_handler) < 0) { 458 plog(LLV_ERROR, LOCATION, NULL, 459 "failed to set_signal (%s)\n", 460 strerror(errno)); 461 exit(1); 462 } 463 } 464 465 static int 466 set_signal(sig, func) 467 int sig; 468 RETSIGTYPE (*func) __P((int)); 469 { 470 struct sigaction sa; 471 472 memset((caddr_t)&sa, 0, sizeof(sa)); 473 sa.sa_handler = func; 474 sa.sa_flags = SA_RESTART; 475 476 if (sigemptyset(&sa.sa_mask) < 0) 477 return -1; 478 479 if (sigaction(sig, &sa, (struct sigaction *)0) < 0) 480 return(-1); 481 482 return 0; 483 } 484 485 static int 486 close_sockets() 487 { 488 isakmp_close(); 489 pfkey_close(lcconf->sock_pfkey); 490 #ifdef ENABLE_ADMINPORT 491 (void)admin_close(); 492 #endif 493 return 0; 494 } 495 496