support of PKCS#11 init arguments required by NSS softoken, patch contributed by...
[strongswan.git] / src / pluto / plutomain.c
index f9badba..a5bf827 100644 (file)
@@ -29,6 +29,8 @@
 #include <resolv.h>
 #include <arpa/nameser.h>      /* missing from <resolv.h> on old systems */
 #include <sys/queue.h>
+#include <linux/capability.h>
+#include <sys/prctl.h>
 
 #include <freeswan.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 */
-
-#ifdef VIRTUAL_IP
+#include "nat_traversal.h"
 #include "virtual.h"
-#endif
 
-#ifdef NAT_TRAVERSAL
-#include "nat_traversal.h"
-#endif
+/* on some distros, a capset() definition is missing */
+#ifdef NO_CAPSET_DEFINED
+extern int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
+#endif /* NO_CAPSET_DEFINED */
 
 static void
 usage(const char *mess)
@@ -87,7 +88,7 @@ usage(const char *mess)
            " [--nocrsend]"
            " \\\n\t"
            "[--strictcrlpolicy]"
-           " [--crlcheckinterval]"
+           " [--crlcheckinterval <interval>]"
            " [--cachecrls]"
            " [--uniqueids]"
            " \\\n\t"
@@ -103,7 +104,8 @@ usage(const char *mess)
            " \\\n\t"
            "[--adns <pathname>]"
            "[--pkcs11module <path>]"
-           "[--pkcs11keepstate"
+           "[--pkcs11keepstate]"
+           "[--pkcs11initargs <string>]"
 #ifdef DEBUG
            " \\\n\t"
            "[--debug-none]"
@@ -123,17 +125,13 @@ usage(const char *mess)
            " [--debug-controlmore]"
            " [--debug-private]"
 #endif
-#ifdef NAT_TRAVERSAL
            " [ --debug-natt]"
            " \\\n\t"
            "[--nat_traversal] [--keep_alive <delay_sec>]"
            " \\\n\t"
            "[--force_keepalive] [--disable_port_floating]"
-#endif
-#ifdef VIRTUAL_IP
           " \\\n\t"
           "[--virtual_private <network_list>]"
-#endif
            "\n"
        "strongSwan %s\n"
        , ipsec_version_code());
@@ -220,21 +218,24 @@ bool pkcs11_keep_state = FALSE;
 /* by default pluto does not allow pkcs11 proxy access via whack */
 bool pkcs11_proxy = FALSE;
 
+/* argument string to pass to PKCS#11 module.
+ * Not used for compliant modules, just for NSS softoken
+ */
+static const char *pkcs11_init_args = NULL;
+
 int
 main(int argc, char **argv)
 {
     bool fork_desired = TRUE;
     bool log_to_stderr_desired = FALSE;
-#ifdef NAT_TRAVERSAL
     bool nat_traversal = FALSE;
     bool nat_t_spf = TRUE;  /* support port floating */
     unsigned int keep_alive = 0;
     bool force_keepalive = FALSE;
-#endif
-#ifdef VIRTUAL_IP
     char *virtual_private = NULL;
-#endif
     int lockfd;
+    struct __user_cap_header_struct hdr;
+    struct __user_cap_data_struct data;
 
     /* handle arguments */
     for (;;)
@@ -268,21 +269,17 @@ main(int argc, char **argv)
 #endif /* !USE_LWRES */
            { "pkcs11module", required_argument, NULL, 'm' },
            { "pkcs11keepstate", no_argument, NULL, 'k' },
+           { "pkcs11initargs", required_argument, NULL, 'z' },
            { "pkcs11proxy", no_argument, NULL, 'y' },
-#ifdef NAT_TRAVERSAL
            { "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' },
-#endif
-#ifdef VIRTUAL_IP
            { "virtual_private", required_argument, NULL, '6' },
-#endif
 #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 },
@@ -442,6 +439,10 @@ main(int argc, char **argv)
            pkcs11_proxy = TRUE;
            continue;
 
+       case 'z':       /* --pkcs11initargs */
+           pkcs11_init_args = optarg;
+           continue;
+
 #ifdef DEBUG
        case 'N':       /* --debug-none */
            base_debugging = DBG_NONE;
@@ -460,7 +461,6 @@ main(int argc, char **argv)
            log_to_perpeer = TRUE;
            continue;
 
-#ifdef NAT_TRAVERSAL
        case '1':       /* --nat_traversal */
            nat_traversal = TRUE;
            continue;
@@ -476,12 +476,9 @@ main(int argc, char **argv)
        case '5':       /* --debug-nat_t */
            base_debugging |= DBG_NATT;
            continue;
-#endif
-#ifdef VIRTUAL_IP
        case '6':       /* --virtual_private */
            virtual_private = optarg;
            continue;
-#endif
 
        default:
 #ifdef DEBUG
@@ -530,19 +527,6 @@ main(int argc, char **argv)
        }
     }
 
-#ifdef IPSECPOLICY
-    /* create info socket. */
-    {
-       err_t ugh = init_info_socket();
-
-       if (ugh != NULL)
-       {
-           fprintf(stderr, "pluto: %s", ugh);
-           exit_pluto(1);
-       }
-    }
-#endif
-
     /* If not suppressed, do daemon fork */
 
     if (fork_desired)
@@ -594,12 +578,10 @@ main(int argc, char **argv)
        int i;
 
        for (i = getdtablesize() - 1; i >= 0; i--)  /* Bad hack */
-           if ((!log_to_stderr || i != 2)
-#ifdef IPSECPOLICY
-           && i != info_fd
-#endif
-           && i != ctl_fd)
+       {
+           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)
@@ -620,14 +602,10 @@ main(int argc, char **argv)
        , ipsec_version_code()
        , compile_time_interop_options);
 
-#ifdef NAT_TRAVERSAL
     init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
-#endif
-
-#ifdef VIRTUAL_IP
     init_virtual_ip(virtual_private);
-#endif
-    scx_init(pkcs11_module_path);   /* load and initialize PKCS #11 module */
+    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();
@@ -638,6 +616,26 @@ main(int argc, char **argv)
     init_id();
     init_fetch();
 
+    /* drop unneeded capabilities and change UID/GID */
+    hdr.version = _LINUX_CAPABILITY_VERSION;
+    hdr.pid = 0;
+    data.effective = data.permitted = 1<<CAP_NET_ADMIN | 1<<CAP_NET_BIND_SERVICE;
+    data.inheritable = 0;
+
+    prctl(PR_SET_KEEPCAPS, 1);
+
+#   if IPSEC_GID
+       setgid(IPSEC_GID);
+#   endif
+#   if IPSEC_UID
+       setuid(IPSEC_UID);
+#   endif
+    if (capset(&hdr, &data))
+    {
+       plog("unable to drop root privileges");
+       abort();
+    }
+
     /* loading X.509 CA certificates */
     load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
     /* loading X.509 AA certificates */
@@ -678,6 +676,7 @@ exit_pluto(int status)
     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();