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