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