1f857ce44254821e22836882ead6158d63e466c7
[strongswan.git] / src / starter / starter.c
1 /* strongSwan IPsec starter
2 * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
3 *
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>.
8 *
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
12 * for more details.
13 *
14 * RCSID $Id: starter.c,v 1.23 2006/02/15 18:37:46 as Exp $
15 */
16
17 #include <sys/types.h>
18 #include <sys/wait.h>
19 #include <sys/stat.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <signal.h>
23 #include <unistd.h>
24 #include <sys/time.h>
25 #include <time.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <fcntl.h>
29
30 #include <freeswan.h>
31
32 #include "../pluto/constants.h"
33 #include "../pluto/defs.h"
34 #include "../pluto/log.h"
35
36 #include "confread.h"
37 #include "files.h"
38 #include "starterwhack.h"
39 #include "starterstroke.h"
40 #include "invokepluto.h"
41 #include "invokecharon.h"
42 #include "netkey.h"
43 #include "cmp.h"
44 #include "interfaces.h"
45
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
52
53 static unsigned int _action_ = 0;
54
55 static void
56 fsig(int signal)
57 {
58 switch (signal)
59 {
60 case SIGCHLD:
61 {
62 int status;
63 pid_t pid;
64 char *name = NULL;
65
66 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
67 {
68 if (pid == starter_pluto_pid())
69 name = " (Pluto)";
70 #ifdef IKEV2
71 if (pid == starter_charon_pid())
72 name = " (Charon)";
73 #endif /* IKEV2 */
74 if (WIFSIGNALED(status))
75 DBG(DBG_CONTROL,
76 DBG_log("child %d%s has been killed by sig %d\n",
77 pid, name?name:"", WTERMSIG(status))
78 )
79 else if (WIFSTOPPED(status))
80 DBG(DBG_CONTROL,
81 DBG_log("child %d%s has been stopped by sig %d\n",
82 pid, name?name:"", WSTOPSIG(status))
83 )
84 else if (WIFEXITED(status))
85 DBG(DBG_CONTROL,
86 DBG_log("child %d%s has quit (exit code %d)\n",
87 pid, name?name:"", WEXITSTATUS(status))
88 )
89 else
90 DBG(DBG_CONTROL,
91 DBG_log("child %d%s has quit", pid, name?name:"")
92 )
93
94 if (pid == starter_pluto_pid())
95 starter_pluto_sigchild(pid);
96 #ifdef IKEV2
97 if (pid == starter_charon_pid())
98 starter_charon_sigchild(pid);
99 #endif /* IKEV2 */
100 }
101 }
102 break;
103
104 case SIGPIPE:
105 /** ignore **/
106 break;
107
108 case SIGALRM:
109 _action_ |= FLAG_ACTION_START_PLUTO;
110 #ifdef IKEV2
111 _action_ |= FLAG_ACTION_START_CHARON;
112 #endif /* IKEV2 */
113 break;
114
115 case SIGHUP:
116 _action_ |= FLAG_ACTION_UPDATE;
117 break;
118
119 case SIGTERM:
120 case SIGQUIT:
121 case SIGINT:
122 _action_ |= FLAG_ACTION_QUIT;
123 break;
124
125 case SIGUSR1:
126 _action_ |= FLAG_ACTION_RELOAD;
127 _action_ |= FLAG_ACTION_UPDATE;
128 break;
129
130 default:
131 plog("fsig(): unknown signal %d -- investigate", signal);
132 break;
133 }
134 }
135
136 static void
137 usage(char *name)
138 {
139 fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>] "
140 "[--debug|--debug-more|--debug-all]\n");
141 exit(1);
142 }
143
144 int main (int argc, char **argv)
145 {
146 starter_config_t *cfg = NULL;
147 starter_config_t *new_cfg;
148 starter_conn_t *conn, *conn2;
149 starter_ca_t *ca, *ca2;
150
151 struct stat stb;
152
153 char *err = NULL;
154 int i;
155 int id = 1;
156 struct timeval tv;
157 unsigned long auto_update = 0;
158 time_t last_reload;
159 bool no_fork = FALSE;
160
161 /* global variables defined in log.h */
162 log_to_stderr = TRUE;
163 base_debugging = DBG_NONE;
164
165 /* parse command line */
166 for (i = 1; i < argc; i++)
167 {
168 if (streq(argv[i], "--debug"))
169 {
170 base_debugging |= DBG_CONTROL;
171 }
172 else if (streq(argv[i], "--debug-more"))
173 {
174 base_debugging |= DBG_CONTROLMORE;
175 }
176 else if (streq(argv[i], "--debug-all"))
177 {
178 base_debugging |= DBG_ALL;
179 }
180 else if (streq(argv[i], "--nofork"))
181 {
182 no_fork = TRUE;
183 }
184 else if (streq(argv[i], "--auto-update") && i+1 < argc)
185 {
186 auto_update = atoi(argv[++i]);
187 if (!auto_update)
188 usage(argv[0]);
189 }
190 else
191 {
192 usage(argv[0]);
193 }
194 }
195
196 /* Init */
197 init_log("ipsec_starter");
198 cur_debugging = base_debugging;
199
200 signal(SIGHUP, fsig);
201 signal(SIGCHLD, fsig);
202 signal(SIGPIPE, fsig);
203 signal(SIGINT, fsig);
204 signal(SIGTERM, fsig);
205 signal(SIGQUIT, fsig);
206 signal(SIGALRM, fsig);
207 signal(SIGUSR1, fsig);
208
209 plog("Starting strongSwan IPsec %s [starter]...", ipsec_version_code());
210
211 /* verify that we can start */
212 if (getuid() != 0)
213 {
214 plog("permission denied (must be superuser)");
215 exit(1);
216 }
217
218 if (stat(PLUTO_PID_FILE, &stb) == 0)
219 {
220 plog("pluto is already running (%s exists) -- skipping pluto start", PLUTO_PID_FILE);
221 }
222 else
223 {
224 _action_ |= FLAG_ACTION_START_PLUTO;
225 }
226 #ifdef IKEV2
227 if (stat(CHARON_PID_FILE, &stb) == 0)
228 {
229 plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE);
230 }
231 else
232 {
233 _action_ |= FLAG_ACTION_START_CHARON;
234 }
235 #endif /* IKEV2 */
236 if (stat(DEV_RANDOM, &stb) != 0)
237 {
238 plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
239 exit(1);
240 }
241
242 if (stat(DEV_URANDOM, &stb)!= 0)
243 {
244 plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
245 exit(1);
246 }
247
248 cfg = confread_load(CONFIG_FILE);
249 if (!cfg)
250 {
251 plog("unable to start strongSwan -- errors in config");
252 exit(1);
253 }
254
255 /* determine if we have a native netkey IPsec stack */
256 if (!starter_netkey_init())
257 {
258 plog("nor netkey IPSec stack detected");
259 exit(1);
260 }
261
262 last_reload = time(NULL);
263
264 if (stat(MY_PID_FILE, &stb) == 0)
265 {
266 plog("starter is already running (%s exists) -- no fork done", MY_PID_FILE);
267 exit(0);
268 }
269
270 /* fork if we're not debugging stuff */
271 if (!no_fork)
272 {
273 log_to_stderr = FALSE;
274
275 switch (fork())
276 {
277 case 0:
278 {
279 int fnull = open("/dev/null", O_RDWR);
280
281 if (fnull >= 0)
282 {
283 dup2(fnull, STDIN_FILENO);
284 dup2(fnull, STDOUT_FILENO);
285 dup2(fnull, STDERR_FILENO);
286 close(fnull);
287 }
288 }
289 break;
290 case -1:
291 plog("can't fork: %s", strerror(errno));
292 break;
293 default:
294 exit(0);
295 }
296 }
297
298 /* save pid file in /var/run/starter.pid */
299 {
300 FILE *fd = fopen(MY_PID_FILE, "w");
301
302 if (fd)
303 {
304 fprintf(fd, "%u\n", getpid());
305 fclose(fd);
306 }
307 }
308
309 for (;;)
310 {
311 /*
312 * Stop pluto/charon (if started) and exit
313 */
314 if (_action_ & FLAG_ACTION_QUIT)
315 {
316 if (starter_pluto_pid())
317 starter_stop_pluto();
318 #ifdef IKEV2
319 if (starter_charon_pid())
320 starter_stop_charon();
321 #endif /* IKEV2 */
322 starter_netkey_cleanup();
323 confread_free(cfg);
324 unlink(MY_PID_FILE);
325 unlink(INFO_FILE);
326 #ifdef LEAK_DETECTIVE
327 report_leaks();
328 #endif /* LEAK_DETECTIVE */
329 close_log();
330 plog("ipsec starter stopped");
331 exit(0);
332 }
333
334 /*
335 * Delete all connections. Will be added below
336 */
337 if (_action_ & FLAG_ACTION_RELOAD)
338 {
339 if (starter_pluto_pid())
340 {
341 for (conn = cfg->conn_first; conn; conn = conn->next)
342 {
343 if (conn->state == STATE_ADDED)
344 {
345 #ifdef IKEV2
346 if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
347 {
348 starter_stroke_del_conn(conn);
349 }
350 #endif /* IKEV2 */
351 else
352 {
353 starter_whack_del_conn(conn);
354 }
355 conn->state = STATE_TO_ADD;
356 }
357 }
358 for (ca = cfg->ca_first; ca; ca = ca->next)
359 {
360 if (ca->state == STATE_ADDED)
361 {
362 starter_whack_del_ca(ca);
363 ca->state = STATE_TO_ADD;
364 }
365 }
366 }
367 _action_ &= ~FLAG_ACTION_RELOAD;
368 }
369
370 /*
371 * Update configuration
372 */
373 if (_action_ & FLAG_ACTION_UPDATE)
374 {
375 err = NULL;
376 DBG(DBG_CONTROL,
377 DBG_log("Reloading config...")
378 )
379 new_cfg = confread_load(CONFIG_FILE);
380
381 if (new_cfg)
382 {
383 /* Switch to new config. New conn will be loaded below */
384 if (!starter_cmp_defaultroute(&new_cfg->defaultroute
385 , &cfg->defaultroute))
386 {
387 _action_ |= FLAG_ACTION_LISTEN;
388 }
389
390 if (!starter_cmp_pluto(cfg, new_cfg))
391 {
392 plog("Pluto has changed");
393 if (starter_pluto_pid())
394 starter_stop_pluto();
395 _action_ &= ~FLAG_ACTION_LISTEN;
396 _action_ |= FLAG_ACTION_START_PLUTO;
397 }
398 else
399 {
400 /* Only reload conn and ca sections if pluto is not killed */
401
402 /* Look for new connections that are already loaded */
403 for (conn = cfg->conn_first; conn; conn = conn->next)
404 {
405 if (conn->state == STATE_ADDED)
406 {
407 for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
408 {
409 if (conn2->state == STATE_TO_ADD
410 && starter_cmp_conn(conn, conn2))
411 {
412 conn->state = STATE_REPLACED;
413 conn2->state = STATE_ADDED;
414 conn2->id = conn->id;
415 break;
416 }
417 }
418 }
419 }
420
421 /* Remove conn sections that have become unused */
422 for (conn = cfg->conn_first; conn; conn = conn->next)
423 {
424 if (conn->state == STATE_ADDED)
425 {
426 #ifdef IKEV2
427 if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
428 {
429 starter_stroke_del_conn(conn);
430 }
431 else
432 #endif /* IKEV2 */
433 {
434 starter_whack_del_conn(conn);
435 }
436 }
437 }
438
439 /* Look for new ca sections that are already loaded */
440 for (ca = cfg->ca_first; ca; ca = ca->next)
441 {
442 if (ca->state == STATE_ADDED)
443 {
444 for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
445 {
446 if (ca2->state == STATE_TO_ADD
447 && starter_cmp_ca(ca, ca2))
448 {
449 ca->state = STATE_REPLACED;
450 ca2->state = STATE_ADDED;
451 break;
452 }
453 }
454 }
455 }
456
457 /* Remove ca sections that have become unused */
458 for (ca = cfg->ca_first; ca; ca = ca->next)
459 {
460 if (ca->state == STATE_ADDED)
461 starter_whack_del_ca(ca);
462 }
463 }
464 confread_free(cfg);
465 cfg = new_cfg;
466 }
467 else
468 {
469 plog("can't reload config file: %s -- keeping old one");
470 }
471 _action_ &= ~FLAG_ACTION_UPDATE;
472 last_reload = time(NULL);
473 }
474
475 /*
476 * Start pluto
477 */
478 if (_action_ & FLAG_ACTION_START_PLUTO)
479 {
480 if (starter_pluto_pid() == 0)
481 {
482 DBG(DBG_CONTROL,
483 DBG_log("Attempting to start pluto...")
484 )
485
486 if (starter_start_pluto(cfg, no_fork) == 0)
487 {
488 starter_whack_listen();
489 }
490 else
491 {
492 /* schedule next try */
493 alarm(PLUTO_RESTART_DELAY);
494 }
495 }
496 _action_ &= ~FLAG_ACTION_START_PLUTO;
497
498 for (ca = cfg->ca_first; ca; ca = ca->next)
499 {
500 if (ca->state == STATE_ADDED)
501 ca->state = STATE_TO_ADD;
502 }
503
504 for (conn = cfg->conn_first; conn; conn = conn->next)
505 {
506 if (conn->state == STATE_ADDED)
507 conn->state = STATE_TO_ADD;
508 }
509 }
510
511 #ifdef IKEV2
512 /*
513 * Start charon
514 */
515 if (_action_ & FLAG_ACTION_START_CHARON)
516 {
517 if (starter_charon_pid() == 0)
518 {
519 DBG(DBG_CONTROL,
520 DBG_log("Attempting to start charon...")
521 )
522 if (starter_start_charon(cfg, no_fork) != 0)
523 {
524 /* schedule next try */
525 alarm(PLUTO_RESTART_DELAY);
526 }
527 }
528 _action_ &= ~FLAG_ACTION_START_CHARON;
529 }
530 #endif /* IKEV2 */
531
532 /*
533 * Tell pluto to reread its interfaces
534 */
535 if (_action_ & FLAG_ACTION_LISTEN)
536 {
537 starter_whack_listen();
538 _action_ &= ~FLAG_ACTION_LISTEN;
539 }
540
541 /*
542 * Add stale conn and ca sections
543 */
544 if (starter_pluto_pid() != 0)
545 {
546 for (ca = cfg->ca_first; ca; ca = ca->next)
547 {
548 if (ca->state == STATE_TO_ADD)
549 {
550 starter_whack_add_ca(ca);
551 ca->state = STATE_ADDED;
552 }
553 }
554
555 for (conn = cfg->conn_first; conn; conn = conn->next)
556 {
557 if (conn->state == STATE_TO_ADD)
558 {
559 if (conn->id == 0)
560 {
561 /* affect new unique id */
562 conn->id = id++;
563 }
564 #ifdef IKEV2
565 if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
566 {
567 starter_stroke_add_conn(conn);
568 }
569 else
570 #endif /* IKEV2 */
571 {
572 starter_whack_add_conn(conn);
573 }
574 conn->state = STATE_ADDED;
575
576 if (conn->startup == STARTUP_START)
577 {
578 #ifdef IKEV2
579 if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
580 {
581 starter_stroke_initiate_conn(conn);
582 }
583 else
584 #endif /* IKEV2 */
585 {
586 starter_whack_initiate_conn(conn);
587 }
588 }
589 else if (conn->startup == STARTUP_ROUTE)
590 {
591 #ifdef IKEV2
592 if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
593 {
594 starter_stroke_route_conn(conn);
595 }
596 else
597 #endif /* IKEV2 */
598 {
599 starter_whack_route_conn(conn);
600 }
601 }
602 }
603 }
604 }
605
606 /*
607 * If auto_update activated, when to stop select
608 */
609 if (auto_update)
610 {
611 time_t now = time(NULL);
612
613 tv.tv_sec = (now < last_reload + auto_update)
614 ? (last_reload + auto_update-now) : 0;
615 tv.tv_usec = 0;
616 }
617
618 /*
619 * Wait for something to happen
620 */
621 if (select(0, NULL, NULL, NULL, auto_update ? &tv : NULL) == 0)
622 {
623 /* timeout -> auto_update */
624 _action_ |= FLAG_ACTION_UPDATE;
625 }
626 }
627
628 return 0;
629 }
630