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