]>
git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/session.c
1 /* $KAME: session.c,v 1.32 2003/09/24 02:01:17 jinmei Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <sys/types.h>
35 #include <sys/param.h>
37 #include <sys/socket.h>
39 # include <sys/wait.h>
42 # define WEXITSTATUS(s) ((unsigned)(s) >> 8)
45 # define WIFEXITED(s) (((s) & 255) == 0)
48 #ifndef HAVE_NETINET6_IPSEC
49 #include <netinet/ipsec.h>
51 #include <netinet6/ipsec.h>
75 #include "grabmyaddr.h"
77 #include "cfparse_proto.h"
78 #include "isakmp_var.h"
79 #include "admin_var.h"
85 #include "localconf.h"
86 #include "remoteconf.h"
89 #include "nattraversal.h"
91 #include "vpn_control_var.h"
94 extern pid_t racoon_pid
;
95 static void close_session
__P((void));
96 static void check_rtsock
__P((void *));
97 static void initfds
__P((void));
98 static void init_signal
__P((void));
99 static int set_signal
__P((int sig
, RETSIGTYPE (*func
) __P((int))));
100 static void check_sigreq
__P((void));
101 static void check_flushsa_stub
__P((void *));
102 static void check_flushsa
__P((void));
103 static void auto_exit_do
__P((void *));
104 static int close_sockets
__P((void));
107 static fd_set maskdying
;
109 static volatile sig_atomic_t sigreq
[NSIG
+ 1];
110 static int dying
= 0;
111 static struct sched
*check_rtsock_sched
= NULL
;
117 struct timeval
*timeout
;
120 char pid_file
[MAXPATHLEN
];
124 /* initialize schedular */
129 if (isakmp_init() < 0) {
130 plog(LLV_ERROR2
, LOCATION
, NULL
,
131 "failed to initialize isakmp");
135 #ifdef ENABLE_ADMINPORT
136 if (admin_init() < 0) {
137 plog(LLV_ERROR2
, LOCATION
, NULL
,
138 "failed to initialize admin port");
142 #ifdef ENABLE_VPNCONTROL_PORT
143 if (vpncontrol_init() < 0) {
144 plog(LLV_ERROR2
, LOCATION
, NULL
,
145 "failed to initialize vpn control port");
155 natt_keepalive_init ();
159 if (privsep_init() != 0) {
160 plog(LLV_ERROR2
, LOCATION
, NULL
,
161 "failed to initialize privsep");
165 for (i
= 0; i
<= NSIG
; i
++)
168 /* write .pid file */
170 racoon_pid
= getpid();
171 if (lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
] == NULL
)
172 strlcpy(pid_file
, _PATH_VARRUN
"racoon.pid", MAXPATHLEN
);
173 else if (lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
][0] == '/')
174 strlcpy(pid_file
, lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
], MAXPATHLEN
);
176 strlcat(pid_file
, _PATH_VARRUN
, MAXPATHLEN
);
177 strlcat(pid_file
, lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
], MAXPATHLEN
);
179 fp
= fopen(pid_file
, "w");
181 if (fchmod(fileno(fp
),
182 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
) == -1) {
183 syslog(LOG_ERR
, "%s", strerror(errno
));
187 fprintf(fp
, "%ld\n", (long)racoon_pid
);
190 plog(LLV_ERROR
, LOCATION
, NULL
,
191 "cannot open %s", pid_file
);
198 * asynchronous requests via signal.
199 * make sure to reset sigreq to 0.
204 timeout
= schedular();
210 error
= select(nfds
, &rfds
, (fd_set
*)0, (fd_set
*)0, timeout
);
216 plog(LLV_ERROR2
, LOCATION
, NULL
,
217 "failed select (%s)\n",
224 #ifdef ENABLE_ADMINPORT
225 if ((lcconf
->sock_admin
!= -1) &&
226 (FD_ISSET(lcconf
->sock_admin
, &rfds
)))
229 #ifdef ENABLE_VPNCONTROL_PORT
231 struct vpnctl_socket_elem
*elem
;
232 struct vpnctl_socket_elem
*t_elem
;
234 if ((lcconf
->sock_vpncontrol
!= -1) &&
235 (FD_ISSET(lcconf
->sock_vpncontrol
, &rfds
))) {
236 vpncontrol_handler();
237 update_fds
= 1; // in case new socket created - update mask
239 /* The handler may close and remove the list element
240 * so we can't rely on it being valid after calling
243 LIST_FOREACH_SAFE(elem
, &lcconf
->vpnctl_comm_socks
, chain
, t_elem
) {
244 if ((elem
->sock
!= -1) &&
245 (FD_ISSET(elem
->sock
, &rfds
)))
246 if (vpncontrol_comm_handler(elem
))
247 update_fds
= 1; // socket closed by peer - update mask
252 for (p
= lcconf
->myaddrs
; p
; p
= p
->next
) {
255 if (FD_ISSET(p
->sock
, &rfds
))
256 if ((error
= isakmp_handler(p
->sock
)) == -2)
260 if (lcconf
->autograbaddr
) {
261 /* serious socket problem - close all listening sockets and re-open */
264 sched_new(5, check_rtsock
, NULL
);
267 isakmp_close_sockets();
274 if (FD_ISSET(lcconf
->sock_pfkey
, &rfds
))
277 if (lcconf
->rtsock
>= 0 && FD_ISSET(lcconf
->rtsock
, &rfds
)) {
278 if (update_myaddrs() && lcconf
->autograbaddr
)
279 if (check_rtsock_sched
== NULL
) /* only schedule if not already done */
280 check_rtsock_sched
= sched_new(5, check_rtsock
, NULL
);
281 // initfds(); //%%% BUG FIX - not needed here
291 /* clear all status and exit program. */
299 plog(LLV_INFO
, LOCATION
, NULL
, "racoon shutdown\n");
308 check_rtsock_sched
= NULL
;
310 isakmp_close_unused();
312 autoconf_myaddrsport();
315 /* initialize socket list again */
329 #ifdef ENABLE_ADMINPORT
330 if (lcconf
->sock_admin
!= -1) {
331 if (lcconf
->sock_admin
>= FD_SETSIZE
) {
332 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - admin socket\n");
335 FD_SET(lcconf
->sock_admin
, &mask0
);
336 /* XXX should we listen on admin socket when dying ?
339 FD_SET(lcconf
->sock_admin
, &maskdying
);
341 nfds
= (nfds
> lcconf
->sock_admin
? nfds
: lcconf
->sock_admin
);
344 #ifdef ENABLE_VPNCONTROL_PORT
346 struct vpnctl_socket_elem
*elem
;
348 if (lcconf
->sock_vpncontrol
!= -1) {
349 if (lcconf
->sock_vpncontrol
>= FD_SETSIZE
) {
350 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - vpncontrol socket\n");
353 FD_SET(lcconf
->sock_vpncontrol
, &mask0
);
354 nfds
= (nfds
> lcconf
->sock_vpncontrol
? nfds
: lcconf
->sock_vpncontrol
);
357 LIST_FOREACH(elem
, &lcconf
->vpnctl_comm_socks
, chain
) {
358 if (elem
->sock
!= -1) {
359 if (elem
->sock
>= FD_SETSIZE
) {
360 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun vpnctl_comm socket\n");
363 FD_SET(elem
->sock
, &mask0
);
364 nfds
= (nfds
> elem
->sock
? nfds
: elem
->sock
);
371 if (lcconf
->sock_pfkey
>= FD_SETSIZE
) {
372 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - pfkey socket\n");
375 FD_SET(lcconf
->sock_pfkey
, &mask0
);
376 FD_SET(lcconf
->sock_pfkey
, &maskdying
);
377 nfds
= (nfds
> lcconf
->sock_pfkey
? nfds
: lcconf
->sock_pfkey
);
378 if (lcconf
->rtsock
>= 0) {
379 if (lcconf
->rtsock
>= FD_SETSIZE
) {
380 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - rt socket\n");
383 FD_SET(lcconf
->rtsock
, &mask0
);
384 nfds
= (nfds
> lcconf
->rtsock
? nfds
: lcconf
->rtsock
);
387 for (p
= lcconf
->myaddrs
; p
; p
= p
->next
) {
392 if (p
->sock
>= FD_SETSIZE
) {
393 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - isakmp socket\n");
396 FD_SET(p
->sock
, &mask0
);
397 nfds
= (nfds
> p
->sock
? nfds
: p
->sock
);
402 static int signals
[] = {
414 * asynchronous requests will actually dispatched in the
415 * main loop in session().
421 /* Do not just set it to 1, because we may miss some signals by just setting
433 * XXX We are not able to tell if we got
434 * several time the same signal. This is
435 * not a problem for the current code,
436 * but we shall remember this limitation.
438 for (sig
= 0; sig
<= NSIG
; sig
++) {
439 if (sigreq
[sig
] == 0)
447 /* Catch up childs, mainly scripts.
458 #ifdef DEBUG_RECORD_MALLOCATION
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
471 /* Save old configuration, load new one... */
473 close(lcconf
->rtsock
);
475 plog(LLV_ERROR2
, LOCATION
, NULL
,
476 "configuration read failed\n");
479 if (lcconf
->logfile_param
== NULL
)
480 plogreset(lcconf
->pathinfo
[LC_PATHTYPE_LOGFILE
]);
490 plog(LLV_INFO
, LOCATION
, NULL
,
491 "caught signal %d\n", sig
);
492 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
493 pfkey_send_flush(lcconf
->sock_pfkey
,
495 sched_new(1, check_flushsa_stub
, NULL
);
500 plog(LLV_INFO
, LOCATION
, NULL
,
501 "caught signal %d\n", sig
);
508 * waiting the termination of processing until sending DELETE message
509 * for all inbound SA will complete.
512 check_flushsa_stub(p
)
523 struct sadb_msg
*msg
, *end
, *next
;
525 caddr_t mhp
[SADB_EXT_MAX
+ 1];
528 buf
= pfkey_dump_sadb(SADB_SATYPE_UNSPEC
);
530 plog(LLV_DEBUG
, LOCATION
, NULL
,
531 "pfkey_dump_sadb: returned nothing.\n");
535 msg
= (struct sadb_msg
*)buf
->v
;
536 end
= (struct sadb_msg
*)(buf
->v
+ buf
->l
);
538 /* counting SA except of dead one. */
541 if (PFKEY_UNUNIT64(msg
->sadb_msg_len
) < sizeof(*msg
))
543 next
= (struct sadb_msg
*)((caddr_t
)msg
+ PFKEY_UNUNIT64(msg
->sadb_msg_len
));
544 if (msg
->sadb_msg_type
!= SADB_DUMP
) {
549 if (pfkey_align(msg
, mhp
) || pfkey_check(mhp
)) {
550 plog(LLV_ERROR
, LOCATION
, NULL
,
551 "pfkey_check (%s)\n", ipsec_strerror());
556 sa
= (struct sadb_sa
*)(mhp
[SADB_EXT_SA
]);
562 if (sa
->sadb_sa_state
!= SADB_SASTATE_DEAD
) {
575 sched_new(1, check_flushsa_stub
, NULL
);
583 auto_exit_do(void *p
)
585 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
586 pfkey_send_flush(lcconf
->sock_pfkey
, SADB_SATYPE_UNSPEC
);
587 sched_new(1, check_flushsa_stub
, NULL
);
592 check_auto_exit(void)
595 if (lcconf
->auto_exit_sched
!= NULL
) { /* exit scheduled? */
596 if (lcconf
->auto_exit_state
!= LC_AUTOEXITSTATE_ENABLED
597 || vpn_control_connected() /* vpn control connected */
598 || policies_installed()) /* policies installed in kernel */
599 SCHED_KILL(lcconf
->auto_exit_sched
);
600 } else { /* exit not scheduled */
601 if (lcconf
->auto_exit_state
== LC_AUTOEXITSTATE_ENABLED
602 && !vpn_control_connected()
603 && !policies_installed())
604 if (lcconf
->auto_exit_delay
== 0)
605 auto_exit_do(NULL
); /* immediate exit */
607 lcconf
->auto_exit_sched
= sched_new(lcconf
->auto_exit_delay
, auto_exit_do
, NULL
);
617 for (i
= 0; signals
[i
] != 0; i
++)
618 if (set_signal(signals
[i
], signal_handler
) < 0) {
619 plog(LLV_ERROR2
, LOCATION
, NULL
,
620 "failed to set_signal (%s)\n",
627 set_signal(sig
, func
)
629 RETSIGTYPE (*func
) __P((int));
633 memset((caddr_t
)&sa
, 0, sizeof(sa
));
634 sa
.sa_handler
= func
;
635 sa
.sa_flags
= SA_RESTART
;
637 if (sigemptyset(&sa
.sa_mask
) < 0)
640 if (sigaction(sig
, &sa
, (struct sigaction
*)0) < 0)
650 pfkey_close(lcconf
->sock_pfkey
);
651 #ifdef ENABLE_ADMINPORT
654 #ifdef ENABLE_VPNCONTROL_PORT