summaryrefslogtreecommitdiff
path: root/src/pluto/plutomain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pluto/plutomain.c')
-rw-r--r--src/pluto/plutomain.c1125
1 files changed, 588 insertions, 537 deletions
diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c
index a39934f1f..39367cafa 100644
--- a/src/pluto/plutomain.c
+++ b/src/pluto/plutomain.c
@@ -1,6 +1,7 @@
/* Pluto main program
* Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
+ * Copyright (C) 1998-2001 D. Hugh Redelmeier.
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -11,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: plutomain.c 4313 2008-08-29 09:24:14Z martin $
*/
#include <stdio.h>
@@ -27,7 +26,7 @@
#include <fcntl.h>
#include <getopt.h>
#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
+#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
#include <sys/queue.h>
#include <sys/prctl.h>
#include <pwd.h>
@@ -39,6 +38,16 @@
#include <freeswan.h>
+#include <library.h>
+#include <debug.h>
+#include <utils/enumerator.h>
+#include <utils/optionsfrom.h>
+
+#ifdef INTEGRITY_TEST
+#include <fips/fips.h>
+#include <fips/fips_signature.h>
+#endif /* INTEGRITY_TEST */
+
#include <pfkeyv2.h>
#include <pfkey.h>
@@ -51,91 +60,88 @@
#include "connections.h"
#include "foodgroups.h"
#include "packet.h"
-#include "demux.h" /* needs packet.h */
+#include "demux.h" /* needs packet.h */
#include "server.h"
#include "kernel.h"
#include "log.h"
#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
-#include "rnd.h"
+#include "adns.h" /* needs <resolv.h> */
+#include "dnskey.h" /* needs keys.h and adns.h */
#include "state.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
+#include "ipsec_doi.h" /* needs demux.h and state.h */
#include "ocsp.h"
#include "crl.h"
#include "fetch.h"
#include "xauth.h"
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "crypto.h"
#include "nat_traversal.h"
#include "virtual.h"
+#include "timer.h"
+#include "vendor.h"
-static void
-usage(const char *mess)
+static void usage(const char *mess)
{
- if (mess != NULL && *mess != '\0')
- fprintf(stderr, "%s\n", mess);
- fprintf(stderr
- , "Usage: pluto"
- " [--help]"
- " [--version]"
- " [--optionsfrom <filename>]"
- " \\\n\t"
- "[--nofork]"
- " [--stderrlog]"
- " [--noklips]"
- " [--nocrsend]"
- " \\\n\t"
- "[--strictcrlpolicy]"
- " [--crlcheckinterval <interval>]"
- " [--cachecrls]"
- " [--uniqueids]"
- " \\\n\t"
- "[--interface <ifname>]"
- " [--ikeport <port-number>]"
- " \\\n\t"
- "[--ctlbase <path>]"
- " \\\n\t"
- "[--perpeerlogbase <path>] [--perpeerlog]"
- " \\\n\t"
- "[--secretsfile <secrets-file>]"
- " [--policygroupsdir <policygroups-dir>]"
- " \\\n\t"
- "[--adns <pathname>]"
- "[--pkcs11module <path>]"
- "[--pkcs11keepstate]"
- "[--pkcs11initargs <string>]"
+ if (mess != NULL && *mess != '\0')
+ fprintf(stderr, "%s\n", mess);
+ fprintf(stderr
+ , "Usage: pluto"
+ " [--help]"
+ " [--version]"
+ " [--optionsfrom <filename>]"
+ " \\\n\t"
+ "[--nofork]"
+ " [--stderrlog]"
+ " [--noklips]"
+ " [--nocrsend]"
+ " \\\n\t"
+ "[--strictcrlpolicy]"
+ " [--crlcheckinterval <interval>]"
+ " [--cachecrls]"
+ " [--uniqueids]"
+ " \\\n\t"
+ "[--interface <ifname>]"
+ " [--ikeport <port-number>]"
+ " \\\n\t"
+ "[--ctlbase <path>]"
+ " \\\n\t"
+ "[--perpeerlogbase <path>] [--perpeerlog]"
+ " \\\n\t"
+ "[--secretsfile <secrets-file>]"
+ " [--policygroupsdir <policygroups-dir>]"
+ " \\\n\t"
+ "[--adns <pathname>]"
+ "[--pkcs11module <path>]"
+ "[--pkcs11keepstate]"
+ "[--pkcs11initargs <string>]"
#ifdef DEBUG
- " \\\n\t"
- "[--debug-none]"
- " [--debug-all]"
- " \\\n\t"
- "[--debug-raw]"
- " [--debug-crypt]"
- " [--debug-parsing]"
- " [--debug-emitting]"
- " \\\n\t"
- "[--debug-control]"
- " [--debug-lifecycle]"
- " [--debug-klips]"
- " [--debug-dns]"
- " \\\n\t"
- "[--debug-oppo]"
- " [--debug-controlmore]"
- " [--debug-private]"
+ " \\\n\t"
+ "[--debug-none]"
+ " [--debug-all]"
+ " \\\n\t"
+ "[--debug-raw]"
+ " [--debug-crypt]"
+ " [--debug-parsing]"
+ " [--debug-emitting]"
+ " \\\n\t"
+ "[--debug-control]"
+ " [--debug-lifecycle]"
+ " [--debug-klips]"
+ " [--debug-dns]"
+ " \\\n\t"
+ "[--debug-oppo]"
+ " [--debug-controlmore]"
+ " [--debug-private]"
+ " [--debug-natt]"
#endif
- " [ --debug-natt]"
- " \\\n\t"
- "[--nat_traversal] [--keep_alive <delay_sec>]"
- " \\\n\t"
- "[--force_keepalive] [--disable_port_floating]"
- " \\\n\t"
- "[--virtual_private <network_list>]"
- "\n"
- "strongSwan %s\n"
- , ipsec_version_code());
- exit_pluto(mess == NULL? 0 : 1);
+ " \\\n\t"
+ "[--nat_traversal] [--keep_alive <delay_sec>]"
+ " \\\n\t"
+ "[--force_keepalive] [--disable_port_floating]"
+ " \\\n\t"
+ "[--virtual_private <network_list>]"
+ "\n"
+ "strongSwan "VERSION"\n");
+ exit_pluto(mess == NULL? 0 : 1);
}
@@ -150,53 +156,51 @@ static char pluto_lock[sizeof(ctl_addr.sun_path)] = DEFAULT_CTLBASE LOCK_SUFFIX;
static bool pluto_lock_created = FALSE;
/* create lockfile, or die in the attempt */
-static int
-create_lock(void)
+static int create_lock(void)
{
- int fd = open(pluto_lock, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC
- , S_IRUSR | S_IRGRP | S_IROTH);
+ int fd = open(pluto_lock, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC
+ , S_IRUSR | S_IRGRP | S_IROTH);
- if (fd < 0)
- {
- if (errno == EEXIST)
+ if (fd < 0)
{
- fprintf(stderr, "pluto: lock file \"%s\" already exists\n"
- , pluto_lock);
- exit_pluto(10);
+ if (errno == EEXIST)
+ {
+ fprintf(stderr, "pluto: lock file \"%s\" already exists\n"
+ , pluto_lock);
+ exit_pluto(10);
+ }
+ else
+ {
+ fprintf(stderr
+ , "pluto: unable to create lock file \"%s\" (%d %s)\n"
+ , pluto_lock, errno, strerror(errno));
+ exit_pluto(1);
+ }
}
- else
- {
- fprintf(stderr
- , "pluto: unable to create lock file \"%s\" (%d %s)\n"
- , pluto_lock, errno, strerror(errno));
- exit_pluto(1);
- }
- }
- pluto_lock_created = TRUE;
- return fd;
+ pluto_lock_created = TRUE;
+ return fd;
}
-static bool
-fill_lock(int lockfd, pid_t pid)
+static bool fill_lock(int lockfd, pid_t pid)
{
- char buf[30]; /* holds "<pid>\n" */
- int len = snprintf(buf, sizeof(buf), "%u\n", (unsigned int) pid);
- bool ok = len > 0 && write(lockfd, buf, len) == len;
+ char buf[30]; /* holds "<pid>\n" */
+ int len = snprintf(buf, sizeof(buf), "%u\n", (unsigned int) pid);
+ bool ok = len > 0 && write(lockfd, buf, len) == len;
- close(lockfd);
- return ok;
+ close(lockfd);
+ return ok;
}
-static void
-delete_lock(void)
+static void delete_lock(void)
{
- if (pluto_lock_created)
- {
- delete_ctl_socket();
- unlink(pluto_lock); /* is noting failure useful? */
- }
+ if (pluto_lock_created)
+ {
+ delete_ctl_socket();
+ unlink(pluto_lock); /* is noting failure useful? */
+ }
}
+
/* by default pluto sends certificate requests to its peers */
bool no_cr_send = FALSE;
@@ -223,459 +227,504 @@ bool pkcs11_proxy = FALSE;
*/
static const char *pkcs11_init_args = NULL;
-int
-main(int argc, char **argv)
+/* options read by optionsfrom */
+options_t *options;
+
+/**
+ * Log loaded plugins
+ */
+static void print_plugins()
+{
+ char buf[BUF_LEN], *plugin;
+ int len = 0;
+ enumerator_t *enumerator;
+
+ buf[0] = '\0';
+ enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
+ while (len < BUF_LEN && enumerator->enumerate(enumerator, &plugin))
+ {
+ len += snprintf(&buf[len], BUF_LEN-len, "%s ", plugin);
+ }
+ enumerator->destroy(enumerator);
+ DBG1("loaded plugins: %s", buf);
+}
+
+int main(int argc, char **argv)
{
- bool fork_desired = TRUE;
- bool log_to_stderr_desired = FALSE;
- bool nat_traversal = FALSE;
- bool nat_t_spf = TRUE; /* support port floating */
- unsigned int keep_alive = 0;
- bool force_keepalive = FALSE;
- char *virtual_private = NULL;
- int lockfd;
+ bool fork_desired = TRUE;
+ bool log_to_stderr_desired = FALSE;
+ bool nat_traversal = FALSE;
+ bool nat_t_spf = TRUE; /* support port floating */
+ unsigned int keep_alive = 0;
+ bool force_keepalive = FALSE;
+ char *virtual_private = NULL;
+ int lockfd;
#ifdef CAPABILITIES
- cap_t caps;
- int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
+ cap_t caps;
+ int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
#endif /* CAPABILITIES */
- /* handle arguments */
- for (;;)
- {
-# define DBG_OFFSET 256
- static const struct option long_opts[] = {
- /* name, has_arg, flag, val */
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'v' },
- { "optionsfrom", required_argument, NULL, '+' },
- { "nofork", no_argument, NULL, 'd' },
- { "stderrlog", no_argument, NULL, 'e' },
- { "noklips", no_argument, NULL, 'n' },
- { "nocrsend", no_argument, NULL, 'c' },
- { "strictcrlpolicy", no_argument, NULL, 'r' },
- { "crlcheckinterval", required_argument, NULL, 'x'},
- { "cachecrls", no_argument, NULL, 'C' },
- { "uniqueids", no_argument, NULL, 'u' },
- { "interface", required_argument, NULL, 'i' },
- { "ikeport", required_argument, NULL, 'p' },
- { "ctlbase", required_argument, NULL, 'b' },
- { "secretsfile", required_argument, NULL, 's' },
- { "foodgroupsdir", required_argument, NULL, 'f' },
- { "perpeerlogbase", required_argument, NULL, 'P' },
- { "perpeerlog", no_argument, NULL, 'l' },
- { "policygroupsdir", required_argument, NULL, 'f' },
+ /* initialize library and optionsfrom */
+ library_init(STRONGSWAN_CONF);
+ options = options_create();
+
+ /* handle arguments */
+ for (;;)
+ {
+# define DBG_OFFSET 256
+ static const struct option long_opts[] = {
+ /* name, has_arg, flag, val */
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { "optionsfrom", required_argument, NULL, '+' },
+ { "nofork", no_argument, NULL, 'd' },
+ { "stderrlog", no_argument, NULL, 'e' },
+ { "noklips", no_argument, NULL, 'n' },
+ { "nocrsend", no_argument, NULL, 'c' },
+ { "strictcrlpolicy", no_argument, NULL, 'r' },
+ { "crlcheckinterval", required_argument, NULL, 'x'},
+ { "cachecrls", no_argument, NULL, 'C' },
+ { "uniqueids", no_argument, NULL, 'u' },
+ { "interface", required_argument, NULL, 'i' },
+ { "ikeport", required_argument, NULL, 'p' },
+ { "ctlbase", required_argument, NULL, 'b' },
+ { "secretsfile", required_argument, NULL, 's' },
+ { "foodgroupsdir", required_argument, NULL, 'f' },
+ { "perpeerlogbase", required_argument, NULL, 'P' },
+ { "perpeerlog", no_argument, NULL, 'l' },
+ { "policygroupsdir", required_argument, NULL, 'f' },
#ifdef USE_LWRES
- { "lwdnsq", required_argument, NULL, 'a' },
+ { "lwdnsq", required_argument, NULL, 'a' },
#else /* !USE_LWRES */
- { "adns", required_argument, NULL, 'a' },
+ { "adns", required_argument, NULL, 'a' },
#endif /* !USE_LWRES */
- { "pkcs11module", required_argument, NULL, 'm' },
- { "pkcs11keepstate", no_argument, NULL, 'k' },
- { "pkcs11initargs", required_argument, NULL, 'z' },
- { "pkcs11proxy", no_argument, NULL, 'y' },
- { "nat_traversal", no_argument, NULL, '1' },
- { "keep_alive", required_argument, NULL, '2' },
- { "force_keepalive", no_argument, NULL, '3' },
- { "disable_port_floating", no_argument, NULL, '4' },
- { "debug-natt", no_argument, NULL, '5' },
- { "virtual_private", required_argument, NULL, '6' },
+ { "pkcs11module", required_argument, NULL, 'm' },
+ { "pkcs11keepstate", no_argument, NULL, 'k' },
+ { "pkcs11initargs", required_argument, NULL, 'z' },
+ { "pkcs11proxy", no_argument, NULL, 'y' },
+ { "nat_traversal", no_argument, NULL, '1' },
+ { "keep_alive", required_argument, NULL, '2' },
+ { "force_keepalive", no_argument, NULL, '3' },
+ { "disable_port_floating", no_argument, NULL, '4' },
+ { "debug-natt", no_argument, NULL, '5' },
+ { "virtual_private", required_argument, NULL, '6' },
#ifdef DEBUG
- { "debug-none", no_argument, NULL, 'N' },
- { "debug-all", no_argument, NULL, 'A' },
- { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
- { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
- { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
- { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
- { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
- { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
- { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
- { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
- { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
- { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
- { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
-
- { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
- { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
- { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
- { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
+ { "debug-none", no_argument, NULL, 'N' },
+ { "debug-all", no_argument, NULL, 'A' },
+ { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
+ { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
+ { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
+ { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
+ { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
+ { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
+ { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
+ { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
+ { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
+ { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
+ { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
+
+ { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
+ { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
+ { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
+ { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
#endif
- { 0,0,0,0 }
- };
- /* Note: we don't like the way short options get parsed
- * by getopt_long, so we simply pass an empty string as
- * the list. It could be "hvdenp:l:s:" "NARXPECK".
- */
- int c = getopt_long(argc, argv, "", long_opts, NULL);
-
- /* Note: "breaking" from case terminates loop */
- switch (c)
- {
- case EOF: /* end of flags */
- break;
-
- case 0: /* long option already handled */
- continue;
-
- case ':': /* diagnostic already printed by getopt_long */
- case '?': /* diagnostic already printed by getopt_long */
- usage("");
- break; /* not actually reached */
-
- case 'h': /* --help */
- usage(NULL);
- break; /* not actually reached */
-
- case 'v': /* --version */
- {
- const char **sp = ipsec_copyright_notice();
-
- printf("%s%s\n", ipsec_version_string(),
- compile_time_interop_options);
- for (; *sp != NULL; sp++)
- puts(*sp);
- }
- exit_pluto(0);
- break; /* not actually reached */
-
- case '+': /* --optionsfrom <filename> */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* does not return on error */
- continue;
-
- case 'd': /* --nofork*/
- fork_desired = FALSE;
- continue;
-
- case 'e': /* --stderrlog */
- log_to_stderr_desired = TRUE;
- continue;
-
- case 'n': /* --noklips */
- no_klips = TRUE;
- continue;
-
- case 'c': /* --nocrsend */
- no_cr_send = TRUE;
- continue;
-
- case 'r': /* --strictcrlpolicy */
- strict_crl_policy = TRUE;
- continue;
-
- case 'x': /* --crlcheckinterval <time>*/
- if (optarg == NULL || !isdigit(optarg[0]))
- usage("missing interval time");
-
- {
- char *endptr;
- long interval = strtol(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg
- || interval <= 0)
- usage("<interval-time> must be a positive number");
- crl_check_interval = interval;
- }
- continue;
-
- case 'C': /* --cachecrls */
- cache_crls = TRUE;
- continue;
-
- case 'u': /* --uniqueids */
- uniqueIDs = TRUE;
- continue;
-
- case 'i': /* --interface <ifname> */
- if (!use_interface(optarg))
- usage("too many --interface specifications");
- continue;
-
- case 'p': /* --port <portnumber> */
- if (optarg == NULL || !isdigit(optarg[0]))
- usage("missing port number");
-
- {
- char *endptr;
- long port = strtol(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg
- || port <= 0 || port > 0x10000)
- usage("<port-number> must be a number between 1 and 65535");
- pluto_port = port;
- }
- continue;
-
- case 'b': /* --ctlbase <path> */
- if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
- , "%s%s", optarg, CTL_SUFFIX) == -1)
- usage("<path>" CTL_SUFFIX " too long for sun_path");
- if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
- , "%s%s", optarg, INFO_SUFFIX) == -1)
- usage("<path>" INFO_SUFFIX " too long for sun_path");
- if (snprintf(pluto_lock, sizeof(pluto_lock)
- , "%s%s", optarg, LOCK_SUFFIX) == -1)
- usage("<path>" LOCK_SUFFIX " must fit");
- continue;
-
- case 's': /* --secretsfile <secrets-file> */
- shared_secrets_file = optarg;
- continue;
-
- case 'f': /* --policygroupsdir <policygroups-dir> */
- policygroups_dir = optarg;
- continue;
-
- case 'a': /* --adns <pathname> */
- pluto_adns_option = optarg;
- continue;
-
- case 'm': /* --pkcs11module <pathname> */
- pkcs11_module_path = optarg;
- continue;
-
- case 'k': /* --pkcs11keepstate */
- pkcs11_keep_state = TRUE;
- continue;
-
- case 'y': /* --pkcs11proxy */
- pkcs11_proxy = TRUE;
- continue;
-
- case 'z': /* --pkcs11initargs */
- pkcs11_init_args = optarg;
- continue;
+ { 0,0,0,0 }
+ };
+ /* Note: we don't like the way short options get parsed
+ * by getopt_long, so we simply pass an empty string as
+ * the list. It could be "hvdenp:l:s:" "NARXPECK".
+ */
+ int c = getopt_long(argc, argv, "", long_opts, NULL);
+
+ /* Note: "breaking" from case terminates loop */
+ switch (c)
+ {
+ case EOF: /* end of flags */
+ break;
+
+ case 0: /* long option already handled */
+ continue;
+
+ case ':': /* diagnostic already printed by getopt_long */
+ case '?': /* diagnostic already printed by getopt_long */
+ usage("");
+ break; /* not actually reached */
+
+ case 'h': /* --help */
+ usage(NULL);
+ break; /* not actually reached */
+
+ case 'v': /* --version */
+ {
+ const char **sp = ipsec_copyright_notice();
+
+ printf("strongSwan "VERSION"%s\n", compile_time_interop_options);
+ for (; *sp != NULL; sp++)
+ puts(*sp);
+ }
+ exit_pluto(0);
+ break; /* not actually reached */
+
+ case '+': /* --optionsfrom <filename> */
+ if (!options->from(options, optarg, &argc, &argv, optind))
+ {
+ exit_pluto(1);
+ }
+ continue;
+
+ case 'd': /* --nofork*/
+ fork_desired = FALSE;
+ continue;
+
+ case 'e': /* --stderrlog */
+ log_to_stderr_desired = TRUE;
+ continue;
+
+ case 'n': /* --noklips */
+ no_klips = TRUE;
+ continue;
+
+ case 'c': /* --nocrsend */
+ no_cr_send = TRUE;
+ continue;
+
+ case 'r': /* --strictcrlpolicy */
+ strict_crl_policy = TRUE;
+ continue;
+
+ case 'x': /* --crlcheckinterval <time>*/
+ if (optarg == NULL || !isdigit(optarg[0]))
+ usage("missing interval time");
+
+ {
+ char *endptr;
+ long interval = strtol(optarg, &endptr, 0);
+
+ if (*endptr != '\0' || endptr == optarg
+ || interval <= 0)
+ usage("<interval-time> must be a positive number");
+ crl_check_interval = interval;
+ }
+ continue;
+
+ case 'C': /* --cachecrls */
+ cache_crls = TRUE;
+ continue;
+
+ case 'u': /* --uniqueids */
+ uniqueIDs = TRUE;
+ continue;
+
+ case 'i': /* --interface <ifname> */
+ if (!use_interface(optarg))
+ usage("too many --interface specifications");
+ continue;
+
+ case 'p': /* --port <portnumber> */
+ if (optarg == NULL || !isdigit(optarg[0]))
+ usage("missing port number");
+
+ {
+ char *endptr;
+ long port = strtol(optarg, &endptr, 0);
+
+ if (*endptr != '\0' || endptr == optarg
+ || port <= 0 || port > 0x10000)
+ usage("<port-number> must be a number between 1 and 65535");
+ pluto_port = port;
+ }
+ continue;
+
+ case 'b': /* --ctlbase <path> */
+ if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
+ , "%s%s", optarg, CTL_SUFFIX) == -1)
+ usage("<path>" CTL_SUFFIX " too long for sun_path");
+ if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
+ , "%s%s", optarg, INFO_SUFFIX) == -1)
+ usage("<path>" INFO_SUFFIX " too long for sun_path");
+ if (snprintf(pluto_lock, sizeof(pluto_lock)
+ , "%s%s", optarg, LOCK_SUFFIX) == -1)
+ usage("<path>" LOCK_SUFFIX " must fit");
+ continue;
+
+ case 's': /* --secretsfile <secrets-file> */
+ shared_secrets_file = optarg;
+ continue;
+
+ case 'f': /* --policygroupsdir <policygroups-dir> */
+ policygroups_dir = optarg;
+ continue;
+
+ case 'a': /* --adns <pathname> */
+ pluto_adns_option = optarg;
+ continue;
+
+ case 'm': /* --pkcs11module <pathname> */
+ pkcs11_module_path = optarg;
+ continue;
+
+ case 'k': /* --pkcs11keepstate */
+ pkcs11_keep_state = TRUE;
+ continue;
+
+ case 'y': /* --pkcs11proxy */
+ pkcs11_proxy = TRUE;
+ continue;
+
+ case 'z': /* --pkcs11initargs */
+ pkcs11_init_args = optarg;
+ continue;
#ifdef DEBUG
- case 'N': /* --debug-none */
- base_debugging = DBG_NONE;
- continue;
+ case 'N': /* --debug-none */
+ base_debugging = DBG_NONE;
+ continue;
- case 'A': /* --debug-all */
- base_debugging = DBG_ALL;
- continue;
+ case 'A': /* --debug-all */
+ base_debugging = DBG_ALL;
+ continue;
#endif
- case 'P': /* --perpeerlogbase */
- base_perpeer_logdir = optarg;
- continue;
-
- case 'l':
- log_to_perpeer = TRUE;
- continue;
-
- case '1': /* --nat_traversal */
- nat_traversal = TRUE;
- continue;
- case '2': /* --keep_alive */
- keep_alive = atoi(optarg);
- continue;
- case '3': /* --force_keepalive */
- force_keepalive = TRUE;
- continue;
- case '4': /* --disable_port_floating */
- nat_t_spf = FALSE;
- continue;
- case '5': /* --debug-nat_t */
- base_debugging |= DBG_NATT;
- continue;
- case '6': /* --virtual_private */
- virtual_private = optarg;
- continue;
-
- default:
+ case 'P': /* --perpeerlogbase */
+ base_perpeer_logdir = optarg;
+ continue;
+
+ case 'l':
+ log_to_perpeer = TRUE;
+ continue;
+
+ case '1': /* --nat_traversal */
+ nat_traversal = TRUE;
+ continue;
+ case '2': /* --keep_alive */
+ keep_alive = atoi(optarg);
+ continue;
+ case '3': /* --force_keepalive */
+ force_keepalive = TRUE;
+ continue;
+ case '4': /* --disable_port_floating */
+ nat_t_spf = FALSE;
+ continue;
+ case '5': /* --debug-nat_t */
+ base_debugging |= DBG_NATT;
+ continue;
+ case '6': /* --virtual_private */
+ virtual_private = optarg;
+ continue;
+
+ default:
#ifdef DEBUG
- if (c >= DBG_OFFSET)
- {
- base_debugging |= c - DBG_OFFSET;
- continue;
- }
-# undef DBG_OFFSET
+ if (c >= DBG_OFFSET)
+ {
+ base_debugging |= c - DBG_OFFSET;
+ continue;
+ }
+# undef DBG_OFFSET
#endif
- bad_case(c);
+ bad_case(c);
+ }
+ break;
}
- break;
- }
- if (optind != argc)
- usage("unexpected argument");
- reset_debugging();
- lockfd = create_lock();
+ if (optind != argc)
+ usage("unexpected argument");
+ reset_debugging();
+ lockfd = create_lock();
- /* select between logging methods */
+ /* select between logging methods */
- if (log_to_stderr_desired)
- log_to_syslog = FALSE;
- else
- log_to_stderr = FALSE;
+ if (log_to_stderr_desired)
+ {
+ log_to_syslog = FALSE;
+ }
+ else
+ {
+ log_to_stderr = FALSE;
+ }
- /* set the logging function of pfkey debugging */
+ /* set the logging function of pfkey debugging */
#ifdef DEBUG
- pfkey_debug_func = DBG_log;
+ pfkey_debug_func = DBG_log;
#else
- pfkey_debug_func = NULL;
+ pfkey_debug_func = NULL;
#endif
- /* create control socket.
- * We must create it before the parent process returns so that
- * there will be no race condition in using it. The easiest
- * place to do this is before the daemon fork.
- */
- {
- err_t ugh = init_ctl_socket();
-
- if (ugh != NULL)
+ /* create control socket.
+ * We must create it before the parent process returns so that
+ * there will be no race condition in using it. The easiest
+ * place to do this is before the daemon fork.
+ */
{
- fprintf(stderr, "pluto: %s", ugh);
- exit_pluto(1);
+ err_t ugh = init_ctl_socket();
+
+ if (ugh != NULL)
+ {
+ fprintf(stderr, "pluto: %s", ugh);
+ exit_pluto(1);
+ }
}
- }
- /* If not suppressed, do daemon fork */
+ /* If not suppressed, do daemon fork */
- if (fork_desired)
- {
+ if (fork_desired)
{
- pid_t pid = fork();
+ {
+ pid_t pid = fork();
+
+ if (pid < 0)
+ {
+ int e = errno;
+
+ fprintf(stderr, "pluto: fork failed (%d %s)\n",
+ errno, strerror(e));
+ exit_pluto(1);
+ }
+
+ if (pid != 0)
+ {
+ /* parent: die, after filling PID into lock file.
+ * must not use exit_pluto: lock would be removed!
+ */
+ exit(fill_lock(lockfd, pid)? 0 : 1);
+ }
+ }
+
+ if (setsid() < 0)
+ {
+ int e = errno;
+
+ fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
+ errno, strerror(e));
+ exit_pluto(1);
+ }
+ }
+ else
+ {
+ /* no daemon fork: we have to fill in lock file */
+ (void) fill_lock(lockfd, getpid());
+ fprintf(stdout, "Pluto initialized\n");
+ fflush(stdout);
+ }
- if (pid < 0)
- {
- int e = errno;
+ /* Close everything but ctl_fd and (if needed) stderr.
+ * There is some danger that a library that we don't know
+ * about is using some fd that we don't know about.
+ * I guess we'll soon find out.
+ */
+ {
+ int i;
+
+ for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */
+ {
+ if ((!log_to_stderr || i != 2) && i != ctl_fd)
+ close(i);
+ }
+
+ /* make sure that stdin, stdout, stderr are reserved */
+ if (open("/dev/null", O_RDONLY) != 0)
+ abort();
+ if (dup2(0, 1) != 1)
+ abort();
+ if (!log_to_stderr && dup2(0, 2) != 2)
+ abort();
+ }
- fprintf(stderr, "pluto: fork failed (%d %s)\n",
- errno, strerror(e));
- exit_pluto(1);
- }
+ init_constants();
+ init_log("pluto");
- if (pid != 0)
- {
- /* parent: die, after filling PID into lock file.
- * must not use exit_pluto: lock would be removed!
- */
- exit(fill_lock(lockfd, pid)? 0 : 1);
- }
- }
+ /* Note: some scripts may look for this exact message -- don't change
+ * ipsec barf was one, but it no longer does.
+ */
+ plog("Starting IKEv1 pluto daemon (strongSwan "VERSION")%s",
+ compile_time_interop_options);
- if (setsid() < 0)
- {
- int e = errno;
+ /* load plugins, further infrastructure may need it */
+ lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
+ lib->settings->get_str(lib->settings, "pluto.load", PLUGINS));
+ print_plugins();
- fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
- errno, strerror(e));
- exit_pluto(1);
+#ifdef INTEGRITY_TEST
+ DBG1("integrity test of libstrongswan code");
+ if (fips_verify_hmac_signature(hmac_key, hmac_signature))
+ {
+ DBG1(" integrity test passed");
}
- }
- else
- {
- /* no daemon fork: we have to fill in lock file */
- (void) fill_lock(lockfd, getpid());
- fprintf(stdout, "Pluto initialized\n");
- fflush(stdout);
- }
-
- /* Close everything but ctl_fd and (if needed) stderr.
- * There is some danger that a library that we don't know
- * about is using some fd that we don't know about.
- * I guess we'll soon find out.
- */
- {
- int i;
-
- for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */
+ else
{
- if ((!log_to_stderr || i != 2) && i != ctl_fd)
- close(i);
+ DBG1(" integrity test failed");
+ abort();
}
-
- /* make sure that stdin, stdout, stderr are reserved */
- if (open("/dev/null", O_RDONLY) != 0)
- abort();
- if (dup2(0, 1) != 1)
- abort();
- if (!log_to_stderr && dup2(0, 2) != 2)
- abort();
- }
-
- init_constants();
- init_log("pluto");
-
- /* Note: some scripts may look for this exact message -- don't change
- * ipsec barf was one, but it no longer does.
- */
- plog("Starting Pluto (strongSwan Version %s%s)"
- , ipsec_version_code()
- , compile_time_interop_options);
-
- init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
- init_virtual_ip(virtual_private);
- scx_init(pkcs11_module_path, pkcs11_init_args); /* load and initialize PKCS #11 module */
- xauth_init(); /* load and initialize XAUTH module */
- init_rnd_pool();
- init_secret();
- init_states();
- init_crypto();
- init_demux();
- init_kernel();
- init_adns();
- init_id();
- init_fetch();
-
- /* drop unneeded capabilities and change UID/GID */
-
- prctl(PR_SET_KEEPCAPS, 1);
-
+#endif /* INTEGRITY_TEST */
+
+ init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
+ init_virtual_ip(virtual_private);
+ scx_init(pkcs11_module_path, pkcs11_init_args);
+ xauth_init();
+ init_secret();
+ init_states();
+ init_crypto();
+ init_demux();
+ init_kernel();
+ init_adns();
+ init_id();
+ init_fetch();
+
+ /* drop unneeded capabilities and change UID/GID */
+ prctl(PR_SET_KEEPCAPS, 1);
+
#ifdef IPSEC_GROUP
- {
- struct group group, *grp;
- char buf[1024];
-
- if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
- grp == NULL || setgid(grp->gr_gid) != 0)
{
- plog("unable to change daemon group");
- abort();
+ struct group group, *grp;
+ char buf[1024];
+
+ if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
+ grp == NULL || setgid(grp->gr_gid) != 0)
+ {
+ plog("unable to change daemon group");
+ abort();
+ }
}
- }
#endif
#ifdef IPSEC_USER
- {
- struct passwd passwd, *pwp;
- char buf[1024];
-
- if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
- pwp == NULL || setuid(pwp->pw_uid) != 0)
{
- plog("unable to change daemon user");
- abort();
- }
- }
+ struct passwd passwd, *pwp;
+ char buf[1024];
+
+ if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
+ pwp == NULL || setuid(pwp->pw_uid) != 0)
+ {
+ plog("unable to change daemon user");
+ abort();
+ }
+ }
#endif
#ifdef CAPABILITIES
- caps = cap_init();
- cap_set_flag(caps, CAP_EFFECTIVE, 2, keep, CAP_SET);
- cap_set_flag(caps, CAP_INHERITABLE, 2, keep, CAP_SET);
- cap_set_flag(caps, CAP_PERMITTED, 2, keep, CAP_SET);
- if (cap_set_proc(caps) != 0)
- {
- plog("unable to drop daemon capabilities");
- abort();
- }
- cap_free(caps);
+ caps = cap_init();
+ cap_set_flag(caps, CAP_EFFECTIVE, 2, keep, CAP_SET);
+ cap_set_flag(caps, CAP_INHERITABLE, 2, keep, CAP_SET);
+ cap_set_flag(caps, CAP_PERMITTED, 2, keep, CAP_SET);
+ if (cap_set_proc(caps) != 0)
+ {
+ plog("unable to drop daemon capabilities");
+ abort();
+ }
+ cap_free(caps);
#endif /* CAPABILITIES */
- /* loading X.509 CA certificates */
- load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
- /* loading X.509 AA certificates */
- load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
- /* loading X.509 OCSP certificates */
- load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);
- /* loading X.509 CRLs */
- load_crls();
- /* loading attribute certificates (experimental) */
- load_acerts();
-
- daily_log_event();
- call_server();
- return -1; /* Shouldn't ever reach this */
+ /* loading X.509 CA certificates */
+ load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
+ /* loading X.509 AA certificates */
+ load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
+ /* loading X.509 OCSP certificates */
+ load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);
+ /* loading X.509 CRLs */
+ load_crls();
+ /* loading attribute certificates (experimental) */
+ load_acerts();
+
+ daily_log_event();
+ call_server();
+ return -1; /* Shouldn't ever reach this */
}
/* leave pluto, with status.
@@ -686,31 +735,33 @@ main(int argc, char **argv)
* 1 general discomfort
* 10 lock file exists
*/
-void
-exit_pluto(int status)
+void exit_pluto(int status)
{
- reset_globals(); /* needed because we may be called in odd state */
- free_preshared_secrets();
- free_remembered_public_keys();
- delete_every_connection();
- free_crl_fetch(); /* free chain of crl fetch requests */
- free_ocsp_fetch(); /* free chain of ocsp fetch requests */
- free_authcerts(); /* free chain of X.509 authority certificates */
- free_crls(); /* free chain of X.509 CRLs */
- free_acerts(); /* free chain of X.509 attribute certificates */
- free_ca_infos(); /* free chain of X.509 CA information records */
- free_ocsp(); /* free ocsp cache */
- free_ifaces();
- scx_finalize(); /* finalize and unload PKCS #11 module */
- xauth_finalize(); /* finalize and unload XAUTH module */
- stop_adns();
- free_md_pool();
- delete_lock();
-#ifdef LEAK_DETECTIVE
- report_leaks();
-#endif /* LEAK_DETECTIVE */
- close_log();
- exit(status);
+ reset_globals(); /* needed because we may be called in odd state */
+ free_preshared_secrets();
+ free_remembered_public_keys();
+ delete_every_connection();
+ free_crl_fetch(); /* free chain of crl fetch requests */
+ free_ocsp_fetch(); /* free chain of ocsp fetch requests */
+ free_authcerts(); /* free chain of X.509 authority certificates */
+ free_crls(); /* free chain of X.509 CRLs */
+ free_acerts(); /* free chain of X.509 attribute certificates */
+ free_ca_infos(); /* free chain of X.509 CA information records */
+ free_ocsp(); /* free ocsp cache */
+ free_ifaces();
+ scx_finalize(); /* finalize and unload PKCS #11 module */
+ xauth_finalize(); /* finalize and unload XAUTH module */
+ stop_adns();
+ free_md_pool();
+ free_crypto();
+ free_id(); /* free myids */
+ free_events(); /* free remaining events */
+ free_vendorid(); /* free all vendor id records */
+ delete_lock();
+ options->destroy(options);
+ library_deinit();
+ close_log();
+ exit(status);
}
/*