]>
git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/session.c
c5c98da354a001e0d27b06ede18c08865aaf8c59
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 close(lcconf
->rtsock
);
136 if (isakmp_open() < 0) {
137 plog(LLV_ERROR2
, LOCATION
, NULL
,
138 "failed to reopen isakmp sockets\n");
147 struct timeval
*timeout
;
150 char pid_file
[MAXPATHLEN
];
154 /* initialize schedular */
160 if (isakmp_init() < 0) {
162 if (isakmp_init(false) < 0) {
163 #endif /* __APPLE__ */
164 plog(LLV_ERROR2
, LOCATION
, NULL
,
165 "failed to initialize isakmp");
169 #ifdef ENABLE_ADMINPORT
170 if (admin_init() < 0) {
171 plog(LLV_ERROR2
, LOCATION
, NULL
,
172 "failed to initialize admin port");
176 #ifdef ENABLE_VPNCONTROL_PORT
177 if (vpncontrol_init() < 0) {
178 plog(LLV_ERROR2
, LOCATION
, NULL
,
179 "failed to initialize vpn control port");
190 natt_keepalive_init ();
194 if (privsep_init() != 0) {
195 plog(LLV_ERROR2
, LOCATION
, NULL
,
196 "failed to initialize privsep");
200 for (i
= 0; i
<= NSIG
; i
++)
203 /* write .pid file */
205 racoon_pid
= getpid();
206 if (lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
] == NULL
)
207 strlcpy(pid_file
, _PATH_VARRUN
"racoon.pid", sizeof(pid_file
));
208 else if (lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
][0] == '/')
209 strlcpy(pid_file
, lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
], sizeof(pid_file
));
211 strlcat(pid_file
, _PATH_VARRUN
, sizeof(pid_file
));
212 strlcat(pid_file
, lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
], sizeof(pid_file
));
214 fp
= fopen(pid_file
, "w");
216 if (fchmod(fileno(fp
),
217 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
) == -1) {
218 syslog(LOG_ERR
, "%s", strerror(errno
));
222 fprintf(fp
, "%ld\n", (long)racoon_pid
);
225 plog(LLV_ERROR
, LOCATION
, NULL
,
226 "cannot open %s", pid_file
);
231 if (!TAILQ_EMPTY(&lcconf
->saved_msg_queue
))
232 pfkey_post_handler();
235 * asynchronous requests via signal.
236 * make sure to reset sigreq to 0.
241 timeout
= schedular();
242 // <rdar://problem/7650111> Workaround: make sure timeout is playing nice
244 if (timeout
->tv_usec
< 0 || timeout
->tv_usec
> SELECT_USEC_MAX
) {
245 timeout
->tv_sec
+= ((__typeof__(timeout
->tv_sec
))timeout
->tv_usec
)/SELECT_USEC_MAX
;
246 timeout
->tv_usec
%= SELECT_USEC_MAX
;
248 if (timeout
->tv_sec
> SELECT_SEC_MAX
/* tv_sec is unsigned */) {
249 timeout
->tv_sec
= SELECT_SEC_MAX
;
251 if (!timeout
->tv_sec
&& !timeout
->tv_usec
) {
260 error
= select(nfds
, &rfds
, (fd_set
*)0, (fd_set
*)0, timeout
);
266 plog(LLV_ERROR2
, LOCATION
, NULL
,
267 "failed select (%s) nfds %d\n",
268 strerror(errno
), nfds
);
276 #ifdef ENABLE_ADMINPORT
277 if ((lcconf
->sock_admin
!= -1) &&
278 (FD_ISSET(lcconf
->sock_admin
, &rfds
)))
281 #ifdef ENABLE_VPNCONTROL_PORT
283 struct vpnctl_socket_elem
*elem
;
284 struct vpnctl_socket_elem
*t_elem
;
286 if ((lcconf
->sock_vpncontrol
!= -1) &&
287 (FD_ISSET(lcconf
->sock_vpncontrol
, &rfds
))) {
288 vpncontrol_handler();
289 update_fds
= 1; // in case new socket created - update mask
291 /* The handler may close and remove the list element
292 * so we can't rely on it being valid after calling
295 LIST_FOREACH_SAFE(elem
, &lcconf
->vpnctl_comm_socks
, chain
, t_elem
) {
296 if ((elem
->sock
!= -1) &&
297 (FD_ISSET(elem
->sock
, &rfds
)))
298 if (vpncontrol_comm_handler(elem
))
299 update_fds
= 1; // socket closed by peer - update mask
304 for (p
= lcconf
->myaddrs
; p
; p
= p
->next
) {
307 if (FD_ISSET(p
->sock
, &rfds
))
308 if ((error
= isakmp_handler(p
->sock
)) == -2)
316 if (FD_ISSET(lcconf
->sock_pfkey
, &rfds
))
319 if (lcconf
->rtsock
>= 0 && FD_ISSET(lcconf
->rtsock
, &rfds
)) {
320 if (update_myaddrs() && lcconf
->autograbaddr
)
321 if (check_rtsock_sched
== NULL
) /* only schedule if not already done */
322 check_rtsock_sched
= sched_new(5, check_rtsock
, NULL
);
323 // initfds(); //%%% BUG FIX - not needed here
333 /* clear all status and exit program. */
343 plog(LLV_INFO
, LOCATION
, NULL
, "racoon shutdown\n");
352 check_rtsock_sched
= NULL
;
354 isakmp_close_unused();
356 autoconf_myaddrsport();
359 /* initialize socket list again */
373 #ifdef ENABLE_ADMINPORT
374 if (lcconf
->sock_admin
!= -1) {
375 if (lcconf
->sock_admin
>= FD_SETSIZE
) {
376 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - admin socket\n");
379 FD_SET(lcconf
->sock_admin
, &mask0
);
380 /* XXX should we listen on admin socket when dying ?
383 FD_SET(lcconf
->sock_admin
, &maskdying
);
385 nfds
= (nfds
> lcconf
->sock_admin
? nfds
: lcconf
->sock_admin
);
388 #ifdef ENABLE_VPNCONTROL_PORT
390 struct vpnctl_socket_elem
*elem
;
392 if (lcconf
->sock_vpncontrol
!= -1) {
393 if (lcconf
->sock_vpncontrol
>= FD_SETSIZE
) {
394 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - vpncontrol socket\n");
397 FD_SET(lcconf
->sock_vpncontrol
, &mask0
);
398 nfds
= (nfds
> lcconf
->sock_vpncontrol
? nfds
: lcconf
->sock_vpncontrol
);
401 LIST_FOREACH(elem
, &lcconf
->vpnctl_comm_socks
, chain
) {
402 if (elem
->sock
!= -1) {
403 if (elem
->sock
>= FD_SETSIZE
) {
404 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun vpnctl_comm socket\n");
407 FD_SET(elem
->sock
, &mask0
);
408 nfds
= (nfds
> elem
->sock
? nfds
: elem
->sock
);
414 if (lcconf
->sock_pfkey
>= FD_SETSIZE
) {
415 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - pfkey socket\n");
418 FD_SET(lcconf
->sock_pfkey
, &mask0
);
419 FD_SET(lcconf
->sock_pfkey
, &maskdying
);
420 nfds
= (nfds
> lcconf
->sock_pfkey
? nfds
: lcconf
->sock_pfkey
);
421 if (lcconf
->rtsock
>= 0) {
422 if (lcconf
->rtsock
>= FD_SETSIZE
) {
423 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - rt socket\n");
426 FD_SET(lcconf
->rtsock
, &mask0
);
427 nfds
= (nfds
> lcconf
->rtsock
? nfds
: lcconf
->rtsock
);
430 for (p
= lcconf
->myaddrs
; p
; p
= p
->next
) {
435 if (p
->sock
>= FD_SETSIZE
) {
436 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - isakmp socket\n");
439 FD_SET(p
->sock
, &mask0
);
440 nfds
= (nfds
> p
->sock
? nfds
: p
->sock
);
446 static int signals
[] = {
458 * asynchronous requests will actually dispatched in the
459 * main loop in session().
465 /* Do not just set it to 1, because we may miss some signals by just setting
469 if ( sig
== SIGTERM
){
480 * XXX We are not able to tell if we got
481 * several time the same signal. This is
482 * not a problem for the current code,
483 * but we shall remember this limitation.
485 for (sig
= 0; sig
<= NSIG
; sig
++) {
486 if (sigreq
[sig
] == 0)
494 /* Catch up childs, mainly scripts.
505 #ifdef DEBUG_RECORD_MALLOCATION
507 * XXX This operation is signal handler unsafe and may lead to
508 * crashes and security breaches: See Henning Brauer talk at
509 * EuroBSDCon 2005. Do not run in production with this option
520 if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM
)) != 0) {
521 plog(LLV_ERROR
, LOCATION
, NULL
,
522 "ISAKMP mode config structure reset failed, "
530 /* Save old configuration, load new one... */
532 close(lcconf
->rtsock
);
533 if (cfreparse(sig
)) {
534 plog(LLV_ERROR2
, LOCATION
, NULL
,
535 "configuration read failed\n");
538 if (lcconf
->logfile_param
== NULL
)
539 plogreset(lcconf
->pathinfo
[LC_PATHTYPE_LOGFILE
]);
547 #endif /* __APPLE__ */
549 #if TARGET_OS_EMBEDDED
550 if (no_remote_configs(TRUE
)) {
551 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
552 pfkey_send_flush(lcconf
->sock_pfkey
, SADB_SATYPE_UNSPEC
);
553 #ifdef ENABLE_FASTQUIT
556 sched_new(1, check_flushsa_stub
, NULL
);
565 plog(LLV_INFO
, LOCATION
, NULL
,
566 "caught signal %d\n", sig
);
567 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
568 pfkey_send_flush(lcconf
->sock_pfkey
,
570 if ( sig
== SIGTERM
){
571 terminated
= 1; /* in case if it hasn't been set yet */
575 sched_new(1, check_flushsa_stub
, NULL
);
581 plog(LLV_INFO
, LOCATION
, NULL
,
582 "caught signal %d\n", sig
);
589 * waiting the termination of processing until sending DELETE message
590 * for all inbound SA will complete.
593 check_flushsa_stub(p
)
604 struct sadb_msg
*msg
, *end
, *next
;
606 caddr_t mhp
[SADB_EXT_MAX
+ 1];
609 buf
= pfkey_dump_sadb(SADB_SATYPE_UNSPEC
);
611 plog(LLV_DEBUG
, LOCATION
, NULL
,
612 "pfkey_dump_sadb: returned nothing.\n");
616 msg
= (struct sadb_msg
*)buf
->v
;
617 end
= (struct sadb_msg
*)(buf
->v
+ buf
->l
);
619 /* counting SA except of dead one. */
622 if (PFKEY_UNUNIT64(msg
->sadb_msg_len
) < sizeof(*msg
))
624 next
= (struct sadb_msg
*)((caddr_t
)msg
+ PFKEY_UNUNIT64(msg
->sadb_msg_len
));
625 if (msg
->sadb_msg_type
!= SADB_DUMP
) {
630 if (pfkey_align(msg
, mhp
) || pfkey_check(mhp
)) {
631 plog(LLV_ERROR
, LOCATION
, NULL
,
632 "pfkey_check (%s)\n", ipsec_strerror());
637 sa
= (struct sadb_sa
*)(mhp
[SADB_EXT_SA
]);
643 if (sa
->sadb_sa_state
!= SADB_SASTATE_DEAD
) {
656 sched_new(1, check_flushsa_stub
, NULL
);
660 #if !TARGET_OS_EMBEDDED
661 // abort exit if policies/config/control state is still there
662 if (vpn_control_connected() ||
663 policies_installed() ||
664 !no_remote_configs(FALSE
)) {
670 #if !TARGET_OS_EMBEDDED
672 vproc_transaction_end(NULL
, lcconf
->vt
);
677 auto_exit_do(void *p
)
679 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
680 plog(LLV_DEBUG
, LOCATION
, NULL
,
681 "performing auto exit\n");
682 pfkey_send_flush(lcconf
->sock_pfkey
, SADB_SATYPE_UNSPEC
);
683 sched_new(1, check_flushsa_stub
, NULL
);
688 check_auto_exit(void)
690 if (lcconf
->auto_exit_sched
!= NULL
) { /* exit scheduled? */
691 if (lcconf
->auto_exit_state
!= LC_AUTOEXITSTATE_ENABLED
692 || vpn_control_connected() /* vpn control connected */
693 || policies_installed() /* policies installed in kernel */
694 || !no_remote_configs(FALSE
)) /* remote or anonymous configs */
695 SCHED_KILL(lcconf
->auto_exit_sched
);
696 } else { /* exit not scheduled */
697 if (lcconf
->auto_exit_state
== LC_AUTOEXITSTATE_ENABLED
698 && !vpn_control_connected()
699 && !policies_installed()
700 && no_remote_configs(FALSE
))
701 if (lcconf
->auto_exit_delay
== 0)
702 auto_exit_do(NULL
); /* immediate exit */
704 lcconf
->auto_exit_sched
= sched_new(lcconf
->auto_exit_delay
, auto_exit_do
, NULL
);
714 for (i
= 0; signals
[i
] != 0; i
++)
715 if (set_signal(signals
[i
], signal_handler
) < 0) {
716 plog(LLV_ERROR2
, LOCATION
, NULL
,
717 "failed to set_signal (%s)\n",
724 set_signal(sig
, func
)
726 RETSIGTYPE (*func
) __P((int));
730 memset((caddr_t
)&sa
, 0, sizeof(sa
));
731 sa
.sa_handler
= func
;
732 sa
.sa_flags
= SA_RESTART
;
734 if (sigemptyset(&sa
.sa_mask
) < 0)
737 if (sigaction(sig
, &sa
, (struct sigaction
*)0) < 0)
747 pfkey_close(lcconf
->sock_pfkey
);
748 #ifdef ENABLE_ADMINPORT
751 #ifdef ENABLE_VPNCONTROL_PORT