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>
74 #include <vproc_priv.h>
87 #include "grabmyaddr.h"
89 #include "cfparse_proto.h"
90 #include "isakmp_var.h"
91 #include "isakmp_xauth.h"
92 #include "isakmp_cfg.h"
93 #include "admin_var.h"
99 #include "localconf.h"
100 #include "remoteconf.h"
101 #include "backupsa.h"
103 #include "nattraversal.h"
105 #include "vpn_control_var.h"
107 #include "algorithm.h" /* XXX ??? */
113 extern pid_t racoon_pid
;
114 extern int launchedbylaunchd(void);
115 static void close_session
__P((void));
116 static void check_rtsock
__P((void *));
117 static void initfds
__P((void));
118 static void init_signal
__P((void));
119 static int set_signal
__P((int sig
, RETSIGTYPE (*func
) __P((int))));
120 static void check_sigreq
__P((void));
121 static void check_flushsa_stub
__P((void *));
122 static void check_flushsa
__P((void));
123 static void auto_exit_do
__P((void *));
124 static int close_sockets
__P((void));
127 static fd_set maskdying
;
129 static volatile sig_atomic_t sigreq
[NSIG
+ 1];
130 static int dying
= 0;
131 static struct sched
*check_rtsock_sched
= NULL
;
138 close(lcconf
->rtsock
);
140 if (isakmp_open() < 0) {
141 plog(LLV_ERROR2
, LOCATION
, NULL
,
142 "failed to reopen isakmp sockets\n");
148 static int64_t racoon_keepalive
= -1;
151 * This is used to (manually) update racoon's launchd keepalive, which is needed because racoon is (mostly)
152 * launched on demand and for <rdar://problem/8773022> requires a keepalive on dirty/failure exits.
153 * The launchd plist can't be used for this because RunOnLoad is required to have keepalive on a failure exit.
156 launchd_update_racoon_keepalive (Boolean enabled
)
158 if (launchedbylaunchd()) {
159 vproc_t vp
= vprocmgr_lookup_vproc("com.apple.racoon");
161 int64_t val
= (__typeof__(val
))enabled
;
162 if (vproc_swap_integer(vp
,
163 VPROC_GSK_BASIC_KEEPALIVE
,
165 &racoon_keepalive
)) {
166 plog(LLV_ERROR2
, LOCATION
, NULL
,
167 "failed to swap launchd keepalive integer %d\n", enabled
);
172 return racoon_keepalive
;
180 struct timeval
*timeout
;
183 char pid_file
[MAXPATHLEN
];
187 /* initialize schedular */
193 if (isakmp_init() < 0) {
195 if (isakmp_init(false) < 0) {
196 #endif /* __APPLE__ */
197 plog(LLV_ERROR2
, LOCATION
, NULL
,
198 "failed to initialize isakmp");
202 #ifdef ENABLE_ADMINPORT
203 if (admin_init() < 0) {
204 plog(LLV_ERROR2
, LOCATION
, NULL
,
205 "failed to initialize admin port");
209 #ifdef ENABLE_VPNCONTROL_PORT
210 if (vpncontrol_init() < 0) {
211 plog(LLV_ERROR2
, LOCATION
, NULL
,
212 "failed to initialize vpn control port");
223 natt_keepalive_init ();
227 if (privsep_init() != 0) {
228 plog(LLV_ERROR2
, LOCATION
, NULL
,
229 "failed to initialize privsep");
233 for (i
= 0; i
<= NSIG
; i
++)
236 /* write .pid file */
238 racoon_pid
= getpid();
239 if (lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
] == NULL
)
240 strlcpy(pid_file
, _PATH_VARRUN
"racoon.pid", sizeof(pid_file
));
241 else if (lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
][0] == '/')
242 strlcpy(pid_file
, lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
], sizeof(pid_file
));
244 strlcat(pid_file
, _PATH_VARRUN
, sizeof(pid_file
));
245 strlcat(pid_file
, lcconf
->pathinfo
[LC_PATHTYPE_PIDFILE
], sizeof(pid_file
));
247 fp
= fopen(pid_file
, "w");
249 if (fchmod(fileno(fp
),
250 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
) == -1) {
251 syslog(LOG_ERR
, "%s", strerror(errno
));
255 fprintf(fp
, "%ld\n", (long)racoon_pid
);
258 plog(LLV_ERROR
, LOCATION
, NULL
,
259 "cannot open %s", pid_file
);
264 #if !TARGET_OS_EMBEDDED
265 // enable keepalive for recovery (from crashes and bad exits... after init)
266 (void)launchd_update_racoon_keepalive(true);
267 #endif // !TARGET_OS_EMBEDDED
271 if (!TAILQ_EMPTY(&lcconf
->saved_msg_queue
))
272 pfkey_post_handler();
275 * asynchronous requests via signal.
276 * make sure to reset sigreq to 0.
281 timeout
= schedular();
282 // <rdar://problem/7650111> Workaround: make sure timeout is playing nice
284 if (timeout
->tv_usec
< 0 || timeout
->tv_usec
> SELECT_USEC_MAX
) {
285 timeout
->tv_sec
+= ((__typeof__(timeout
->tv_sec
))timeout
->tv_usec
)/SELECT_USEC_MAX
;
286 timeout
->tv_usec
%= SELECT_USEC_MAX
;
288 if (timeout
->tv_sec
> SELECT_SEC_MAX
/* tv_sec is unsigned */) {
289 timeout
->tv_sec
= SELECT_SEC_MAX
;
291 if (!timeout
->tv_sec
&& !timeout
->tv_usec
) {
300 error
= select(nfds
, &rfds
, (fd_set
*)0, (fd_set
*)0, timeout
);
306 plog(LLV_ERROR2
, LOCATION
, NULL
,
307 "failed select (%s) nfds %d\n",
308 strerror(errno
), nfds
);
316 #ifdef ENABLE_ADMINPORT
317 if ((lcconf
->sock_admin
!= -1) &&
318 (FD_ISSET(lcconf
->sock_admin
, &rfds
)))
321 #ifdef ENABLE_VPNCONTROL_PORT
323 struct vpnctl_socket_elem
*elem
;
324 struct vpnctl_socket_elem
*t_elem
;
326 if ((lcconf
->sock_vpncontrol
!= -1) &&
327 (FD_ISSET(lcconf
->sock_vpncontrol
, &rfds
))) {
328 vpncontrol_handler();
329 update_fds
= 1; // in case new socket created - update mask
331 /* The handler may close and remove the list element
332 * so we can't rely on it being valid after calling
335 LIST_FOREACH_SAFE(elem
, &lcconf
->vpnctl_comm_socks
, chain
, t_elem
) {
336 if ((elem
->sock
!= -1) &&
337 (FD_ISSET(elem
->sock
, &rfds
)))
338 if (vpncontrol_comm_handler(elem
))
339 update_fds
= 1; // socket closed by peer - update mask
344 for (p
= lcconf
->myaddrs
; p
; p
= p
->next
) {
347 if (FD_ISSET(p
->sock
, &rfds
))
348 if ((error
= isakmp_handler(p
->sock
)) == -2)
356 if (FD_ISSET(lcconf
->sock_pfkey
, &rfds
))
359 if (lcconf
->rtsock
>= 0 && FD_ISSET(lcconf
->rtsock
, &rfds
)) {
360 if (update_myaddrs() && lcconf
->autograbaddr
)
361 if (check_rtsock_sched
== NULL
) /* only schedule if not already done */
362 check_rtsock_sched
= sched_new(5, check_rtsock
, NULL
);
363 // initfds(); //%%% BUG FIX - not needed here
373 /* clear all status and exit program. */
384 #if !TARGET_OS_EMBEDDED
385 // a clean exit, so disable launchd keepalive
386 (void)launchd_update_racoon_keepalive(false);
387 #endif // !TARGET_OS_EMBEDDED
390 plog(LLV_INFO
, LOCATION
, NULL
, "racoon shutdown\n");
399 check_rtsock_sched
= NULL
;
401 isakmp_close_unused();
403 autoconf_myaddrsport();
406 /* initialize socket list again */
420 #ifdef ENABLE_ADMINPORT
421 if (lcconf
->sock_admin
!= -1) {
422 if (lcconf
->sock_admin
>= FD_SETSIZE
) {
423 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - admin socket\n");
426 FD_SET(lcconf
->sock_admin
, &mask0
);
427 /* XXX should we listen on admin socket when dying ?
430 FD_SET(lcconf
->sock_admin
, &maskdying
);
432 nfds
= (nfds
> lcconf
->sock_admin
? nfds
: lcconf
->sock_admin
);
435 #ifdef ENABLE_VPNCONTROL_PORT
437 struct vpnctl_socket_elem
*elem
;
439 if (lcconf
->sock_vpncontrol
!= -1) {
440 if (lcconf
->sock_vpncontrol
>= FD_SETSIZE
) {
441 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - vpncontrol socket\n");
444 FD_SET(lcconf
->sock_vpncontrol
, &mask0
);
445 nfds
= (nfds
> lcconf
->sock_vpncontrol
? nfds
: lcconf
->sock_vpncontrol
);
448 LIST_FOREACH(elem
, &lcconf
->vpnctl_comm_socks
, chain
) {
449 if (elem
->sock
!= -1) {
450 if (elem
->sock
>= FD_SETSIZE
) {
451 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun vpnctl_comm socket\n");
454 FD_SET(elem
->sock
, &mask0
);
455 nfds
= (nfds
> elem
->sock
? nfds
: elem
->sock
);
461 if (lcconf
->sock_pfkey
>= FD_SETSIZE
) {
462 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - pfkey socket\n");
465 FD_SET(lcconf
->sock_pfkey
, &mask0
);
466 FD_SET(lcconf
->sock_pfkey
, &maskdying
);
467 nfds
= (nfds
> lcconf
->sock_pfkey
? nfds
: lcconf
->sock_pfkey
);
468 if (lcconf
->rtsock
>= 0) {
469 if (lcconf
->rtsock
>= FD_SETSIZE
) {
470 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - rt socket\n");
473 FD_SET(lcconf
->rtsock
, &mask0
);
474 nfds
= (nfds
> lcconf
->rtsock
? nfds
: lcconf
->rtsock
);
477 for (p
= lcconf
->myaddrs
; p
; p
= p
->next
) {
482 if (p
->sock
>= FD_SETSIZE
) {
483 plog(LLV_ERROR2
, LOCATION
, NULL
, "fd_set overrun - isakmp socket\n");
486 FD_SET(p
->sock
, &mask0
);
487 nfds
= (nfds
> p
->sock
? nfds
: p
->sock
);
493 static int signals
[] = {
505 * asynchronous requests will actually dispatched in the
506 * main loop in session().
512 /* Do not just set it to 1, because we may miss some signals by just setting
516 if ( sig
== SIGTERM
){
527 * XXX We are not able to tell if we got
528 * several time the same signal. This is
529 * not a problem for the current code,
530 * but we shall remember this limitation.
532 for (sig
= 0; sig
<= NSIG
; sig
++) {
533 if (sigreq
[sig
] == 0)
541 /* Catch up childs, mainly scripts.
552 #ifdef DEBUG_RECORD_MALLOCATION
554 * XXX This operation is signal handler unsafe and may lead to
555 * crashes and security breaches: See Henning Brauer talk at
556 * EuroBSDCon 2005. Do not run in production with this option
567 if ((isakmp_cfg_init(ISAKMP_CFG_INIT_WARM
)) != 0) {
568 plog(LLV_ERROR
, LOCATION
, NULL
,
569 "ISAKMP mode config structure reset failed, "
577 /* Save old configuration, load new one... */
579 close(lcconf
->rtsock
);
580 if (cfreparse(sig
)) {
581 plog(LLV_ERROR2
, LOCATION
, NULL
,
582 "configuration read failed\n");
585 if (lcconf
->logfile_param
== NULL
)
586 plogreset(lcconf
->pathinfo
[LC_PATHTYPE_LOGFILE
]);
594 #endif /* __APPLE__ */
596 #if TARGET_OS_EMBEDDED
597 if (no_remote_configs(TRUE
)) {
598 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
599 pfkey_send_flush(lcconf
->sock_pfkey
, SADB_SATYPE_UNSPEC
);
600 #ifdef ENABLE_FASTQUIT
603 sched_new(1, check_flushsa_stub
, NULL
);
612 plog(LLV_INFO
, LOCATION
, NULL
,
613 "caught signal %d\n", sig
);
614 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
615 pfkey_send_flush(lcconf
->sock_pfkey
,
617 if ( sig
== SIGTERM
){
618 terminated
= 1; /* in case if it hasn't been set yet */
622 sched_new(1, check_flushsa_stub
, NULL
);
628 plog(LLV_INFO
, LOCATION
, NULL
,
629 "caught signal %d\n", sig
);
636 * waiting the termination of processing until sending DELETE message
637 * for all inbound SA will complete.
640 check_flushsa_stub(p
)
651 struct sadb_msg
*msg
, *end
, *next
;
653 caddr_t mhp
[SADB_EXT_MAX
+ 1];
656 buf
= pfkey_dump_sadb(SADB_SATYPE_UNSPEC
);
658 plog(LLV_DEBUG
, LOCATION
, NULL
,
659 "pfkey_dump_sadb: returned nothing.\n");
663 msg
= (struct sadb_msg
*)buf
->v
;
664 end
= (struct sadb_msg
*)(buf
->v
+ buf
->l
);
666 /* counting SA except of dead one. */
669 if (PFKEY_UNUNIT64(msg
->sadb_msg_len
) < sizeof(*msg
))
671 next
= (struct sadb_msg
*)((caddr_t
)msg
+ PFKEY_UNUNIT64(msg
->sadb_msg_len
));
672 if (msg
->sadb_msg_type
!= SADB_DUMP
) {
677 if (pfkey_align(msg
, mhp
) || pfkey_check(mhp
)) {
678 plog(LLV_ERROR
, LOCATION
, NULL
,
679 "pfkey_check (%s)\n", ipsec_strerror());
684 sa
= (struct sadb_sa
*)(mhp
[SADB_EXT_SA
]);
690 if (sa
->sadb_sa_state
!= SADB_SASTATE_DEAD
) {
703 sched_new(1, check_flushsa_stub
, NULL
);
707 #if !TARGET_OS_EMBEDDED
708 // abort exit if policies/config/control state is still there
709 if (vpn_control_connected() ||
710 policies_installed() ||
711 !no_remote_configs(FALSE
)) {
717 #if !TARGET_OS_EMBEDDED
719 vproc_transaction_end(NULL
, lcconf
->vt
);
724 auto_exit_do(void *p
)
726 EVT_PUSH(NULL
, NULL
, EVTT_RACOON_QUIT
, NULL
);
727 plog(LLV_DEBUG
, LOCATION
, NULL
,
728 "performing auto exit\n");
729 pfkey_send_flush(lcconf
->sock_pfkey
, SADB_SATYPE_UNSPEC
);
730 sched_new(1, check_flushsa_stub
, NULL
);
735 check_auto_exit(void)
737 if (lcconf
->auto_exit_sched
!= NULL
) { /* exit scheduled? */
738 if (lcconf
->auto_exit_state
!= LC_AUTOEXITSTATE_ENABLED
739 || vpn_control_connected() /* vpn control connected */
740 || policies_installed() /* policies installed in kernel */
741 || !no_remote_configs(FALSE
)) /* remote or anonymous configs */
742 SCHED_KILL(lcconf
->auto_exit_sched
);
743 } else { /* exit not scheduled */
744 if (lcconf
->auto_exit_state
== LC_AUTOEXITSTATE_ENABLED
745 && !vpn_control_connected()
746 && !policies_installed()
747 && no_remote_configs(FALSE
))
748 if (lcconf
->auto_exit_delay
== 0)
749 auto_exit_do(NULL
); /* immediate exit */
751 lcconf
->auto_exit_sched
= sched_new(lcconf
->auto_exit_delay
, auto_exit_do
, NULL
);
761 for (i
= 0; signals
[i
] != 0; i
++)
762 if (set_signal(signals
[i
], signal_handler
) < 0) {
763 plog(LLV_ERROR2
, LOCATION
, NULL
,
764 "failed to set_signal (%s)\n",
771 set_signal(sig
, func
)
773 RETSIGTYPE (*func
) __P((int));
777 memset((caddr_t
)&sa
, 0, sizeof(sa
));
778 sa
.sa_handler
= func
;
779 sa
.sa_flags
= SA_RESTART
;
781 if (sigemptyset(&sa
.sa_mask
) < 0)
784 if (sigaction(sig
, &sa
, (struct sigaction
*)0) < 0)
794 pfkey_close(lcconf
->sock_pfkey
);
795 #ifdef ENABLE_ADMINPORT
798 #ifdef ENABLE_VPNCONTROL_PORT