1 /* strongSwan IPsec starter
2 * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * RCSID $Id: starter.c,v 1.23 2006/02/15 18:37:46 as Exp $
17 #include <sys/types.h>
32 #include "../pluto/constants.h"
33 #include "../pluto/defs.h"
34 #include "../pluto/log.h"
38 #include "starterwhack.h"
39 #include "starterstroke.h"
40 #include "invokepluto.h"
41 #include "invokecharon.h"
44 #include "interfaces.h"
46 #define FLAG_ACTION_START_PLUTO 0x01
47 #define FLAG_ACTION_UPDATE 0x02
48 #define FLAG_ACTION_RELOAD 0x04
49 #define FLAG_ACTION_QUIT 0x08
50 #define FLAG_ACTION_LISTEN 0x10
51 #define FLAG_ACTION_START_CHARON 0x20
53 static unsigned int _action_
= 0;
66 while ((pid
= waitpid(-1, &status
, WNOHANG
)) > 0)
68 if (pid
== starter_pluto_pid())
70 if (pid
== starter_charon_pid())
72 if (WIFSIGNALED(status
))
74 DBG_log("child %d%s has been killed by sig %d\n",
75 pid
, name?name
:"", WTERMSIG(status
))
77 else if (WIFSTOPPED(status
))
79 DBG_log("child %d%s has been stopped by sig %d\n",
80 pid
, name?name
:"", WSTOPSIG(status
))
82 else if (WIFEXITED(status
))
84 DBG_log("child %d%s has quit (exit code %d)\n",
85 pid
, name?name
:"", WEXITSTATUS(status
))
89 DBG_log("child %d%s has quit", pid
, name?name
:"")
91 if (pid
== starter_pluto_pid())
92 starter_pluto_sigchild(pid
);
93 if (pid
== starter_charon_pid())
94 starter_charon_sigchild(pid
);
104 _action_
|= FLAG_ACTION_START_PLUTO
;
105 _action_
|= FLAG_ACTION_START_CHARON
;
109 _action_
|= FLAG_ACTION_UPDATE
;
115 _action_
|= FLAG_ACTION_QUIT
;
119 _action_
|= FLAG_ACTION_RELOAD
;
120 _action_
|= FLAG_ACTION_UPDATE
;
124 plog("fsig(): unknown signal %d -- investigate", signal
);
132 fprintf(stderr
, "Usage: starter [--nofork] [--auto-update <sec>] "
133 "[--debug|--debug-more|--debug-all]\n");
137 int main (int argc
, char **argv
)
139 starter_config_t
*cfg
= NULL
;
140 starter_config_t
*new_cfg
;
141 starter_conn_t
*conn
, *conn2
;
142 starter_ca_t
*ca
, *ca2
;
150 unsigned long auto_update
= 0;
152 bool no_fork
= FALSE
;
154 /* global variables defined in log.h */
155 log_to_stderr
= TRUE
;
156 base_debugging
= DBG_NONE
;
158 /* parse command line */
159 for (i
= 1; i
< argc
; i
++)
161 if (streq(argv
[i
], "--debug"))
163 base_debugging
|= DBG_CONTROL
;
165 else if (streq(argv
[i
], "--debug-more"))
167 base_debugging
|= DBG_CONTROLMORE
;
169 else if (streq(argv
[i
], "--debug-all"))
171 base_debugging
|= DBG_ALL
;
173 else if (streq(argv
[i
], "--nofork"))
177 else if (streq(argv
[i
], "--auto-update") && i
+1 < argc
)
179 auto_update
= atoi(argv
[++i
]);
190 init_log("ipsec_starter");
191 cur_debugging
= base_debugging
;
193 signal(SIGHUP
, fsig
);
194 signal(SIGCHLD
, fsig
);
195 signal(SIGPIPE
, fsig
);
196 signal(SIGINT
, fsig
);
197 signal(SIGTERM
, fsig
);
198 signal(SIGQUIT
, fsig
);
199 signal(SIGALRM
, fsig
);
200 signal(SIGUSR1
, fsig
);
202 plog("Starting strongSwan %s IPsec [starter]...", ipsec_version_code());
204 /* verify that we can start */
207 plog("permission denied (must be superuser)");
211 if (stat(PLUTO_PID_FILE
, &stb
) == 0)
213 plog("pluto is already running (%s exists) -- skipping pluto start", PLUTO_PID_FILE
);
217 _action_
|= FLAG_ACTION_START_PLUTO
;
219 if (stat(CHARON_PID_FILE
, &stb
) == 0)
221 plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE
);
225 _action_
|= FLAG_ACTION_START_CHARON
;
227 if (stat(DEV_RANDOM
, &stb
) != 0)
229 plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM
);
233 if (stat(DEV_URANDOM
, &stb
)!= 0)
235 plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM
);
239 cfg
= confread_load(CONFIG_FILE
);
240 if (cfg
== NULL
|| cfg
->err
> 0)
242 plog("unable to start strongSwan -- fatal errors in config");
250 /* determine if we have a native netkey IPsec stack */
251 if (!starter_netkey_init())
253 plog("no netkey IPSec stack detected");
257 last_reload
= time(NULL
);
259 if (stat(STARTER_PID_FILE
, &stb
) == 0)
261 plog("starter is already running (%s exists) -- no fork done", STARTER_PID_FILE
);
265 /* fork if we're not debugging stuff */
268 log_to_stderr
= FALSE
;
274 int fnull
= open("/dev/null", O_RDWR
);
278 dup2(fnull
, STDIN_FILENO
);
279 dup2(fnull
, STDOUT_FILENO
);
280 dup2(fnull
, STDERR_FILENO
);
287 plog("can't fork: %s", strerror(errno
));
294 /* save pid file in /var/run/starter.pid */
296 FILE *fd
= fopen(STARTER_PID_FILE
, "w");
300 fprintf(fd
, "%u\n", getpid());
308 * Stop pluto/charon (if started) and exit
310 if (_action_
& FLAG_ACTION_QUIT
)
312 if (starter_pluto_pid())
313 starter_stop_pluto();
314 if (starter_charon_pid())
315 starter_stop_charon();
316 starter_netkey_cleanup();
318 unlink(STARTER_PID_FILE
);
320 #ifdef LEAK_DETECTIVE
322 #endif /* LEAK_DETECTIVE */
324 plog("ipsec starter stopped");
329 * Delete all connections. Will be added below
331 if (_action_
& FLAG_ACTION_RELOAD
)
333 if (starter_pluto_pid() || starter_charon_pid())
335 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
337 if (conn
->state
== STATE_ADDED
)
339 if (starter_charon_pid())
341 starter_stroke_del_conn(conn
);
343 if (starter_pluto_pid())
345 starter_whack_del_conn(conn
);
347 conn
->state
= STATE_TO_ADD
;
350 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
352 if (ca
->state
== STATE_ADDED
)
354 if (starter_charon_pid())
356 starter_stroke_del_ca(ca
);
358 if (starter_pluto_pid())
360 starter_whack_del_ca(ca
);
362 ca
->state
= STATE_TO_ADD
;
366 _action_
&= ~FLAG_ACTION_RELOAD
;
370 * Update configuration
372 if (_action_
& FLAG_ACTION_UPDATE
)
376 DBG_log("Reloading config...")
378 new_cfg
= confread_load(CONFIG_FILE
);
380 if (new_cfg
->err
+ new_cfg
->non_fatal_err
== 0)
382 /* Switch to new config. New conn will be loaded below */
383 if (!starter_cmp_defaultroute(&new_cfg
->defaultroute
384 , &cfg
->defaultroute
))
386 _action_
|= FLAG_ACTION_LISTEN
;
389 if (!starter_cmp_pluto(cfg
, new_cfg
))
391 plog("Pluto has changed");
392 if (starter_pluto_pid())
393 starter_stop_pluto();
394 _action_
&= ~FLAG_ACTION_LISTEN
;
395 _action_
|= FLAG_ACTION_START_PLUTO
;
399 /* Only reload conn and ca sections if pluto is not killed */
401 /* Look for new connections that are already loaded */
402 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
404 if (conn
->state
== STATE_ADDED
)
406 for (conn2
= new_cfg
->conn_first
; conn2
; conn2
= conn2
->next
)
408 if (conn2
->state
== STATE_TO_ADD
&& starter_cmp_conn(conn
, conn2
))
410 conn
->state
= STATE_REPLACED
;
411 conn2
->state
= STATE_ADDED
;
412 conn2
->id
= conn
->id
;
419 /* Remove conn sections that have become unused */
420 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
422 if (conn
->state
== STATE_ADDED
)
424 if (starter_charon_pid())
426 starter_stroke_del_conn(conn
);
428 if (starter_pluto_pid())
430 starter_whack_del_conn(conn
);
435 /* Look for new ca sections that are already loaded */
436 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
438 if (ca
->state
== STATE_ADDED
)
440 for (ca2
= new_cfg
->ca_first
; ca2
; ca2
= ca2
->next
)
442 if (ca2
->state
== STATE_TO_ADD
&& starter_cmp_ca(ca
, ca2
))
444 ca
->state
= STATE_REPLACED
;
445 ca2
->state
= STATE_ADDED
;
452 /* Remove ca sections that have become unused */
453 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
455 if (ca
->state
== STATE_ADDED
)
457 if (starter_charon_pid())
459 starter_stroke_del_ca(ca
);
461 if (starter_pluto_pid())
463 starter_whack_del_ca(ca
);
473 plog("can't reload config file due to errors -- keeping old one");
474 confread_free(new_cfg
);
476 _action_
&= ~FLAG_ACTION_UPDATE
;
477 last_reload
= time(NULL
);
483 if (_action_
& FLAG_ACTION_START_PLUTO
)
485 if (cfg
->setup
.plutostart
&& !starter_pluto_pid())
488 DBG_log("Attempting to start pluto...")
491 if (starter_start_pluto(cfg
, no_fork
) == 0)
493 starter_whack_listen();
497 /* schedule next try */
498 alarm(PLUTO_RESTART_DELAY
);
501 _action_
&= ~FLAG_ACTION_START_PLUTO
;
503 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
505 if (ca
->state
== STATE_ADDED
)
506 ca
->state
= STATE_TO_ADD
;
509 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
511 if (conn
->state
== STATE_ADDED
)
512 conn
->state
= STATE_TO_ADD
;
519 if (_action_
& FLAG_ACTION_START_CHARON
)
521 if (cfg
->setup
.charonstart
&& !starter_charon_pid())
524 DBG_log("Attempting to start charon...")
526 if (starter_start_charon(cfg
, no_fork
))
528 /* schedule next try */
529 alarm(PLUTO_RESTART_DELAY
);
532 _action_
&= ~FLAG_ACTION_START_CHARON
;
536 * Tell pluto to reread its interfaces
538 if (_action_
& FLAG_ACTION_LISTEN
)
540 if (starter_pluto_pid())
542 starter_whack_listen();
543 _action_
&= ~FLAG_ACTION_LISTEN
;
548 * Add stale conn and ca sections
550 if (starter_pluto_pid() || starter_charon_pid())
552 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
554 if (ca
->state
== STATE_TO_ADD
)
556 if (starter_charon_pid())
558 starter_stroke_add_ca(ca
);
560 if (starter_pluto_pid())
562 starter_whack_add_ca(ca
);
564 ca
->state
= STATE_ADDED
;
568 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
570 if (conn
->state
== STATE_TO_ADD
)
574 /* affect new unique id */
577 if (starter_charon_pid())
579 starter_stroke_add_conn(conn
);
581 if (starter_pluto_pid())
583 starter_whack_add_conn(conn
);
585 conn
->state
= STATE_ADDED
;
587 if (conn
->startup
== STARTUP_START
)
589 if (conn
->keyexchange
== KEY_EXCHANGE_IKEV2
)
591 if (starter_charon_pid())
593 starter_stroke_initiate_conn(conn
);
598 if (starter_pluto_pid())
600 starter_whack_initiate_conn(conn
);
604 else if (conn
->startup
== STARTUP_ROUTE
)
606 if (conn
->keyexchange
== KEY_EXCHANGE_IKEV2
)
608 if (starter_charon_pid())
610 starter_stroke_route_conn(conn
);
615 if (starter_pluto_pid())
617 starter_whack_route_conn(conn
);
626 * If auto_update activated, when to stop select
630 time_t now
= time(NULL
);
632 tv
.tv_sec
= (now
< last_reload
+ auto_update
)
633 ?
(last_reload
+ auto_update
-now
) : 0;
638 * Wait for something to happen
640 if (select(0, NULL
, NULL
, NULL
, auto_update ?
&tv
: NULL
) == 0)
642 /* timeout -> auto_update */
643 _action_
|= FLAG_ACTION_UPDATE
;