Home | History | Annotate | Download | only in racoon
      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