]>
git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/session.c
1 /* $NetBSD: session.c,v 1.7.6.2 2007/08/01 11:52:22 vanhu 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)
50 #ifndef HAVE_NETINET6_IPSEC
51 #include <netinet/ipsec.h>
53 #include <netinet6/ipsec.h>
67 #include <netinet/in.h>
68 #include <netinet/ip.h>
69 #include <netinet/ip_icmp.h>
72 #include <TargetConditionals.h>
84 #include "grabmyaddr.h"
86 #include "cfparse_proto.h"
87 #include "isakmp_var.h"
88 #include "isakmp_xauth.h"
89 #include "isakmp_cfg.h"
90 #include "admin_var.h"
96 #include "localconf.h"
97 #include "remoteconf.h"
100 #include "nattraversal.h"
102 #include "vpn_control_var.h"
104 #include "algorithm.h" /* XXX ??? */
110 extern pid_t racoon_pid
;
111 static void close_session
__P((void));
112 static void check_rtsock
__P((void *));
113 static void initfds
__P((void));
114 static void init_signal
__P((void));
115 static int set_signal
__P((int sig
, RETSIGTYPE (*func
) __P((int))));
116 static void check_sigreq
__P((void));
117 static void check_flushsa_stub
__P((void *));
118 static void check_flushsa
__P((void));
119 static void auto_exit_do
__P((void *));
120 static int close_sockets
__P((void));
123 static fd_set maskdying
;
125 static volatile sig_atomic_t sigreq
[NSIG
+ 1];
126 static int dying
= 0;
127 static struct sched
*check_rtsock_sched
= NULL
;
134 struct timeval
*timeout
;
137 char pid_file
[MAXPATHLEN
];
141 /* initialize schedular */
147 if (isakmp_init() < 0) {
149 if (isakmp_init(false) < 0) {
150 #endif /* __APPLE__ */
151 plog(LLV_ERROR2
, LOCATION
, NULL
,
152 "failed to initialize isakmp");
156 #ifdef ENABLE_ADMINPORT
157 if (admin_init() < 0) {
158 plog(LLV_ERROR2
, LOCATION
, NULL
,
159 "failed to initialize admin port");
163 #ifdef ENABLE_VPNCONTROL_PORT
164 if (vpncontrol_init() < 0) {
165 plog(LLV_ERROR2
, LOCATION
, NULL
,
166 "failed to initialize vpn control port");
177 natt_keepalive_init ();
181 if (privsep_init() != 0) {
182 plog(LLV_ERROR2
, LOCATION
, NULL
,
183 "failed to initialize privsep");
187 for (i
= 0; i
<= NSIG
; i
++)
190 /* write .pid file */
192 racoon_pid
= getpid();
193 if (lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
] == NULL
)
194 strlcpy(pid_file
, _PATH_VARRUN
"racoon.pid", sizeof(pid_file
));
195 else if (lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
][0] == '/')
196 strlcpy(pid_file
, lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
], sizeof(pid_file
));
198 strlcat(pid_file
, _PATH_VARRUN
, sizeof(pid_file
));
199 strlcat(pid_file
, lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
], sizeof(pid_file
));
201 fp
= fopen(pid_file
, "w");
203 if (fchmod(fileno(fp
),
204 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
) == -1) {
205 syslog(LOG_ERR
, "%s", strerror(errno
));
209 fprintf(fp
, "%ld\n", (long)racoon_pid
);
212 plog(LLV_ERROR
, LOCATION
, NULL
,
213 "cannot open %s", pid_file
);
218 if (!TAILQ_EMPTY(&lcconf
->saved_msg_queue
))
219 pfkey_post_handler();
222 * asynchronous requests via signal.
223 * make sure to reset sigreq to 0.
228 timeout
= schedular();
234 error
= select(nfds
, &rfds
, (fd_set
*)0, (fd_set
*)0, timeout
);
240 plog(LLV_ERROR2
, LOCATION
, NULL
,
241 "failed select (%s)\n",
243 /* serious socket problem - close all listening sockets and re-open */
244 if (lcconf
->autograbaddr
) {
247 sched_new(5, check_rtsock
, NULL
);
249 isakmp_close_sockets();
258 #ifdef ENABLE_ADMINPORT
259 if ((lcconf
->sock_admin
!= -1) &&
260 (FD_ISSET(lcconf
->sock_admin
, &rfds
)))
263 #ifdef ENABLE_VPNCONTROL_PORT
265 struct vpnctl_socket_elem
*elem
;
266 struct vpnctl_socket_elem
*t_elem
;
268 if ((lcconf
->sock_vpncontrol
!= -1) &&
269 (FD_ISSET(lcconf
->sock_vpncontrol
, &rfds
))) {
270 vpncontrol_handler();
271 update_fds
= 1; // in case new socket created - update mask
273 /* The handler may close and remove the list element
274 * so we can't rely on it being valid after calling
277 LIST_FOREACH_SAFE(elem
, &lcconf
->vpnctl_comm_socks
, chain
, t_elem
) {
278 if ((elem
->sock
!= -1) &&
279 (FD_ISSET(elem
->sock
, &rfds
)))
280 if (vpncontrol_comm_handler(elem
))
281 update_fds
= 1; // socket closed by peer - update mask
286 for (p
= lcconf
->myaddrs
; p
; p
= p
->next
) {
289 if (FD_ISSET(p
->sock
, &rfds
))
290 if ((error
= isakmp_handler(p
->sock
)) == -2)
294 if (lcconf
->autograbaddr
) {
295 /* serious socket problem - close all listening sockets and re-open */
298 sched_new(5, check_rtsock
, NULL
);
301 isakmp_close_sockets();
308 if (FD_ISSET(lcconf
->sock_pfkey
, &rfds
))
311 if (lcconf
->rtsock
>= 0 && FD_ISSET(lcconf
->rtsock
, &rfds
)) {
312 if (update_myaddrs() && lcconf
->autograbaddr
)
313 if (check_rtsock_sched
== NULL
) /* only schedule if not already done */
314 check_rtsock_sched
= sched_new(5, check_rtsock
, NULL
);
315 // initfds(); //%%% BUG FIX - not needed here
325 /* clear all status and exit program. */
335 plog(LLV_INFO
, LOCATION
, NULL
, "racoon shutdown\n");
344 check_rtsock_sched
= NULL
;
346 isakmp_close_unused();
348 autoconf_myaddrsport();
351 /* initialize socket list again */
365 #ifdef ENABLE_ADMINPORT
366 if (lcconf
->sock_admin
!= -1) {
367 if (lcconf
->sock_admin
>= FD_SETSIZE
) {
368 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - admin socket\n");
371 FD_SET(lcconf
->sock_admin
, &mask0
);
372 /* XXX should we listen on admin socket when dying ?
375 FD_SET(lcconf
->sock_admin
, &maskdying
);
377 nfds
= (nfds
> lcconf
->sock_admin
? nfds
: lcconf
->sock_admin
);
380 #ifdef ENABLE_VPNCONTROL_PORT
382 struct vpnctl_socket_elem
*elem
;
384 if (lcconf
->sock_vpncontrol
!= -1) {
385 if (lcconf
->sock_vpncontrol
>= FD_SETSIZE
) {
386 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - vpncontrol socket\n");
389 FD_SET(lcconf
->sock_vpncontrol
, &mask0
);
390 nfds
= (nfds
> lcconf
->sock_vpncontrol
? nfds
: lcconf
->sock_vpncontrol
);
393 LIST_FOREACH(elem
, &lcconf
->vpnctl_comm_socks
, chain
) {
394 if (elem
->sock
!= -1) {
395 if (elem
->sock
>= FD_SETSIZE
) {
396 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun vpnctl_comm socket\n");
399 FD_SET(elem
->sock
, &mask0
);
400 nfds
= (nfds
> elem
->sock
? nfds
: elem
->sock
);
406 if (lcconf
->sock_pfkey
>= FD_SETSIZE
) {
407 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - pfkey socket\n");
410 FD_SET(lcconf
->sock_pfkey
, &mask0
);
411 FD_SET(lcconf
->sock_pfkey
, &maskdying
);
412 nfds
= (nfds
> lcconf
->sock_pfkey
? nfds
: lcconf
->sock_pfkey
);
413 if (lcconf
->rtsock
>= 0) {
414 if (lcconf
->rtsock
>= FD_SETSIZE
) {
415 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - rt socket\n");
418 FD_SET(lcconf
->rtsock
, &mask0
);
419 nfds
= (nfds
> lcconf
->rtsock
? nfds
: lcconf
->rtsock
);
422 for (p
= lcconf
->myaddrs
; p
; p
= p
->next
) {
427 if (p
->sock
>= FD_SETSIZE
) {
428 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - isakmp socket\n");
431 FD_SET(p
->sock
, &mask0
);
432 nfds
= (nfds
> p
->sock
? nfds
: p
->sock
);
438 static int signals
[] = {
450 * asynchronous requests will actually dispatched in the
451 * main loop in session().
457 /* Do not just set it to 1, because we may miss some signals by just setting
461 if ( sig
== SIGTERM
){
472 * XXX We are not able to tell if we got
473 * several time the same signal. This is
474 * not a problem for the current code,
475 * but we shall remember this limitation.
477 for (sig
= 0; sig
<= NSIG
; sig
++) {
478 if (sigreq
[sig
] == 0)
486 /* Catch up childs, mainly scripts.
497 #ifdef DEBUG_RECORD_MALLOCATION
499 * XXX This operation is signal handler unsafe and may lead to
500 * crashes and security breaches: See Henning Brauer talk at
501 * EuroBSDCon 2005. Do not run in production with this option
512 if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM
)) != 0) {
513 plog(LLV_ERROR
, LOCATION
, NULL
,
514 "ISAKMP mode config structure reset failed, "
522 /* Save old configuration, load new one... */
524 close(lcconf
->rtsock
);
525 if (cfreparse(sig
)) {
526 plog(LLV_ERROR2
, LOCATION
, NULL
,
527 "configuration read failed\n");
530 if (lcconf
->logfile_param
== NULL
)
531 plogreset(lcconf
->pathinfo
[LC_PATHTYPE_LOGFILE
]);
539 #endif /* __APPLE__ */
541 #if TARGET_OS_EMBEDDED
542 if (no_remote_configs()) {
543 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
544 pfkey_send_flush(lcconf
->sock_pfkey
, SADB_SATYPE_UNSPEC
);
545 #ifdef ENABLE_FASTQUIT
548 sched_new(1, check_flushsa_stub
, NULL
);
557 plog(LLV_INFO
, LOCATION
, NULL
,
558 "caught signal %d\n", sig
);
559 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
560 pfkey_send_flush(lcconf
->sock_pfkey
,
562 if ( sig
== SIGTERM
){
563 terminated
= 1; /* in case if it hasn't been set yet */
567 sched_new(1, check_flushsa_stub
, NULL
);
573 plog(LLV_INFO
, LOCATION
, NULL
,
574 "caught signal %d\n", sig
);
581 * waiting the termination of processing until sending DELETE message
582 * for all inbound SA will complete.
585 check_flushsa_stub(p
)
596 struct sadb_msg
*msg
, *end
, *next
;
598 caddr_t mhp
[SADB_EXT_MAX
+ 1];
601 buf
= pfkey_dump_sadb(SADB_SATYPE_UNSPEC
);
603 plog(LLV_DEBUG
, LOCATION
, NULL
,
604 "pfkey_dump_sadb: returned nothing.\n");
608 msg
= (struct sadb_msg
*)buf
->v
;
609 end
= (struct sadb_msg
*)(buf
->v
+ buf
->l
);
611 /* counting SA except of dead one. */
614 if (PFKEY_UNUNIT64(msg
->sadb_msg_len
) < sizeof(*msg
))
616 next
= (struct sadb_msg
*)((caddr_t
)msg
+ PFKEY_UNUNIT64(msg
->sadb_msg_len
));
617 if (msg
->sadb_msg_type
!= SADB_DUMP
) {
622 if (pfkey_align(msg
, mhp
) || pfkey_check(mhp
)) {
623 plog(LLV_ERROR
, LOCATION
, NULL
,
624 "pfkey_check (%s)\n", ipsec_strerror());
629 sa
= (struct sadb_sa
*)(mhp
[SADB_EXT_SA
]);
635 if (sa
->sadb_sa_state
!= SADB_SASTATE_DEAD
) {
648 sched_new(1, check_flushsa_stub
, NULL
);
653 #if !TARGET_OS_EMBEDDED
655 vproc_transaction_end(NULL
, lcconf
->vt
);
660 auto_exit_do(void *p
)
662 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
663 plog(LLV_DEBUG
, LOCATION
, NULL
,
664 "performing auto exit\n");
665 pfkey_send_flush(lcconf
->sock_pfkey
, SADB_SATYPE_UNSPEC
);
666 sched_new(1, check_flushsa_stub
, NULL
);
671 check_auto_exit(void)
673 if (lcconf
->auto_exit_sched
!= NULL
) { /* exit scheduled? */
674 if (lcconf
->auto_exit_state
!= LC_AUTOEXITSTATE_ENABLED
675 || vpn_control_connected() /* vpn control connected */
676 || policies_installed()) /* policies installed in kernel */
677 SCHED_KILL(lcconf
->auto_exit_sched
);
678 } else { /* exit not scheduled */
679 if (lcconf
->auto_exit_state
== LC_AUTOEXITSTATE_ENABLED
680 && !vpn_control_connected()
681 && !policies_installed())
682 if (lcconf
->auto_exit_delay
== 0)
683 auto_exit_do(NULL
); /* immediate exit */
685 lcconf
->auto_exit_sched
= sched_new(lcconf
->auto_exit_delay
, auto_exit_do
, NULL
);
695 for (i
= 0; signals
[i
] != 0; i
++)
696 if (set_signal(signals
[i
], signal_handler
) < 0) {
697 plog(LLV_ERROR2
, LOCATION
, NULL
,
698 "failed to set_signal (%s)\n",
705 set_signal(sig
, func
)
707 RETSIGTYPE (*func
) __P((int));
711 memset((caddr_t
)&sa
, 0, sizeof(sa
));
712 sa
.sa_handler
= func
;
713 sa
.sa_flags
= SA_RESTART
;
715 if (sigemptyset(&sa
.sa_mask
) < 0)
718 if (sigaction(sig
, &sa
, (struct sigaction
*)0) < 0)
728 pfkey_close(lcconf
->sock_pfkey
);
729 #ifdef ENABLE_ADMINPORT
732 #ifdef ENABLE_VPNCONTROL_PORT