]>
git.ipfire.org Git - thirdparty/strongswan.git/blob - programs/starter/starter.c
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 "invokepluto.h"
43 #include "interfaces.h"
45 #define FLAG_ACTION_START_PLUTO 0x01
46 #define FLAG_ACTION_UPDATE 0x02
47 #define FLAG_ACTION_RELOAD 0x04
48 #define FLAG_ACTION_QUIT 0x08
49 #define FLAG_ACTION_LISTEN 0x10
51 static unsigned int _action_
= 0;
64 while ((pid
= waitpid(-1, &status
, WNOHANG
)) > 0)
66 if (pid
== starter_pluto_pid())
68 if (WIFSIGNALED(status
))
70 DBG_log("child %d%s has been killed by sig %d\n",
71 pid
, name
?name
:"", WTERMSIG(status
))
73 else if (WIFSTOPPED(status
))
75 DBG_log("child %d%s has been stopped by sig %d\n",
76 pid
, name
?name
:"", WSTOPSIG(status
))
78 else if (WIFEXITED(status
))
80 DBG_log("child %d%s has quit (exit code %d)\n",
81 pid
, name
?name
:"", WEXITSTATUS(status
))
85 DBG_log("child %d%s has quit", pid
, name
?name
:"")
88 if (pid
== starter_pluto_pid())
89 starter_pluto_sigchild(pid
);
99 _action_
|= FLAG_ACTION_START_PLUTO
;
103 _action_
|= FLAG_ACTION_UPDATE
;
109 _action_
|= FLAG_ACTION_QUIT
;
113 _action_
|= FLAG_ACTION_RELOAD
;
114 _action_
|= FLAG_ACTION_UPDATE
;
118 plog("fsig(): unknown signal %d -- investigate", signal
);
126 fprintf(stderr
, "Usage: starter [--nofork] [--auto-update <sec>] "
127 "[--debug|--debug-more|--debug-all]\n");
131 int main (int argc
, char **argv
)
133 starter_config_t
*cfg
= NULL
;
134 starter_config_t
*new_cfg
;
135 starter_conn_t
*conn
, *conn2
;
136 starter_ca_t
*ca
, *ca2
;
144 unsigned long auto_update
= 0;
147 bool no_fork
= FALSE
;
149 /* global variables defined in log.h */
150 log_to_stderr
= TRUE
;
151 base_debugging
= DBG_NONE
;
153 /* parse command line */
154 for (i
= 1; i
< argc
; i
++)
156 if (streq(argv
[i
], "--debug"))
158 base_debugging
|= DBG_CONTROL
;
160 else if (streq(argv
[i
], "--debug-more"))
162 base_debugging
|= DBG_CONTROLMORE
;
164 else if (streq(argv
[i
], "--debug-all"))
166 base_debugging
|= DBG_ALL
;
168 else if (streq(argv
[i
], "--nofork"))
172 else if (streq(argv
[i
], "--auto-update") && i
+1 < argc
)
174 auto_update
= atoi(argv
[++i
]);
185 init_log("ipsec_starter");
186 cur_debugging
= base_debugging
;
188 signal(SIGHUP
, fsig
);
189 signal(SIGCHLD
, fsig
);
190 signal(SIGPIPE
, fsig
);
191 signal(SIGINT
, fsig
);
192 signal(SIGTERM
, fsig
);
193 signal(SIGQUIT
, fsig
);
194 signal(SIGALRM
, fsig
);
195 signal(SIGUSR1
, fsig
);
197 /* verify that we can start */
200 plog("permission denied (must be superuser)");
204 if (stat(PID_FILE
, &stb
) == 0)
206 plog("pluto is already running (%s exists) -- aborting", PID_FILE
);
210 if (stat(DEV_RANDOM
, &stb
) != 0)
212 plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM
);
216 if (stat(DEV_URANDOM
, &stb
)!= 0)
218 plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM
);
222 cfg
= confread_load(CONFIG_FILE
);
225 plog("unable to start strongSwan -- errors in config");
229 /* determine if we have a native netkey IPsec stack */
230 has_netkey
= starter_netkey_init();
234 /* determine if we have a KLIPS IPsec stack instead */
235 if (starter_klips_init())
237 starter_klips_set_config(cfg
);
238 starter_ifaces_init();
239 starter_ifaces_clear();
243 plog("neither netkey nor KLIPS IPSec stack detected");
248 last_reload
= time(NULL
);
250 plog("Starting strongSwan IPsec %s [starter]...", ipsec_version_code());
252 /* fork if we're not debugging stuff */
255 log_to_stderr
= FALSE
;
261 int fnull
= open("/dev/null", O_RDWR
);
265 dup2(fnull
, STDIN_FILENO
);
266 dup2(fnull
, STDOUT_FILENO
);
267 dup2(fnull
, STDERR_FILENO
);
273 plog("can't fork: %s", strerror(errno
));
280 /* save pid file in /var/run/starter.pid */
282 FILE *fd
= fopen(MY_PID_FILE
, "w");
286 fprintf(fd
, "%u\n", getpid());
293 starter_ifaces_load(cfg
->setup
.interfaces
294 , cfg
->setup
.overridemtu
295 , cfg
->setup
.nat_traversal
296 , &cfg
->defaultroute
);
299 _action_
= FLAG_ACTION_START_PLUTO
;
304 * Stop pluto (if started) and exit
306 if (_action_
& FLAG_ACTION_QUIT
)
308 if (starter_pluto_pid())
309 starter_stop_pluto();
311 starter_netkey_cleanup();
314 starter_ifaces_clear();
315 starter_klips_cleanup();
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())
335 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
337 if (conn
->state
== STATE_ADDED
)
339 starter_whack_del_conn(conn
);
340 conn
->state
= STATE_TO_ADD
;
343 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
345 if (ca
->state
== STATE_ADDED
)
347 starter_whack_del_ca(ca
);
348 ca
->state
= STATE_TO_ADD
;
352 _action_
&= ~FLAG_ACTION_RELOAD
;
356 * Update configuration
358 if (_action_
& FLAG_ACTION_UPDATE
)
362 DBG_log("Reloading config...")
364 new_cfg
= confread_load(CONFIG_FILE
);
368 /* Switch to new config. New conn will be loaded below */
371 if (!starter_cmp_defaultroute(&new_cfg
->defaultroute
372 , &cfg
->defaultroute
))
374 _action_
|= FLAG_ACTION_LISTEN
;
379 if (!starter_cmp_klips(cfg
, new_cfg
))
381 plog("KLIPS has changed");
382 starter_klips_set_config(new_cfg
);
385 if (starter_ifaces_load(new_cfg
->setup
.interfaces
386 , new_cfg
->setup
.overridemtu
387 , new_cfg
->setup
.nat_traversal
388 , &new_cfg
->defaultroute
))
390 _action_
|= FLAG_ACTION_LISTEN
;
394 if (!starter_cmp_pluto(cfg
, new_cfg
))
396 plog("Pluto has changed");
397 if (starter_pluto_pid())
398 starter_stop_pluto();
399 _action_
&= ~FLAG_ACTION_LISTEN
;
400 _action_
|= FLAG_ACTION_START_PLUTO
;
404 /* Only reload conn and ca sections if pluto is not killed */
406 /* Look for new connections that are already loaded */
407 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
409 if (conn
->state
== STATE_ADDED
)
411 for (conn2
= new_cfg
->conn_first
; conn2
; conn2
= conn2
->next
)
413 if (conn2
->state
== STATE_TO_ADD
414 && starter_cmp_conn(conn
, conn2
))
416 conn
->state
= STATE_REPLACED
;
417 conn2
->state
= STATE_ADDED
;
418 conn2
->id
= conn
->id
;
425 /* Remove conn sections that have become unused */
426 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
428 if (conn
->state
== STATE_ADDED
)
429 starter_whack_del_conn(conn
);
432 /* Look for new ca sections that are already loaded */
433 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
435 if (ca
->state
== STATE_ADDED
)
437 for (ca2
= new_cfg
->ca_first
; ca2
; ca2
= ca2
->next
)
439 if (ca2
->state
== STATE_TO_ADD
440 && starter_cmp_ca(ca
, ca2
))
442 ca
->state
= STATE_REPLACED
;
443 ca2
->state
= STATE_ADDED
;
450 /* Remove ca sections that have become unused */
451 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
453 if (ca
->state
== STATE_ADDED
)
454 starter_whack_del_ca(ca
);
462 plog("can't reload config file: %s -- keeping old one");
464 _action_
&= ~FLAG_ACTION_UPDATE
;
465 last_reload
= time(NULL
);
471 if (_action_
& FLAG_ACTION_START_PLUTO
)
473 if (starter_pluto_pid() == 0)
476 DBG_log("Attempting to start pluto...")
479 starter_klips_clear();
481 if (starter_start_pluto(cfg
, no_fork
) == 0)
483 starter_whack_listen();
487 /* schedule next try */
488 alarm(PLUTO_RESTART_DELAY
);
491 _action_
&= ~FLAG_ACTION_START_PLUTO
;
493 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
495 if (ca
->state
== STATE_ADDED
)
496 ca
->state
= STATE_TO_ADD
;
499 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
501 if (conn
->state
== STATE_ADDED
)
502 conn
->state
= STATE_TO_ADD
;
507 * Tell pluto to reread its interfaces
509 if (_action_
& FLAG_ACTION_LISTEN
)
511 starter_whack_listen();
512 _action_
&= ~FLAG_ACTION_LISTEN
;
516 * Add stale conn and ca sections
518 if (starter_pluto_pid() != 0)
520 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
522 if (ca
->state
== STATE_TO_ADD
)
524 starter_whack_add_ca(ca
);
525 ca
->state
= STATE_ADDED
;
529 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
531 if (conn
->state
== STATE_TO_ADD
)
535 /* affect new unique id */
538 starter_whack_add_conn(conn
);
539 conn
->state
= STATE_ADDED
;
540 if (conn
->startup
== STARTUP_START
)
541 starter_whack_initiate_conn(conn
);
542 else if (conn
->startup
== STARTUP_ROUTE
)
543 starter_whack_route_conn(conn
);
549 * If auto_update activated, when to stop select
553 time_t now
= time(NULL
);
554 tv
.tv_sec
= (now
< last_reload
+ auto_update
)
555 ? (last_reload
+ auto_update
-now
) : 0;
560 * Wait for something to happen
562 if (select(0, NULL
, NULL
, NULL
, auto_update
? &tv
: NULL
) == 0)
564 /* timeout -> auto_update */
565 _action_
|= FLAG_ACTION_UPDATE
;