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