c92b2bc5901f93aefc89b7ebb49e77a28d1bce72
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
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"
47 * Return codes defined by Linux Standard Base Core Specification 3.1
48 * in section 20.2. Init Script Actions
50 #define LSB_RC_SUCCESS 0 /* success */
51 #define LSB_RC_FAILURE 1 /* generic or unspecified error */
52 #define LSB_RC_INVALID_ARGUMENT 2 /* invalid or excess argument(s) */
53 #define LSB_RC_NOT_IMPLEMENTED 3 /* unimplemented feature (reload) */
54 #define LSB_RC_NOT_ALLOWED 4 /* user had insufficient privilege */
55 #define LSB_RC_NOT_INSTALLED 5 /* program is not installed */
56 #define LSB_RC_NOT_CONFIGURED 6 /* program is not configured */
57 #define LSB_RC_NOT_RUNNING 7 /* program is not running */
59 #define FLAG_ACTION_START_PLUTO 0x01
60 #define FLAG_ACTION_UPDATE 0x02
61 #define FLAG_ACTION_RELOAD 0x04
62 #define FLAG_ACTION_QUIT 0x08
63 #define FLAG_ACTION_LISTEN 0x10
64 #define FLAG_ACTION_START_CHARON 0x20
66 static unsigned int _action_
= 0;
79 while ((pid
= waitpid(-1, &status
, WNOHANG
)) > 0)
81 if (pid
== starter_pluto_pid())
83 if (pid
== starter_charon_pid())
85 if (WIFSIGNALED(status
))
87 DBG_log("child %d%s has been killed by sig %d\n",
88 pid
, name?name
:"", WTERMSIG(status
))
90 else if (WIFSTOPPED(status
))
92 DBG_log("child %d%s has been stopped by sig %d\n",
93 pid
, name?name
:"", WSTOPSIG(status
))
95 else if (WIFEXITED(status
))
97 DBG_log("child %d%s has quit (exit code %d)\n",
98 pid
, name?name
:"", WEXITSTATUS(status
))
102 DBG_log("child %d%s has quit", pid
, name?name
:"")
104 if (pid
== starter_pluto_pid())
105 starter_pluto_sigchild(pid
);
106 if (pid
== starter_charon_pid())
107 starter_charon_sigchild(pid
);
117 _action_
|= FLAG_ACTION_START_PLUTO
;
118 _action_
|= FLAG_ACTION_START_CHARON
;
122 _action_
|= FLAG_ACTION_UPDATE
;
128 _action_
|= FLAG_ACTION_QUIT
;
132 _action_
|= FLAG_ACTION_RELOAD
;
133 _action_
|= FLAG_ACTION_UPDATE
;
137 plog("fsig(): unknown signal %d -- investigate", signal
);
145 fprintf(stderr
, "Usage: starter [--nofork] [--auto-update <sec>] "
146 "[--debug|--debug-more|--debug-all]\n");
147 exit(LSB_RC_INVALID_ARGUMENT
);
150 int main (int argc
, char **argv
)
152 starter_config_t
*cfg
= NULL
;
153 starter_config_t
*new_cfg
;
154 starter_conn_t
*conn
, *conn2
;
155 starter_ca_t
*ca
, *ca2
;
163 unsigned long auto_update
= 0;
165 bool no_fork
= FALSE
;
167 /* global variables defined in log.h */
168 log_to_stderr
= TRUE
;
169 base_debugging
= DBG_NONE
;
171 /* parse command line */
172 for (i
= 1; i
< argc
; i
++)
174 if (streq(argv
[i
], "--debug"))
176 base_debugging
|= DBG_CONTROL
;
178 else if (streq(argv
[i
], "--debug-more"))
180 base_debugging
|= DBG_CONTROLMORE
;
182 else if (streq(argv
[i
], "--debug-all"))
184 base_debugging
|= DBG_ALL
;
186 else if (streq(argv
[i
], "--nofork"))
190 else if (streq(argv
[i
], "--auto-update") && i
+1 < argc
)
192 auto_update
= atoi(argv
[++i
]);
203 init_log("ipsec_starter");
204 cur_debugging
= base_debugging
;
206 signal(SIGHUP
, fsig
);
207 signal(SIGCHLD
, fsig
);
208 signal(SIGPIPE
, fsig
);
209 signal(SIGINT
, fsig
);
210 signal(SIGTERM
, fsig
);
211 signal(SIGQUIT
, fsig
);
212 signal(SIGALRM
, fsig
);
213 signal(SIGUSR1
, fsig
);
215 plog("Starting strongSwan %s IPsec [starter]...", ipsec_version_code());
217 /* verify that we can start */
220 plog("permission denied (must be superuser)");
221 exit(LSB_RC_NOT_ALLOWED
);
224 if (stat(PLUTO_PID_FILE
, &stb
) == 0)
226 plog("pluto is already running (%s exists) -- skipping pluto start", PLUTO_PID_FILE
);
230 _action_
|= FLAG_ACTION_START_PLUTO
;
232 if (stat(CHARON_PID_FILE
, &stb
) == 0)
234 plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE
);
238 _action_
|= FLAG_ACTION_START_CHARON
;
240 if (stat(DEV_RANDOM
, &stb
) != 0)
242 plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM
);
243 exit(LSB_RC_FAILURE
);
246 if (stat(DEV_URANDOM
, &stb
)!= 0)
248 plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM
);
249 exit(LSB_RC_FAILURE
);
252 cfg
= confread_load(CONFIG_FILE
);
253 if (cfg
== NULL
|| cfg
->err
> 0)
255 plog("unable to start strongSwan -- fatal errors in config");
260 exit(LSB_RC_INVALID_ARGUMENT
);
263 /* determine if we have a native netkey IPsec stack */
264 if (!starter_netkey_init())
266 plog("no netkey IPSec stack detected");
267 exit(LSB_RC_FAILURE
);
270 last_reload
= time(NULL
);
272 if (stat(STARTER_PID_FILE
, &stb
) == 0)
274 plog("starter is already running (%s exists) -- no fork done", STARTER_PID_FILE
);
275 exit(LSB_RC_SUCCESS
);
278 /* fork if we're not debugging stuff */
281 log_to_stderr
= FALSE
;
287 int fnull
= open("/dev/null", O_RDWR
);
291 dup2(fnull
, STDIN_FILENO
);
292 dup2(fnull
, STDOUT_FILENO
);
293 dup2(fnull
, STDERR_FILENO
);
300 plog("can't fork: %s", strerror(errno
));
303 exit(LSB_RC_SUCCESS
);
307 /* save pid file in /var/run/starter.pid */
309 FILE *fd
= fopen(STARTER_PID_FILE
, "w");
313 fprintf(fd
, "%u\n", getpid());
321 * Stop pluto/charon (if started) and exit
323 if (_action_
& FLAG_ACTION_QUIT
)
325 if (starter_pluto_pid())
326 starter_stop_pluto();
327 if (starter_charon_pid())
328 starter_stop_charon();
329 starter_netkey_cleanup();
331 unlink(STARTER_PID_FILE
);
333 #ifdef LEAK_DETECTIVE
335 #endif /* LEAK_DETECTIVE */
337 plog("ipsec starter stopped");
338 exit(LSB_RC_SUCCESS
);
342 * Delete all connections. Will be added below
344 if (_action_
& FLAG_ACTION_RELOAD
)
346 if (starter_pluto_pid() || starter_charon_pid())
348 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
350 if (conn
->state
== STATE_ADDED
)
352 if (starter_charon_pid())
354 starter_stroke_del_conn(conn
);
356 if (starter_pluto_pid())
358 starter_whack_del_conn(conn
);
360 conn
->state
= STATE_TO_ADD
;
363 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
365 if (ca
->state
== STATE_ADDED
)
367 if (starter_charon_pid())
369 starter_stroke_del_ca(ca
);
371 if (starter_pluto_pid())
373 starter_whack_del_ca(ca
);
375 ca
->state
= STATE_TO_ADD
;
379 _action_
&= ~FLAG_ACTION_RELOAD
;
383 * Update configuration
385 if (_action_
& FLAG_ACTION_UPDATE
)
389 DBG_log("Reloading config...")
391 new_cfg
= confread_load(CONFIG_FILE
);
393 if (new_cfg
->err
+ new_cfg
->non_fatal_err
== 0)
395 /* Switch to new config. New conn will be loaded below */
396 if (!starter_cmp_defaultroute(&new_cfg
->defaultroute
397 , &cfg
->defaultroute
))
399 _action_
|= FLAG_ACTION_LISTEN
;
402 if (!starter_cmp_pluto(cfg
, new_cfg
))
404 plog("Pluto has changed");
405 if (starter_pluto_pid())
406 starter_stop_pluto();
407 _action_
&= ~FLAG_ACTION_LISTEN
;
408 _action_
|= FLAG_ACTION_START_PLUTO
;
412 /* Only reload conn and ca sections if pluto is not killed */
414 /* Look for new connections that are already loaded */
415 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
417 if (conn
->state
== STATE_ADDED
)
419 for (conn2
= new_cfg
->conn_first
; conn2
; conn2
= conn2
->next
)
421 if (conn2
->state
== STATE_TO_ADD
&& starter_cmp_conn(conn
, conn2
))
423 conn
->state
= STATE_REPLACED
;
424 conn2
->state
= STATE_ADDED
;
425 conn2
->id
= conn
->id
;
432 /* Remove conn sections that have become unused */
433 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
435 if (conn
->state
== STATE_ADDED
)
437 if (starter_charon_pid())
439 starter_stroke_del_conn(conn
);
441 if (starter_pluto_pid())
443 starter_whack_del_conn(conn
);
448 /* Look for new ca sections that are already loaded */
449 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
451 if (ca
->state
== STATE_ADDED
)
453 for (ca2
= new_cfg
->ca_first
; ca2
; ca2
= ca2
->next
)
455 if (ca2
->state
== STATE_TO_ADD
&& starter_cmp_ca(ca
, ca2
))
457 ca
->state
= STATE_REPLACED
;
458 ca2
->state
= STATE_ADDED
;
465 /* Remove ca sections that have become unused */
466 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
468 if (ca
->state
== STATE_ADDED
)
470 if (starter_charon_pid())
472 starter_stroke_del_ca(ca
);
474 if (starter_pluto_pid())
476 starter_whack_del_ca(ca
);
486 plog("can't reload config file due to errors -- keeping old one");
487 confread_free(new_cfg
);
489 _action_
&= ~FLAG_ACTION_UPDATE
;
490 last_reload
= time(NULL
);
496 if (_action_
& FLAG_ACTION_START_PLUTO
)
498 if (cfg
->setup
.plutostart
&& !starter_pluto_pid())
501 DBG_log("Attempting to start pluto...")
504 if (starter_start_pluto(cfg
, no_fork
) == 0)
506 starter_whack_listen();
510 /* schedule next try */
511 alarm(PLUTO_RESTART_DELAY
);
514 _action_
&= ~FLAG_ACTION_START_PLUTO
;
516 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
518 if (ca
->state
== STATE_ADDED
)
519 ca
->state
= STATE_TO_ADD
;
522 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
524 if (conn
->state
== STATE_ADDED
)
525 conn
->state
= STATE_TO_ADD
;
532 if (_action_
& FLAG_ACTION_START_CHARON
)
534 if (cfg
->setup
.charonstart
&& !starter_charon_pid())
537 DBG_log("Attempting to start charon...")
539 if (starter_start_charon(cfg
, no_fork
))
541 /* schedule next try */
542 alarm(PLUTO_RESTART_DELAY
);
544 starter_stroke_configure(cfg
);
546 _action_
&= ~FLAG_ACTION_START_CHARON
;
550 * Tell pluto to reread its interfaces
552 if (_action_
& FLAG_ACTION_LISTEN
)
554 if (starter_pluto_pid())
556 starter_whack_listen();
557 _action_
&= ~FLAG_ACTION_LISTEN
;
562 * Add stale conn and ca sections
564 if (starter_pluto_pid() || starter_charon_pid())
566 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
568 if (ca
->state
== STATE_TO_ADD
)
570 if (starter_charon_pid())
572 starter_stroke_add_ca(ca
);
574 if (starter_pluto_pid())
576 starter_whack_add_ca(ca
);
578 ca
->state
= STATE_ADDED
;
582 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
584 if (conn
->state
== STATE_TO_ADD
)
588 /* affect new unique id */
591 if (starter_charon_pid())
593 starter_stroke_add_conn(cfg
, conn
);
595 if (starter_pluto_pid())
597 starter_whack_add_conn(conn
);
599 conn
->state
= STATE_ADDED
;
601 if (conn
->startup
== STARTUP_START
)
603 if (conn
->keyexchange
== KEY_EXCHANGE_IKEV2
)
605 if (starter_charon_pid())
607 starter_stroke_initiate_conn(conn
);
612 if (starter_pluto_pid())
614 starter_whack_initiate_conn(conn
);
618 else if (conn
->startup
== STARTUP_ROUTE
)
620 if (conn
->keyexchange
== KEY_EXCHANGE_IKEV2
)
622 if (starter_charon_pid())
624 starter_stroke_route_conn(conn
);
629 if (starter_pluto_pid())
631 starter_whack_route_conn(conn
);
640 * If auto_update activated, when to stop select
644 time_t now
= time(NULL
);
646 tv
.tv_sec
= (now
< last_reload
+ auto_update
)
647 ?
(last_reload
+ auto_update
-now
) : 0;
652 * Wait for something to happen
654 if (select(0, NULL
, NULL
, NULL
, auto_update ?
&tv
: NULL
) == 0)
656 /* timeout -> auto_update */
657 _action_
|= FLAG_ACTION_UPDATE
;
660 exit(LSB_RC_SUCCESS
);