OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / pluto / main.c
1 /* Pluto main program
2  * Copyright (C) 1997 Angelos D. Keromytis.
3  * Copyright (C) 1998-2001  D. Hugh Redelmeier.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  *
15  * RCSID $Id$
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <sys/un.h>
27 #include <fcntl.h>
28 #include <getopt.h>
29 #include <resolv.h>
30 #include <arpa/nameser.h>       /* missing from <resolv.h> on old systems */
31
32 #include <freeswan.h>
33
34 #include "constants.h"
35 #include "defs.h"
36 #include "id.h"
37 #include "x509.h"
38 #include "connections.h"        /* needs id.h */
39 #include "packet.h"
40 #include "demux.h"  /* needs packet.h */
41 #include "server.h"
42 #include "kernel.h"
43 #include "log.h"
44 #include "x509.h"
45 #include "preshared.h"
46 #include "adns.h"       /* needs <resolv.h> */
47 #include "dnskey.h"     /* needs preshared.h and adns.h */
48 #include "rnd.h"
49 #include "state.h"
50
51 #include "sha1.h"
52 #include "md5.h"
53 #include "crypto.h"     /* requires sha1.h and md5.h */
54
55 #ifdef VIRTUAL_IP
56 #include "virtual.h"
57 #endif
58
59 #ifdef NAT_TRAVERSAL
60 #include "nat_traversal.h"
61 #endif
62
63 char *phys_interfaces[NUM_INTERFACES];
64
65 /*
66  *  Version of X.509 patch
67  */
68 static const char x509patch_version[] = "0.9.13";
69
70 static void
71 usage(const char *mess)
72 {
73     if (mess != NULL && *mess != '\0')
74         fprintf(stderr, "%s\n", mess);
75     fprintf(stderr,
76         "Usage: pluto"
77             " [--help]"
78             " [--version]"
79             " [--optionsfrom <filename>]"
80             " \\\n\t"
81             "[--nofork]"
82             " [--stderrlog]"
83             " [--noklips]"
84             " [--nocrsend]"
85             " [--uniqueids]"
86             " \\\n\t"
87             "[--interface <ifname>]"
88             " [--ikeport <port-number>]"
89             " \\\n\t"
90             "[--ctlbase <path>]"
91             " \\\n\t"
92             "[--secretsfile <secrets-file>]"
93             " \\\n\t"
94             "[--adns <pathname>]"
95 #ifdef DEBUG
96             " \\\n\t"
97             "[--debug-none]"
98             " [--debug-all]"
99             " \\\n\t"
100             "[--debug-raw]"
101             " [--debug-crypt]"
102             " [--debug-parsing]"
103             " [--debug-emitting]"
104             " \\\n\t"
105             "[--debug-control]"
106             " [--debug-klips]"
107             " [--debug-dns]"
108             " [ --debug-private]"
109 #endif
110 #ifdef NAT_TRAVERSAL
111             " [ --debug-nat_t]"
112             " \\\n\t"
113             "[--nat_traversal] [--keep_alive <delay_sec>]"
114             " \\\n\t"
115                 "[--force_keepalive] [--disable_port_floating]"
116 #endif
117 #ifdef VIRTUAL_IP
118             " \\\n\t"
119             "[--virtual_private <network_list>]"
120 #endif
121             "\n"
122         "FreeS/WAN %s\n",
123         ipsec_version_code());
124     exit_pluto(mess == NULL? 0 : 1);
125 }
126
127 static void init_interfaces( char *ipsec0, char *ipsec1, char *ipsec2, char *ipsec3)
128 {
129         if (ipsec0)
130                 phys_interfaces[0] = strdup(ipsec0);
131         if (ipsec1)
132                 phys_interfaces[1] = strdup(ipsec1);
133         if (ipsec2)
134                 phys_interfaces[2] = strdup(ipsec2);
135         if (ipsec3)
136                 phys_interfaces[3] = strdup(ipsec3);
137 }
138
139 /* lock file support
140  * - provides convenient way for scripts to find Pluto's pid
141  * - prevents multiple Plutos competing for the same port
142  * - same basename as unix domain control socket
143  * NOTE: will not take account of sharing LOCK_DIR with other systems.
144  */
145
146 static char pluto_lock[sizeof(ctl_addr.sun_path)] = DEFAULT_CTLBASE LOCK_SUFFIX;
147 static bool pluto_lock_created = FALSE;
148
149 /* create lockfile, or die in the attempt */
150 static int
151 create_lock(void)
152 {
153     int fd = open(pluto_lock, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
154         S_IRUSR | S_IRGRP | S_IROTH);
155
156     if (fd < 0)
157     {
158         if (errno == EEXIST)
159         {
160             fprintf(stderr, "pluto: lock file \"%s\" already exists\n"
161                 , pluto_lock);
162             exit_pluto(10);
163         }
164         else
165         {
166             fprintf(stderr
167                 , "pluto: unable to create lock file \"%s\" (%d %s)\n"
168                 , pluto_lock, errno, strerror(errno));
169             exit_pluto(1);
170         }
171     }
172     pluto_lock_created = TRUE;
173     return fd;
174 }
175
176 static bool
177 fill_lock(int lockfd, pid_t pid)
178 {
179     char buf[30];       /* holds "<pid>\n" */
180     int len = snprintf(buf, sizeof(buf), "%u\n", (unsigned int) pid);
181     bool ok = len > 0 && write(lockfd, buf, len) == len;
182
183     close(lockfd);
184     return ok;
185 }
186
187 static void
188 delete_lock(void)
189 {
190     if (pluto_lock_created)
191     {
192         delete_ctl_socket();
193         unlink(pluto_lock);     /* is noting failure useful? */
194     }
195 }
196
197 /* by default pluto sends certificate requests to its peers */
198 bool no_cr_send = FALSE;
199
200 int
201 main(int argc, char **argv)
202 {
203     bool fork_desired = TRUE;
204     bool log_to_stderr_desired = FALSE;
205     int lockfd;
206 #ifdef NAT_TRAVERSAL
207     bool nat_traversal = FALSE;
208     bool nat_t_spf = TRUE;  /* support port floating */
209     unsigned int keep_alive = 0;
210     bool force_keepalive = FALSE;
211 #endif
212 #ifdef VIRTUAL_IP
213     char *virtual_private = NULL;
214 #endif
215
216     char *ipsec0 = NULL;
217     char *ipsec1 = NULL;
218     char *ipsec2 = NULL;
219     char *ipsec3 = NULL;
220     
221     /* handle arguments */
222     for (;;)
223     {
224         static const struct option long_opts[] = {
225             /* name, has_arg, flag, val */
226             { "help", no_argument, NULL, 'h' },
227             { "version", no_argument, NULL, 'v' },
228             { "optionsfrom", required_argument, NULL, '+' },
229             { "nofork", no_argument, NULL, 'd' },
230             { "stderrlog", no_argument, NULL, 'e' },
231             { "noklips", no_argument, NULL, 'n' },
232             { "nocrsend", no_argument, NULL, 'c' },
233             { "uniqueids", no_argument, NULL, 'u' },
234             { "interface", required_argument, NULL, 'i' },
235             { "ikeport", required_argument, NULL, 'p' },
236             { "ctlbase", required_argument, NULL, 'b' },
237             { "secretsfile", required_argument, NULL, 's' },
238             { "adns", required_argument, NULL, 'a' },
239 #ifdef DEBUG
240             { "debug-none", no_argument, NULL, 'N' },
241             { "debug-all]", no_argument, NULL, 'A' },
242             { "debug-raw", no_argument, NULL, 'R' },
243             { "debug-crypt", no_argument, NULL, 'X' },
244             { "debug-parsing", no_argument, NULL, 'P' },
245             { "debug-emitting", no_argument, NULL, 'E' },
246             { "debug-control", no_argument, NULL, 'C' },
247             { "debug-lifecycle", no_argument, NULL, 'L' },
248             { "debug-klips", no_argument, NULL, 'K' },
249             { "debug-dns", no_argument, NULL, 'D' },
250             { "debug-private", no_argument, NULL, 'Z' },
251 #endif
252 #ifdef NAT_TRAVERSAL
253             { "nat_traversal", no_argument, NULL, '1' },
254             { "keep_alive", required_argument, NULL, '2' },
255             { "force_keepalive", no_argument, NULL, '3' },
256             { "disable_port_floating", no_argument, NULL, '4' },
257             { "debug-nat_t", no_argument, NULL, '5' },
258 #endif
259 #ifdef VIRTUAL_IP
260             { "virtual_private", required_argument, NULL, '6' },
261 #endif
262             { "ipsec0", required_argument, NULL, '7' },
263             { "ipsec1", required_argument, NULL, '8' },
264             { "ipsec2", required_argument, NULL, '9' },
265             { "ipsec3", required_argument, NULL, '0' },
266             { 0,0,0,0 }
267             };
268         /* Note: we don't like the way short options get parsed
269          * by getopt_long, so we simply pass an empty string as
270          * the list.  It could be "hvdenp:l:s:" "NARXPECK".
271          */
272         int c = getopt_long(argc, argv, "", long_opts, NULL);
273
274         /* Note: "breaking" from case terminates loop */
275         switch (c)
276         {
277         case EOF:       /* end of flags */
278             break;
279
280         case 0: /* long option already handled */
281             continue;
282
283         case ':':       /* diagnostic already printed by getopt_long */
284         case '?':       /* diagnostic already printed by getopt_long */
285             usage("");
286             break;   /* not actually reached */
287
288         case 'h':       /* --help */
289             usage(NULL);
290             break;      /* not actually reached */
291
292         case 'v':       /* --version */
293             {
294                 const char **sp = ipsec_copyright_notice();
295
296                 printf("%s\n", ipsec_version_string());
297                 for (; *sp != NULL; sp++)
298                     puts(*sp);
299             }
300             exit_pluto(0);
301             break;      /* not actually reached */
302
303         case '+':       /* --optionsfrom <filename> */
304             optionsfrom(optarg, &argc, &argv, optind, stderr);
305             /* does not return on error */
306             continue;
307
308         case 'd':       /* --nofork*/
309             fork_desired = FALSE;
310             continue;
311
312         case 'e':       /* --stderrlog */
313             log_to_stderr_desired = TRUE;
314             continue;
315
316         case 'n':       /* --noklips */
317             no_klips = TRUE;
318             continue;
319
320         case 'c':       /* --nocrsend */
321             no_cr_send = TRUE;
322             continue
323             ;
324         case 'u':       /* --uniquids */
325             uniqueIDs = TRUE;
326             continue;
327
328         case 'i':       /* --interface <ifname> */
329             if (!use_interface(optarg))
330                 usage("too many --interface specifications");
331             continue;
332
333         case 'p':       /* --port <portnumber> */
334             if (optarg == NULL || !isdigit(optarg[0]))
335                 usage("missing port number");
336
337             {
338                 char *endptr;
339                 long port = strtol(optarg, &endptr, 0);
340
341                 if (*endptr != '\0' || endptr == optarg
342                 || port <= 0 || port > 0x10000)
343                     usage("<port-number> must be a number between 1 and 65535");
344                 pluto_port = port;
345             }
346             continue;
347
348         case 'b':       /* --ctlbase <path> */
349             if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
350             , "%s%s", optarg, CTL_SUFFIX) == -1)
351                 usage("<path>" CTL_SUFFIX " too long for sun_path");
352             if (snprintf(pluto_lock, sizeof(pluto_lock)
353             , "%s%s", optarg, LOCK_SUFFIX) == -1)
354                 usage("<path>" LOCK_SUFFIX " must fit");
355             continue;
356
357         case 's':       /* --secretsfile <secrets-file> */
358             shared_secrets_file = optarg;
359             continue;
360
361         case 'a':       /* --adns <pathname> */
362             pluto_adns_option = optarg;
363             continue;
364
365 #ifdef DEBUG
366         case 'N':       /* --debug-none */
367             base_debugging = DBG_NONE;
368             continue;
369
370         case 'A':       /* --debug-all */
371             base_debugging = DBG_ALL;
372             continue;
373
374         case 'R':       /* --debug-raw */
375             base_debugging |= DBG_RAW;
376             continue;
377
378         case 'X':       /* --debug-crypt */
379             base_debugging |= DBG_CRYPT;
380             continue;
381
382         case 'P':       /* --debug-parsing */
383             base_debugging |= DBG_PARSING;
384             continue;
385
386         case 'E':       /* --debug-emitting */
387             base_debugging |= DBG_EMITTING;
388             continue;
389
390         case 'C':       /* --debug-control */
391             base_debugging |= DBG_CONTROL;
392             continue;
393
394         case 'L':       /* --debug-lifecycle */
395             base_debugging |= DBG_LIFECYCLE;
396             continue;
397
398         case 'K':       /* --debug-klips */
399             base_debugging |= DBG_KLIPS;
400             continue;
401
402         case 'D':       /* --debug-dns */
403             base_debugging |= DBG_DNS;
404             continue;
405
406         case 'Z':       /* --debug-private */
407             base_debugging |= DBG_PRIVATE;
408             continue;
409 #endif
410 #ifdef NAT_TRAVERSAL
411         case '1':       /* --nat_traversal */
412             nat_traversal = TRUE;
413             continue;
414         case '2':       /* --keep_alive */
415             keep_alive = atoi(optarg);
416             continue;
417         case '3':       /* --force_keepalive */
418             force_keepalive = TRUE;
419             continue;
420         case '4':       /* --disable_port_floating */
421             nat_t_spf = FALSE;
422             continue;
423         case '5':       /* --debug-nat_t */
424             base_debugging |= DBG_NATT;
425             continue;
426 #endif
427 #ifdef VIRTUAL_IP
428         case '6':       /* --virtual_private */
429             virtual_private = optarg;
430             continue;
431 #endif
432         case '7':       /* --ipsec0 */
433             ipsec0 = optarg;
434             continue;
435         case '8':       /* --ipsec1 */
436             ipsec1 = optarg;
437             continue;
438         case '9':       /* --ipsec2 */
439             ipsec2 = optarg;
440             continue;
441         case '0':       /* --ipsec3 */
442             ipsec3 = optarg;
443             continue;
444
445         default:
446             impossible();
447         }
448         break;
449     }
450     if (optind != argc)
451         usage("unexpected argument");
452     reset_debugging();
453     lockfd = create_lock();
454
455     /* select between logging methods */
456
457     if (log_to_stderr_desired)
458         log_to_syslog = FALSE;
459     else
460         log_to_stderr = FALSE;
461
462     /* create control socket.
463      * We must create it before the parent process returns so that
464      * there will be no race condition in using it.  The easiest
465      * place to do this is before the daemon fork.
466      */
467     {
468         err_t ugh = init_ctl_socket();
469
470         if (ugh != NULL)
471         {
472             fprintf(stderr, "pluto: %s", ugh);
473             exit_pluto(1);
474         }
475     }
476
477     /* If not suppressed, do daemon fork */
478
479 #ifndef __uClinux__
480     if (fork_desired)
481     {
482         {
483             pid_t pid = fork();
484
485             if (pid < 0)
486             {
487                 int e = errno;
488
489                 fprintf(stderr, "pluto: fork failed (%d %s)\n",
490                     errno, strerror(e));
491                 exit_pluto(1);
492             }
493
494             if (pid != 0)
495             {
496                 /* parent: die, after filling PID into lock file.
497                  * must not use exit_pluto: lock would be removed!
498                  */
499                 exit(fill_lock(lockfd, pid)? 0 : 1);
500             }
501         }
502
503         if (setsid() < 0)
504         {
505             int e = errno;
506
507             fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
508                 errno, strerror(e));
509             exit_pluto(1);
510         }
511
512         /* Close everything but ctl_fd and (if needed) stderr. */
513         {
514             int i;
515
516             for (i = getdtablesize() - 1; i >= 0; i--)  /* Bad hack */
517                 if ((!log_to_stderr || i != 2)
518                 && i != ctl_fd)
519                     close(i);
520
521             /* make sure that stdin, stdout, stderr are reserved */
522             if (open("/dev/null", O_RDONLY) != 0)
523                 abort();
524             if (dup2(0, 1) != 1)
525                 abort();
526             if (!log_to_stderr && dup2(0, 2) != 2)
527                 abort();
528         }
529     }
530     else
531 #endif
532     {
533 #ifdef __uClinux__
534         if (fork_desired)
535         {
536             setpgrp();
537         }
538 #endif
539         /* no daemon fork: we have to fill in lock file */
540         (void) fill_lock(lockfd, getpid());
541         fprintf(stdout, "Pluto initialized\n");
542         fflush(stdout);
543     }
544
545     init_constants();
546     init_log();
547     /* Note: some scripts may look for this exact message -- don't change */
548     log("Starting Pluto (FreeS/WAN Version %s)", ipsec_version_code());
549     log("  including X.509 patch (Version %s)", x509patch_version);
550
551 #ifdef NAT_TRAVERSAL
552     init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
553 #endif
554
555 #ifdef VIRTUAL_IP
556     init_virtual_ip(virtual_private);
557 #endif
558     init_interfaces(ipsec0, ipsec1, ipsec2, ipsec3);
559     init_rnd_pool();
560     init_secret();
561     init_states();
562     init_crypto();
563     init_demux();
564     init_kernel();
565     init_adns();
566
567     /* loading CA certificates */
568     load_cacerts();
569     /* loading CRLs */
570     load_crls();
571     /* loading my X.509 or OpenPGP certificate */
572     load_mycert();
573
574     call_server();
575     return -1;        /* Shouldn't ever reach this */
576 }
577
578 /* leave pluto, with status.
579  * Once child is launched, parent must not exit this way because
580  * the lock would be released.
581  *
582  *  0 OK
583  *  1 general discomfort
584  * 10 lock file exists
585  */
586 void
587 exit_pluto(int status)
588 {
589     reset_globals();    /* needed because we may be called in odd state */
590     free_preshared_secrets();
591     free_remembered_public_keys();
592     delete_every_connection();
593     free_cacerts();     /* free chain of CA certificates */
594     free_crls();        /* free chain of CRLS */
595     free_mycert();      /* free default certificate (deprecated for X.509) */
596     free_ifaces();
597     stop_adns();
598     free_md_pool();
599     delete_lock();
600 #ifdef LEAK_DETECTIVE
601     report_leaks();
602 #endif /* LEAK_DETECTIVE */
603     close_log();
604     exit(status);
605 }