1 /* $NetBSD: session.c,v 1.25 2009/04/21 18:38:32 tteras Exp $ */
3 /* $KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $ */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
36 #include <sys/types.h>
37 #include <sys/param.h>
39 #include <sys/socket.h>
41 # include <sys/wait.h>
44 # define WEXITSTATUS(s) ((unsigned)(s) >> 8)
47 # define WIFEXITED(s) (((s) & 255) == 0)
64 #include <netinet/in.h>
77 #include "grabmyaddr.h"
79 #include "cfparse_proto.h"
80 #include "isakmp_var.h"
82 #include "isakmp_var.h"
83 #include "isakmp_xauth.h"
84 #include "isakmp_cfg.h"
85 #include "admin_var.h"
91 #include "localconf.h"
92 #include "remoteconf.h"
94 #include "remoteconf.h"
96 #include "nattraversal.h"
99 #include "algorithm.h" /* XXX ??? */
104 int (*callback
)(void *ctx
, int fd
);
108 static void close_session
__P((void));
109 static void initfds
__P((void));
110 static void init_signal
__P((void));
111 static int set_signal
__P((int sig
, RETSIGTYPE (*func
) __P((int))));
112 static void check_sigreq
__P((void));
113 static void check_flushsa
__P((void));
114 static int close_sockets
__P((void));
116 static fd_set preset_mask
, active_mask
;
117 static struct fd_monitor fd_monitors
[FD_SETSIZE
];
120 static volatile sig_atomic_t sigreq
[NSIG
+ 1];
121 static struct sched scflushsa
= SCHED_INITIALIZER();
124 monitor_fd(int fd
, int (*callback
)(void *, int), void *ctx
)
126 if (fd
< 0 || fd
>= FD_SETSIZE
) {
127 plog(LLV_ERROR
, LOCATION
, NULL
, "fd_set overrun");
131 FD_SET(fd
, &preset_mask
);
135 fd_monitors
[fd
].callback
= callback
;
136 fd_monitors
[fd
].ctx
= ctx
;
142 if (fd
< 0 || fd
>= FD_SETSIZE
) {
143 plog(LLV_ERROR
, LOCATION
, NULL
, "fd_set overrun");
147 FD_CLR(fd
, &preset_mask
);
148 FD_CLR(fd
, &active_mask
);
149 fd_monitors
[fd
].callback
= NULL
;
150 fd_monitors
[fd
].ctx
= NULL
;
156 struct timeval
*timeout
;
158 char pid_file
[MAXPATHLEN
];
160 pid_t racoon_pid
= 0;
164 FD_ZERO(&preset_mask
);
166 /* initialize schedular */
170 if (pfkey_init() < 0)
171 errx(1, "failed to initialize pfkey socket");
173 #ifdef ENABLE_ADMINPORT
174 if (admin_init() < 0)
175 errx(1, "failed to initialize admin port socket");
178 if (isakmp_init() < 0)
179 errx(1, "failed to initialize ISAKMP structures");
182 if (isakmp_cfg_init(ISAKMP_CFG_INIT_COLD
))
183 errx(1, "could not initialize ISAKMP mode config structures");
187 if (xauth_ldap_init_conf() != 0)
188 errx(1, "could not initialize ldap config");
191 #ifdef HAVE_LIBRADIUS
192 if (xauth_radius_init_conf(0) != 0)
193 errx(1, "could not initialize radius config");
199 * in order to prefer the parameters by command line,
200 * saving some parameters before parsing configuration file.
204 errx(1, "failed to parse configuration file.");
208 if(isakmp_cfg_config
.network4
&& isakmp_cfg_config
.pool_size
== 0)
209 if ((error
= isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX
)) != 0)
216 #ifdef HAVE_LIBRADIUS
217 if (xauth_radius_init() != 0)
218 errx(1, "could not initialize libradius");
221 if (myaddr_init() != 0)
222 errx(1, "failed to listen to configured addresses");
226 natt_keepalive_init ();
229 /* write .pid file */
230 if (lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
] == NULL
)
231 strlcpy(pid_file
, _PATH_VARRUN
"racoon.pid", MAXPATHLEN
);
232 else if (lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
][0] == '/')
233 strlcpy(pid_file
, lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
], MAXPATHLEN
);
235 strlcat(pid_file
, _PATH_VARRUN
, MAXPATHLEN
);
236 strlcat(pid_file
, lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
], MAXPATHLEN
);
238 fp
= fopen(pid_file
, "w");
240 if (fchmod(fileno(fp
),
241 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
) == -1) {
242 syslog(LOG_ERR
, "%s", strerror(errno
));
247 plog(LLV_ERROR
, LOCATION
, NULL
,
248 "cannot open %s", pid_file
);
251 if (privsep_init() != 0)
255 * The fork()'ed privileged side will close its copy of fp. We wait
256 * until here to get the correct child pid.
258 racoon_pid
= getpid();
259 fprintf(fp
, "%ld\n", (long)racoon_pid
);
262 for (i
= 0; i
<= NSIG
; i
++)
267 * asynchronous requests via signal.
268 * make sure to reset sigreq to 0.
273 timeout
= schedular();
275 /* schedular can change select() mask, so we reset
276 * the working copy here */
277 active_mask
= preset_mask
;
279 error
= select(nfds
+ 1, &active_mask
, NULL
, NULL
, timeout
);
285 plog(LLV_ERROR
, LOCATION
, NULL
,
286 "failed to select (%s)\n",
293 for (i
= 0; i
<= nfds
; i
++) {
294 if (!FD_ISSET(i
, &active_mask
))
297 if (fd_monitors
[i
].callback
!= NULL
)
298 fd_monitors
[i
].callback(fd_monitors
[i
].ctx
, i
);
300 plog(LLV_ERROR
, LOCATION
, NULL
,
301 "fd %d set, but no active callback\n", i
);
306 /* clear all status and exit program. */
310 evt_generic(EVT_RACOON_QUIT
, NULL
);
311 pfkey_send_flush(lcconf
->sock_pfkey
, SADB_SATYPE_UNSPEC
);
317 plog(LLV_INFO
, LOCATION
, NULL
, "racoon process %d shutdown\n", getpid());
322 static int signals
[] = {
333 * asynchronous requests will actually dispatched in the
334 * main loop in session().
344 /* XXX possible mem leaks and no way to go back for now !!!
346 static void reload_conf(){
350 if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM
)) != 0) {
351 plog(LLV_ERROR
, LOCATION
, NULL
,
352 "ISAKMP mode config structure reset failed, "
360 /* TODO: save / restore / flush old lcconf (?) / rmtree
365 #ifdef HAVE_LIBRADIUS
366 /* free and init radius configuration */
367 xauth_radius_init_conf(1);
376 plog(LLV_ERROR
, LOCATION
, NULL
, "config reload failed\n");
377 /* We are probably in an inconsistant state... */
389 #ifdef HAVE_LIBRADIUS
390 /* re-initialize radius state */
394 /* Revalidate ph1 / ph2tree !!!
395 * update ctdtree if removing some ph1 !
401 save_sainfotree_flush();
410 for (sig
= 0; sig
<= NSIG
; sig
++) {
411 if (sigreq
[sig
] == 0)
420 /* Reap all pending children */
421 while (waitpid(-1, &s
, WNOHANG
) > 0)
425 #ifdef DEBUG_RECORD_MALLOCATION
427 * XXX This operation is signal handler unsafe and may lead to
428 * crashes and security breaches: See Henning Brauer talk at
429 * EuroBSDCon 2005. Do not run in production with this option
438 /* Save old configuration, load new one... */
444 plog(LLV_INFO
, LOCATION
, NULL
,
445 "caught signal %d\n", sig
);
450 plog(LLV_INFO
, LOCATION
, NULL
,
451 "caught signal %d\n", sig
);
463 * Ignore SIGPIPE as we check the return value of system calls
464 * that write to pipe-like fds.
466 signal(SIGPIPE
, SIG_IGN
);
468 for (i
= 0; signals
[i
] != 0; i
++)
469 if (set_signal(signals
[i
], signal_handler
) < 0) {
470 plog(LLV_ERROR
, LOCATION
, NULL
,
471 "failed to set_signal (%s)\n",
478 set_signal(sig
, func
)
480 RETSIGTYPE (*func
) __P((int));
484 memset((caddr_t
)&sa
, 0, sizeof(sa
));
485 sa
.sa_handler
= func
;
486 sa
.sa_flags
= SA_RESTART
;
488 if (sigemptyset(&sa
.sa_mask
) < 0)
491 if (sigaction(sig
, &sa
, (struct sigaction
*)0) < 0)
501 pfkey_close(lcconf
->sock_pfkey
);
502 #ifdef ENABLE_ADMINPORT