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