]> git.ipfire.org Git - people/ms/strongswan.git/commitdiff
- applied patch from andreas
authorMartin Willi <martin@strongswan.org>
Thu, 4 May 2006 07:55:42 +0000 (07:55 -0000)
committerMartin Willi <martin@strongswan.org>
Thu, 4 May 2006 07:55:42 +0000 (07:55 -0000)
- pem loading
- secrets file parsing
- ikev2 testcase
- some other additions here and there

41 files changed:
CHANGES
INSTALL
README.pluto
src/charon/charon/config/credentials/local_credential_store.c
src/charon/charon/config/credentials/local_credential_store.h
src/charon/charon/daemon.c
src/charon/charon/daemon.h
src/charon/charon/threads/stroke_interface.c
src/charon/lib/asn1/asn1.c
src/charon/lib/asn1/pem.c
src/charon/lib/asn1/pem.h
src/charon/lib/asn1/ttodata.h
src/charon/lib/crypto/rsa/rsa_private_key.c
src/charon/lib/crypto/x509.c
src/charon/lib/types.h
src/charon/lib/utils/Makefile.utils
src/charon/lib/utils/lexparser.c [new file with mode: 0644]
src/charon/lib/utils/lexparser.h [new file with mode: 0644]
src/charon/lib/utils/logger.c
src/charon/stroke/stroke.c
src/ipsec/distro.txt
src/ipsec/ipsec.in
src/pluto/connections.c
src/pluto/kernel.c
src/pluto/log.c
src/pluto/state.c
src/pluto/vendor.c
src/pluto/vendor.h
src/starter/confread.h
src/starter/starter.c
testing/do-tests
testing/scripts/build-umlrootfs
testing/tests/ikev2-net2net/description.txt [new file with mode: 0644]
testing/tests/ikev2-net2net/evaltest.dat [new file with mode: 0644]
testing/tests/ikev2-net2net/hosts/moon/etc/ipsec.conf [new file with mode: 0644]
testing/tests/ikev2-net2net/hosts/moon/etc/ipsec.d/certs/sunCert.pem [new file with mode: 0644]
testing/tests/ikev2-net2net/hosts/sun/etc/ipsec.conf [new file with mode: 0644]
testing/tests/ikev2-net2net/hosts/sun/etc/ipsec.d/certs/moonCert.pem [new file with mode: 0644]
testing/tests/ikev2-net2net/posttest.dat [new file with mode: 0644]
testing/tests/ikev2-net2net/pretest.dat [new file with mode: 0644]
testing/tests/ikev2-net2net/test.conf [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index e87a5da334f1fd97fc0c8c22a48324f3c4aef2fd..00aa018728fbebe6e8fd00b0fb62b46b79f4e8d9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,18 @@
+strongswan-4.0.0
+----------------
+
+- initial support of the IKEv2 protocol. Connections in
+  ipsec.conf designated by keyexchange=ikev2 are negotiated 
+  by the new IKEv2 charon keying daemon whereas those marked
+  by keyexchange=ikev1 or the default keyexchange=ike are
+  handled thy the IKEv1 pluto keying daemon. Currently only
+  a limited subset of functions are available with IKEv2
+  (Default AES encryption, authentication based on locally
+  imported X.509 certificates, unencrypted private RSA keys
+  in PKCS#1 file format, limited functionality of the ipsec
+  status command).
+
+
 strongswan-2.7.0
 ----------------
 
diff --git a/INSTALL b/INSTALL
index 0ed54193607d13d64bc651869fda8d9201e7b683..df334ffc7d9f90b7a152fe947459dbfdda3222c0 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -1,5 +1,5 @@
                  ---------------------------
-                 strongSwan - Installation
+                  strongSwan - Installation
                  ---------------------------
 
 
@@ -11,9 +11,7 @@ Contents
    2.1 libcurl
    2.2 OpenLDAP
    2.3 PKCS#11 smartcard library modules
-   3. Building strongSwan with a Linux 2.4 kernel
-   4. Updating strongSwan with a Linux 2.4 kernel
-   5. Building strongSwan with a Linux 2.6 kernel
+   3. Building and running strongSwan with a Linux 2.6 kernel
 
 
 1. Required packages
@@ -125,9 +123,9 @@ Contents
    in "Makefile.inc" 
 
       # Uncomment this line if using OpenSC <= 0.9.6
-      PKCS11_DEFAULT_LIB=\"/usr/lib/pkcs11/opensc-pkcs11.so\"
+      PKCS11_DEFAULT_LIB=\"/usr/lib/pkcs11/opensc-pkcs11.so\"
       # Uncomment tis line if using OpenSC >= 0.10.0
-      #PKCS11_DEFAULT_LIB=\"usr/lib/opensc-pkcs11.so\"
+        PKCS11_DEFAULT_LIB=\"usr/lib/opensc-pkcs11.so\"
 
    This default path to the easily-obtainable OpenSC library module can be
    simply overridden during run-time by specifying an alternative path in
@@ -141,80 +139,9 @@ Contents
        USE="smartcard usb -pam -X" emerge strongswan
 
 
-3. Building strongSwan with a Linux 2.4 kernel
-   -------------------------------------------
 
-   * Building strongSwan with a Linux 2.4 kernel requires the presence of the
-     matching kernel sources referenced via the symbolic link /usr/src/linux.
-     The use of the vanilla kernel sources from ftp.kernel.org is strongly
-     recommended.
-
-     Before building strongSwan you must have compiled the kernel sources at
-     least once:
-
-         make menuconfig; make dep; make bzImage; make modules
-
-   * Now change into the  strongswan-2.x.x  source directory.
-
-     First uncomment any desired compile options in "programs/pluto/Makefile"
-     (see section 2. Optional packages).
-
-     Then in the top source directory type
-
-         make menumod
-
-     This command applies an ESP_IN_UDP encapsulation patch which is required
-     for NAT-Traversal to the kernel sources.
-
-     In the "Networking options" menu set
-
-         <M> IP Security Protocol (strongSwan IPsec)
-
-     in order to build KLIPS as a loadable kernel module "ipsec.o".  Do not
-     forget to save the modified configuration file when leaving "menumod".
-
-     The strongSwan userland programs are now automatically built and
-     installed, whereas the  ipsec.o  kernel module and the crypto modules
-     are only built and must be installed with the command
-
-         make minstall
-
-   * If you intend to use the NAT-Traversal feature then you must compile the
-     patched kernel sources again by executing
-
-         make bzImage
-
-     and then install and boot the modified kernel.
-
-   * Next add your connections to "/etc/ipsec.conf" and start strongSwan with
-
-         ipsec setup start
-
-
-4. Updating strongSwan with a Linux 2.4 kernel
-   -------------------------------------------
-
-   * If you have already successfully installed  strongSwan and want to update
-     to a newer version then the following shortcut can be taken:
-
-     First uncomment any desired compile options in "programs/pluto/Makefile"
-     (see section 2. Optional packages).
-
-     Then in the  strongwan-2.x.x  top directory type
-
-         make programs; make install
-
-     followed by
-
-         make module; make minstall
-
-   * You can then start the updated strongSwan version with
-
-         ipsec setup restart
-
-
-5. Building strongSwan with a Linux 2.6 kernel
-   -------------------------------------------
+3. Building and running strongSwan with a Linux 2.6 kernel
+   -------------------------------------------------------
 
    * Because the Linux 2.6 kernel comes with a built-in native IPsec stack,
      you won't need to build the strongSwan kernel modules. Please make sure 
@@ -225,25 +152,30 @@ Contents
          o esp4
          o ipcomp
          o xfrm_user
+         o xfrm_tunnel
 
      Also the built-in kernel Cryptoapi modules with selected encryption and 
      hash algorithms should be available.
 
-   * First uncomment any desired compile options in "programs/pluto/Makefile"
-     (see section 2. Optional packages).
+   * First select any desired compile options in "Makefile.inc" (see section 2.
+     Optional packages). Then in the  strongwan-4.x.x  top directory type
 
-     Then in the  strongwan-2.x.x  top directory type
-
-         make programs
+         make
 
      followed by
 
          make install
 
-   * Next add your connections to "etc/ipsec.conf" and start strongSwan with
+   * Next add your connections to "/etc/ipsec.conf" and your secrets to 
+     "/etc/ipsec.secrets". Connections that are to be negotiated by the new
+     IKEv2 charon keying daemon should be designated by "keyexchange=ikev2" and 
+     those by the IKEv1 pluto keying daemon either by "keyexchange=ikev1" or
+     the default "keyexchange=ike".
+
+   * At last start strongSwan with
 
-         ipsec setup start
+         ipsec start
 
 -----------------------------------------------------------------------------
 
-This file is RCSID $Id: INSTALL,v 1.8 2006/01/22 16:22:23 as Exp $
+This file is RCSID $Id: INSTALL,v 1.9 2006/05/01 16:02:37 as Exp $
index d40d887a3519657b9a048954f95d39071604e079..e9ebfee020c75801fddb8bb1ef76051fcd764ae5 100644 (file)
@@ -2650,7 +2650,7 @@ and can be used when the following prerequisites are fulfilled:
   - Linux 2.4.x kernel, KLIPS IPsec stack, and arbitrary iptables version.
     Filtering of tunneled traffic is based on ipsecN interfaces.
 
-  - Linux 2.4.16 kernel or newer, native NETKEY IPsec stack, and
+  - Linux 2.6.16 kernel or newer, native NETKEY IPsec stack, and
     iptables-1.3.5 or newer. Filtering of tunneled traffic is based on
     IPsec policy matching rules.
 
index dc6cb6c50ece7363636477d8d16103b2bf1dea36..e4fa1aa26fc9a1203611e0a77e085183dca33e4c 100644 (file)
 
 #include <sys/stat.h>
 #include <dirent.h>
+#include <string.h>
 
 #include "local_credential_store.h"
 
+#include <utils/lexparser.h>
 #include <utils/linked_list.h>
 #include <utils/logger_manager.h>
 #include <crypto/x509.h>
 
+#define PATH_BUF       256
 
 typedef struct key_entry_t key_entry_t;
 
@@ -138,9 +141,9 @@ static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t *
 }
 
 /**
- * Implements local_credential_store_t.load_private_keys
+ * Implements local_credential_store_t.load_certificates
  */
-static void load_certificates(private_local_credential_store_t *this, char *path)
+static void load_certificates(private_local_credential_store_t *this, const char *path)
 {
        struct dirent* entry;
        struct stat stb;
@@ -154,7 +157,8 @@ static void load_certificates(private_local_credential_store_t *this, char *path
        }
        while ((entry = readdir(dir)) != NULL)
        {
-               char file[256];
+               char file[PATH_BUF];
+
                snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
                
                if (stat(file, &stb) == -1)
@@ -168,7 +172,6 @@ static void load_certificates(private_local_credential_store_t *this, char *path
                        if (cert)
                        {
                                this->certificates->insert_last(this->certificates, (void*)cert);
-                               this->logger->log(this->logger, CONTROL|LEVEL1, "loaded certificate \"%s\"", file);
                        }
                        else
                        {
@@ -218,55 +221,118 @@ static identification_t *get_id_for_private_key(private_local_credential_store_t
 /**
  * Implements local_credential_store_t.load_private_keys
  */
-static void load_private_keys(private_local_credential_store_t *this, char *path)
+static void load_private_keys(private_local_credential_store_t *this, const char *secretsfile, const char *defaultpath)
 {
-       struct dirent* entry;
-       struct stat stb;
-       DIR* dir;
-       rsa_private_key_t *key;
-       
-       dir = opendir(path);
-       if (dir == NULL) {
-               this->logger->log(this->logger, ERROR, "error opening private key directory \"%s\"", path);
-               return;
-       }
-       while ((entry = readdir(dir)) != NULL)
+       FILE *fd = fopen(secretsfile, "r");
+
+       if (fd)
        {
-               char file[256];
-               snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
-               
-               if (stat(file, &stb) == -1)
-               {
-                       continue;
-               }
-               /* try to parse all regular files */
-               if (stb.st_mode & S_IFREG)
+               int bytes;
+               int line_nr = 0;
+       chunk_t chunk, src, line;
+
+               this->logger->log(this->logger, CONTROL, "loading secrets from \"%s\"", secretsfile);
+
+               fseek(fd, 0, SEEK_END);
+               chunk.len = ftell(fd);
+               rewind(fd);
+               chunk.ptr = malloc(chunk.len);
+               bytes = fread(chunk.ptr, 1, chunk.len, fd);
+               fclose(fd);
+
+               src = chunk;
+
+               while (fetchline(&src, &line))
                {
-                       key = rsa_private_key_create_from_file(file, NULL);
-                       if (key)
+                       chunk_t ids, token;
+
+                       line_nr++;
+
+                       if (!eat_whitespace(&line))
                        {
-                               key_entry_t *entry;
-                               identification_t *id = get_id_for_private_key(this, key);
-                               if (!id)
+                               continue;
+                       }
+                       if (!extract_token(&ids, ':', &line))
+                       {
+                               this->logger->log(this->logger, ERROR, "line %d: missing ':' separator", line_nr);
+                               goto error;
+                       }
+                       if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
+                       {
+                               this->logger->log(this->logger, ERROR, "line %d: missing token", line_nr);
+                               goto error;
+                       }
+                       if (match("RSA", &token))
+                       {
+                               char path[PATH_BUF];
+                               chunk_t filename;
+
+                               err_t ugh = extract_value(&filename, &line);
+
+                               if (ugh != NULL)
+                               {
+                                       this->logger->log(this->logger, ERROR, "line %d: %s", line_nr, ugh);
+                                       goto error;
+                               }
+                               if (filename.len == 0)
+                               {
+                                       this->logger->log(this->logger, ERROR,
+                                               "line %d: empty filename", line_nr);
+                                       goto error;
+                               }
+                               if (*filename.ptr == '/')
+                               {
+                                       /* absolute path name */
+                                       snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
+                               }
+                               else
                                {
-                                       this->logger->log(this->logger, ERROR, 
-                                                                         "no certificate found for private key \"%s\", skipped", file);
-                                       key->destroy(key);
-                                       continue;
+                                       /* relative path name */
+                                       snprintf(path, sizeof(path), "%s/%.*s", defaultpath, filename.len, filename.ptr);
                                }
-                               entry = malloc_thing(key_entry_t);
-                               entry->key = key;
-                               entry->id = id;
-                               this->private_keys->insert_last(this->private_keys, (void*)entry);
-                               this->logger->log(this->logger, CONTROL|LEVEL1, "loaded private key \"%s\"", file);
+
+                               rsa_private_key_t *key = rsa_private_key_create_from_file(path, NULL);
+                               if (key)
+                               {
+                                       key_entry_t *entry;
+                                       identification_t *id = get_id_for_private_key(this, key);
+
+                                       if (!id)
+                                       {
+                                               this->logger->log(this->logger, ERROR, 
+                                                       "no certificate found for private key \"%s\", skipped", path);
+                                               key->destroy(key);
+                                               continue;
+                                       }
+                                       entry = malloc_thing(key_entry_t);
+                                       entry->key = key;
+                                       entry->id = id;
+                                       this->private_keys->insert_last(this->private_keys, (void*)entry);
+                               }
+                       }
+                       else if (match("PSK", &token))
+                       {
+
+                       }
+                       else if (match("PIN", &token))
+                       {
+
                        }
                        else
                        {
-                               this->logger->log(this->logger, ERROR, "private key \"%s\" invalid, skipped", file);
+                               this->logger->log(this->logger, ERROR,
+                                        "line %d: token must be either RSA, PSK, or PIN",
+                                         line_nr, token.len);
+                               goto error;
                        }
                }
+error:
+               free(chunk.ptr);
+       }
+       else
+       {
+               this->logger->log(this->logger, ERROR, "could not open file '%s'", secretsfile);
        }
-       closedir(dir);
 }
 
 /**
@@ -302,8 +368,8 @@ local_credential_store_t * local_credential_store_create()
        this->public.credential_store.get_shared_secret = (status_t(*)(credential_store_t*,identification_t*,chunk_t*))get_shared_secret;
        this->public.credential_store.get_rsa_private_key = (rsa_private_key_t*(*)(credential_store_t*,identification_t*))get_rsa_private_key;
        this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
-       this->public.load_certificates = (void(*)(local_credential_store_t*,char*))load_certificates;
-       this->public.load_private_keys = (void(*)(local_credential_store_t*,char*))load_private_keys;
+       this->public.load_certificates = (void(*)(local_credential_store_t*,const char*))load_certificates;
+       this->public.load_private_keys = (void(*)(local_credential_store_t*,const char*, const char*))load_private_keys;
        this->public.credential_store.destroy = (void(*)(credential_store_t*))destroy;
        
        /* private variables */
index ab9ef88d7e66003043b77954459280745f98ab55..64438b378bcdb99882ba24a03a6e588527da7526 100644 (file)
@@ -57,7 +57,7 @@ struct local_credential_store_t {
         * @param this          calling object
         * @param path          directory to load certificates from
         */
-       void (*load_certificates) (local_credential_store_t *this, char *path);
+       void (*load_certificates) (local_credential_store_t *this, const char *path);
        
        /**
         * @brief Loads RSA private keys from a folder.
@@ -66,10 +66,11 @@ struct local_credential_store_t {
         * other gets ignored. Further, a certificate for the specific private
         * key must already be loaded to get the ID from.
         * 
-        * @param this          calling object
-        * @param path          directory to load keys from
+        * @param this                  calling object
+        * @param secretsfile   file where secrets are stored
+        * @param defaultpath   default directory for private keys
         */
-       void (*load_private_keys) (local_credential_store_t *this, char *path);
+       void (*load_private_keys) (local_credential_store_t *this, const char *secretsfile, const char *defaultpath);
 };
 
 /**
index 4b0ea54e860d89090833c81fc253b4dec90b1e91..f3d9fecdb8589ef6299dda6c6f81fc6219e881ad 100644 (file)
@@ -179,7 +179,7 @@ static void initialize(private_daemon_t *this)
        
        /* load keys & certs */
        cred_store->load_certificates(cred_store, CERTIFICATE_DIR);
-       cred_store->load_private_keys(cred_store, PRIVATE_KEY_DIR);
+       cred_store->load_private_keys(cred_store, SECRETS_FILE, PRIVATE_KEY_DIR);
        
        
        /* start building threads, we are multi-threaded NOW */
index 5aee21fdbbbe2a0cf83aa52e8045514c055fc30d..5cad1339b648a1e9f626ae3af62fde54ad7f0335 100644 (file)
  */
 #define PID_FILE "/var/run/charon.pid"
 
+/**
+ * Configuration directory
+ * 
+ * @ingroup charon
+ */
+#define CONFIG_DIR "/etc"
+
 /**
  * Directory of IPsec relevant files
  * 
  * @ingroup charon
  */
-#define IPSEC_DIR "/etc/ipsec.d"
+#define IPSEC_DIR CONFIG_DIR "/ipsec.d"
 
 /**
  * Directory for private keys
  */
 #define CERTIFICATE_DIR IPSEC_DIR "/certs"
 
+/**
+ * Secrets files
+ * 
+ * @ingroup charon
+ */
+#define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
 
 typedef struct daemon_t daemon_t;
 
index eeb14cd94a1e77dd9472efc3e7793249a50e5b75..0a7ba80a62a64b979b3ef3e5f3258a2ffc406bca 100755 (executable)
@@ -241,8 +241,8 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
                        my_id = my_id->clone(my_id);
                        cert->destroy(cert);
                        this->logger->log(this->logger, CONTROL, 
-                                                         "defined a valid certificate, using its ID \"%s\"",
-                                                         my_id->get_string(my_id));
+                                                         "valid certificate with ID \"%s\"",
+                                                          my_id->get_string(my_id));
                }
        }
        if (msg->add_conn.other.cert)
@@ -257,8 +257,8 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
                        other_id = other_id->clone(other_id);
                        cert->destroy(cert);
                        this->logger->log(this->logger, CONTROL, 
-                                                         "defined a valid certificate, using its ID \"%s\"",
-                                                         other_id->get_string(other_id));
+                                                         "valid certificate with ID \"%s\"",
+                                                          other_id->get_string(other_id));
                }
        }
        
@@ -308,7 +308,7 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
        connection = charon->connections->get_connection_by_name(charon->connections, msg->initiate.name);
        if (connection == NULL)
        {
-               this->stroke_logger->log(this->stroke_logger, ERROR, "could not find a connection named \"%s\"", msg->initiate.name);
+               this->stroke_logger->log(this->stroke_logger, ERROR, "no connection named \"%s\"", msg->initiate.name);
        }
        else
        {
index c847461b6d253dc32ba1533c51e243022ada1c04..e894999fb6aa2732a5b91ea95f5d91173a10ec68 100644 (file)
@@ -21,8 +21,6 @@
 
 #include <utils/logger_manager.h>
 
-static logger_t *logger;
-
 /* Names of the months */
 static const char* months[] = {
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -87,7 +85,18 @@ static const asn1Object_t algorithmIdentifierObjects[] = {
 #define ALGORITHM_ID_PARAMETERS        2
 #define ALGORITHM_ID_ROOF              3
 
-/*
+static logger_t *logger = NULL;
+
+/**
+ * initializes the ASN.1 logger
+ */
+static void asn1_init_logger()
+{
+       if (logger == NULL)
+               logger = logger_manager->get_logger(logger_manager, ASN1);
+}
+
+/**
  * return the ASN.1 encoded algorithm identifier
  */
 chunk_t asn1_algorithmIdentifier(int oid)
@@ -109,7 +118,7 @@ chunk_t asn1_algorithmIdentifier(int oid)
        }
 }
 
-/*
+/**
  * If the oid is listed in the oid_names table then the corresponding
  * position in the oid_names table is returned otherwise -1 is returned
  */
@@ -141,7 +150,7 @@ int known_oid(chunk_t object)
        return -1;
 }
 
-/*
+/**
  * Decodes the length in bytes of an ASN.1 object
  */
 u_int asn1_length(chunk_t *blob)
@@ -188,7 +197,7 @@ u_int asn1_length(chunk_t *blob)
        return len;
 }
 
-/*
+/**
  * determines if a character string is of type ASN.1 printableString
  */
 bool is_printablestring(chunk_t str)
@@ -205,9 +214,9 @@ bool is_printablestring(chunk_t str)
        return TRUE;
 }
 
-/*
+/**
  * Display a date either in local or UTC time
- * TODO: Does not seem to be thread save
+ * TODO: Does not seem to be thread safe
  */
 char* timetoa(const time_t *time, bool utc)
 {
@@ -225,7 +234,7 @@ char* timetoa(const time_t *time, bool utc)
        return buf;
 }
 
-/*
+/**
  * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
  */
 time_t asn1totime(const chunk_t *utctime, asn1_t type)
@@ -300,19 +309,20 @@ time_t asn1totime(const chunk_t *utctime, asn1_t type)
        return mktime(&t) - timezone - tz_offset;
 }
 
-/*
+/**
  * Initializes the internal context of the ASN.1 parser
  */
 void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit)
 {
-       logger = logger_manager->get_logger(logger_manager, ASN1);
+       asn1_init_logger();
+
        ctx->blobs[0] = blob;
        ctx->level0   = level0;
        ctx->implicit = implicit;
        memset(ctx->loopAddr, '\0', sizeof(ctx->loopAddr));
 }
 
-/*
+/**
  * print the value of an ASN.1 simple object
  */
 static void debug_asn1_simple_object(chunk_t object, asn1_t type)
@@ -348,7 +358,7 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type)
        logger->log_chunk(logger, RAW|LEVEL1, "", object);
 }
 
-/*
+/**
  * Parses and extracts the next ASN.1 object
  */
 bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx)
@@ -479,7 +489,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec
        return TRUE;
 }
 
-/*
+/**
  * parse an ASN.1 simple type
  */
 bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name)
@@ -515,7 +525,7 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c
        return TRUE;
 }
 
-/*
+/**
  * extracts an algorithmIdentifier
  */
 int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
@@ -558,6 +568,8 @@ bool is_asn1(chunk_t blob)
        u_int len;
        u_char tag = *blob.ptr;
        
+       asn1_init_logger();
+
        if (tag != ASN1_SEQUENCE && tag != ASN1_SET)
        {
                logger->log(logger, ERROR|LEVEL2, "  file content is not binary ASN.1");
@@ -572,7 +584,7 @@ bool is_asn1(chunk_t blob)
        return TRUE;
 }
 
-/*
+/**
  * codes ASN.1 lengths up to a size of 16'777'215 bytes
  */
 void code_asn1_length(size_t length, chunk_t *code)
@@ -605,7 +617,7 @@ void code_asn1_length(size_t length, chunk_t *code)
        }
 }
 
-/*
+/**
  * build an empty asn.1 object with tag and length fields already filled in
  */
 u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen)
@@ -634,7 +646,7 @@ u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen)
        return pos;
 }
 
-/*
+/**
  * build a simple ASN.1 object
  */
 chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
@@ -648,7 +660,8 @@ chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
        return object;
 }
 
-/* Build an ASN.1 object from a variable number of individual chunks.
+/**
+ * Build an ASN.1 object from a variable number of individual chunks.
  * Depending on the mode, chunks either are moved ('m') or copied ('c').
  */
 chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
@@ -696,7 +709,7 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
        return construct;
 }
 
-/*
+/**
  * convert a MP integer into a DER coded ASN.1 object
  */
 chunk_t asn1_integer_from_mpz(const mpz_t value)
@@ -709,7 +722,7 @@ chunk_t asn1_integer_from_mpz(const mpz_t value)
        return asn1_wrap(ASN1_INTEGER, "m", n);
 }
 
-/*
+/**
  *  convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
  */
 chunk_t timetoasn1(const time_t *time, asn1_t type)
index b02268dd9a9e6566d21a7fa400565785adb5999f..d3a6986ebdc985d9bbbfd3782cc1e810af279501 100755 (executable)
@@ -1,6 +1,5 @@
 /*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur
  *
  * 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
 #include <stddef.h>
 #include <sys/types.h>
 
+#include "asn1.h"
 #include "pem.h"
 #include "ttodata.h"
 
+#include <utils/lexparser.h>
+#include <utils/logger_manager.h>
 #include <crypto/hashers/hasher.h>
 #include <crypto/crypters/crypter.h>
 
+static logger_t *logger = NULL;
 
-/*
+/**
+ * initializes the PEM logger
+ */
+static void pem_init_logger()
+{
+       if (logger == NULL)
+               logger = logger_manager->get_logger(logger_manager, ASN1);
+}
+
+/**
  * check the presence of a pattern in a character string
  */
 static bool present(const char* pattern, chunk_t* ch)
@@ -44,15 +56,7 @@ static bool present(const char* pattern, chunk_t* ch)
        return FALSE;
 }
 
-/*
- * compare string with chunk
- */
-static bool match(const char *pattern, const chunk_t *ch)
-{
-       return ch->len == strlen(pattern) && strncmp(pattern, ch->ptr, ch->len) == 0;
-}
-
-/*
+/**
  * find a boundary of the form -----tag name-----
  */
 static bool find_boundary(const char* tag, chunk_t *line)
@@ -73,6 +77,8 @@ static bool find_boundary(const char* tag, chunk_t *line)
        {
                if (present("-----", line))
                {
+                       logger->log(logger, CONTROL|LEVEL2,
+                               "  -----%s %.*s-----", tag, (int)name.len, name.ptr);
                        return TRUE;
                }
                line->ptr++;  line->len--;  name.len++;
@@ -80,93 +86,16 @@ static bool find_boundary(const char* tag, chunk_t *line)
        return FALSE;
 }
 
-/*
- * eat whitespace
- */
-static void eat_whitespace(chunk_t *src)
-{
-       while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
-       {
-               src->ptr++;  src->len--;
-       }
-}
-
-/*
- * extracts a token ending with a given termination symbol
- */
-static bool extract_token(chunk_t *token, char termination, chunk_t *src)
-{
-       u_char *eot = memchr(src->ptr, termination, src->len);
-       
-       /* initialize empty token */
-       *token = CHUNK_INITIALIZER;
-       
-       if (eot == NULL) /* termination symbol not found */
-       {
-               return FALSE;
-       }
-       
-       /* extract token */
-       token->ptr = src->ptr;
-       token->len = (u_int)(eot - src->ptr);
-       
-       /* advance src pointer after termination symbol */
-       src->ptr = eot + 1;
-       src->len -= (token->len + 1);
-       
-       return TRUE;
-}
-
-/*
- * extracts a name: value pair from the PEM header
- */
-static bool extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
-{
-       /* extract name */
-       if (!extract_token(name,':', line))
-       {
-               return FALSE;
-       }
-       
-       eat_whitespace(line);
-       
-       /* extract value */
-       *value = *line;
-       return TRUE;
-}
-
-/*
- *  fetches a new line terminated by \n or \r\n
- */
-static bool fetchline(chunk_t *src, chunk_t *line)
-{
-       if (src->len == 0) /* end of src reached */
-               return FALSE;
-
-       if (extract_token(line, '\n', src))
-       {
-               if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
-                       line->len--;  /* remove optional \r */
-       }
-       else /*last line ends without newline */
-       {
-               *line = *src;
-               src->ptr += src->len;
-               src->len = 0;
-       }
-       return TRUE;
-}
-
 /*
  * decrypts a DES-EDE-CBC encrypted data block
  */
-static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase)
+static err_t pem_decrypt(chunk_t *blob, chunk_t *iv, const char *passphrase)
 {
        hasher_t *hasher;
        crypter_t *crypter;
        chunk_t hash;
        chunk_t decrypted;
-       chunk_t pass = {passphrase, strlen(passphrase)};
+       chunk_t pass = {(char*)passphrase, strlen(passphrase)};
        chunk_t key = {alloca(24), 24};
        u_int8_t padding, *last_padding_pos, *first_padding_pos;
        
@@ -203,11 +132,11 @@ static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase)
        while (--last_padding_pos > first_padding_pos)
        {
                if (*last_padding_pos != padding)
-                       return FALSE;
+                       return "invalid passphrase";
        }
        /* remove padding */
        blob->len -= padding;
-       return TRUE;
+       return NULL;
 }
 
 /*  Converts a PEM encoded file into its binary form
@@ -215,7 +144,7 @@ static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase)
  *  RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
  *  RFC 934 Message Encapsulation, January 1985
  */
-status_t pemtobin(chunk_t *blob, char *pass)
+err_t pem_to_bin(chunk_t *blob, const char *passphrase, bool *pgp)
 {
        typedef enum {
                PEM_PRE    = 0,
@@ -244,6 +173,8 @@ status_t pemtobin(chunk_t *blob, char *pass)
        iv.ptr = iv_buf;
        iv.len = 0;
 
+       pem_init_logger();
+
        while (fetchline(&src, &line))
        {
                if (state == PEM_PRE)
@@ -277,8 +208,9 @@ status_t pemtobin(chunk_t *blob, char *pass)
                                        continue;
                                }
 
-                               /* we are looking for a name: value pair */
-                               if (!extract_parameter(&name, &value, &line))
+                               /* we are looking for a parameter: value pair */
+                               logger->log(logger, CONTROL|LEVEL2, "  %.*s", (int)line.len, line.ptr);
+                               if (!extract_parameter_value(&name, &value, &line))
                                        continue;
 
                                if (match("Proc-Type", &name) && *value.ptr == '4')
@@ -294,12 +226,12 @@ status_t pemtobin(chunk_t *blob, char *pass)
 
                                        /* we support DES-EDE3-CBC encrypted files, only */
                                        if (!match("DES-EDE3-CBC", &dek))
-                                               return NOT_SUPPORTED;
+                                               return "encryption algorithm not supported";
 
                                        eat_whitespace(&value);
                                        ugh = ttodata(value.ptr, value.len, 16, iv.ptr, 16, &len);
                                        if (ugh)
-                                               return PARSE_ERROR;
+                                               return "error in IV";
 
                                        iv.len = len;
                                }
@@ -316,6 +248,17 @@ status_t pemtobin(chunk_t *blob, char *pass)
                                        data = line;
                                }
                                
+                               /* check for PGP armor checksum */
+                               if (*data.ptr == '=')
+                               {
+                                       *pgp = TRUE;
+                                       data.ptr++;
+                                       data.len--;
+                                       logger->log(logger, CONTROL|LEVEL2, "  Armor checksum: %.*s",
+                                                               (int)data.len, data.ptr);
+                               continue;
+                               }
+
                                ugh = ttodata(data.ptr, data.len, 64, dst.ptr, blob->len - dst.len, &len);
                                if (ugh)
                                {
@@ -334,10 +277,68 @@ status_t pemtobin(chunk_t *blob, char *pass)
        blob->len = dst.len;
 
        if (state != PEM_POST)
-               return PARSE_ERROR;
+               return "file coded in unknown format, discarded";
+
+       return (encrypted)? pem_decrypt(blob, &iv, passphrase) : NULL;
+}
+
+/* load a coded key or certificate file with autodetection
+ * of binary DER or base64 PEM ASN.1 formats and armored PGP format
+ */
+bool pem_asn1_load_file(const char *filename, const char *passphrase,
+                                               const char *type, chunk_t *blob, bool *pgp)
+{
+       err_t ugh = NULL;
+
+       FILE *fd = fopen(filename, "r");
+
+       pem_init_logger();
+
+       if (fd)
+       {
+               int bytes;
+               fseek(fd, 0, SEEK_END );
+               blob->len = ftell(fd);
+               rewind(fd);
+               blob->ptr = malloc(blob->len);
+               bytes = fread(blob->ptr, 1, blob->len, fd);
+               fclose(fd);
+               logger->log(logger, CONTROL, "loaded %s file '%s' (%d bytes)", type, filename, bytes);
+
+               *pgp = FALSE;
+
+               /* try DER format */
+               if (is_asn1(*blob))
+               {
+                       logger->log(logger, CONTROL|LEVEL1, "  file coded in DER format");
+                       return TRUE;
+               }
+
+               /* try PEM format */
+               ugh = pem_to_bin(blob, passphrase, pgp);
+
+               if (ugh == NULL)
+               {
+                       if (*pgp)
+                       {
+                               logger->log(logger, CONTROL|LEVEL1, "  file coded in armored PGP format");
+                               return TRUE;
+                       }
+                       if (is_asn1(*blob))
+                       {
+                               logger->log(logger, CONTROL|LEVEL1, "  file coded in PEM format");
+                               return TRUE;
+                       }
+                       ugh = "file coded in unknown format, discarded";
+               }
 
-       if (encrypted)
-               return pem_decrypt(blob, &iv, pass);
+               /* a conversion error has occured */
+               logger->log(logger, ERROR, "  %s", ugh);
+               chunk_free(blob);
+       }
        else
-               return SUCCESS;
+       {
+               logger->log(logger, ERROR, "could not open %s file '%s'", type, filename);
+       }
+       return FALSE;
 }
index a4332fd34975cf6b93e0406ac06839796c02b74a..30621fa24aac5a9b6719bbf1a476e634890edf17 100755 (executable)
@@ -1,6 +1,5 @@
 /*
- * Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur
  *
  * 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
@@ -20,6 +19,9 @@
 
 #include <types.h>
 
-status_t pemtobin(chunk_t *blob, char *pass);
+err_t pem_to_bin(chunk_t *blob, const char *passphrase, bool *pgp);
+
+bool pem_asn1_load_file(const char *filename, const char *passphrase,
+                                               const char *type, chunk_t *blob, bool *pgp);
 
 #endif /*PEM_H_*/
index d57244ef55e49f0c3d1a00cfe2aeeb38892f34f1..b2b5adefdce0f89d6d8a1c1f9d97e3e13b3143c7 100644 (file)
@@ -22,8 +22,6 @@
 #define TTODATAV_IGNORESPACE  (1<<1)  /* ignore spaces in base64 encodings*/
 #define TTODATAV_SPACECOUNTS  0       /* do not ignore spaces in base64   */
 
-typedef const char *err_t;     /* error message, or NULL for success */
-
 err_t ttodata(const char *src, size_t srclen, int base, char *buf, size_t buflen, size_t *needed);
 
 
index 358653f0e7205f711d9fd28fd0c3511bb209a755..86a38cbfe734f3a67e65fe934cc4cbea0e024657 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <daemon.h>
 #include <asn1/asn1.h>
+#include <asn1/pem.h>
 
 /* 
  * Oids for hash algorithms are defined in
@@ -736,37 +737,17 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
 
 /*
  * see header
- * TODO: PEM files
  */
 rsa_private_key_t *rsa_private_key_create_from_file(char *filename, char *passphrase)
 {
-       chunk_t chunk;
-       struct stat stb;
-       FILE *file;
-       char *buffer;
-       
-       if (stat(filename, &stb) == -1)
-       {
-               return NULL;
-       }
-       
-       buffer = alloca(stb.st_size);
-       
-       file = fopen(filename, "r");
-       if (file == NULL)
-       {
-               return NULL;
-       }
-       
-       if (fread(buffer, stb.st_size, 1, file) != 1)
-       {
-               fclose(file);
+       bool pgp = FALSE;
+       chunk_t chunk = CHUNK_INITIALIZER;
+       rsa_private_key_t *key = NULL;
+
+       if (!pem_asn1_load_file(filename, passphrase, "private key", &chunk, &pgp))
                return NULL;
-       }
-       fclose(file);
-       
-       chunk.ptr = buffer;
-       chunk.len = stb.st_size;
-       
-       return rsa_private_key_create_from_chunk(chunk);
+
+       key = rsa_private_key_create_from_chunk(chunk);
+       free(chunk.ptr);
+       return key;
 }
index 86a59561829bcf864d63149bd8a17bb18c26cc42..91f9f191ed37c6b200c56179a26c8814399997b0 100755 (executable)
 #include "x509.h"
 
 #include <daemon.h>
-#include <asn1/asn1.h>
 #include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/pem.h>
 #include <utils/logger_manager.h>
 
-typedef const char *err_t;     /* error message, or NULL for success */
-
-
 #define BUF_LEN 512
 #define RSA_MIN_OCTETS (512 / 8)
 #define RSA_MIN_OCTETS_UGH     "RSA modulus too small for security: less than 512 bits"
@@ -905,33 +903,14 @@ x509_t *x509_create_from_chunk(chunk_t chunk)
  */
 x509_t *x509_create_from_file(char *filename)
 {
-       struct stat stb;
-       FILE *file;
-       char *buffer;
-       chunk_t chunk;
-       
-       if (stat(filename, &stb) == -1)
-       {
-               return NULL;
-       }
-       
-       buffer = alloca(stb.st_size);
-       
-       file = fopen(filename, "r");
-       if (file == NULL)
-       {
-               return NULL;
-       }
-       
-       if (fread(buffer, stb.st_size, 1, file) == -1) 
-       {
-               fclose(file);
+       bool pgp = FALSE;
+       chunk_t chunk = CHUNK_INITIALIZER;
+       x509_t *cert = NULL;
+
+       if (!pem_asn1_load_file(filename, "", "certificate", &chunk, &pgp))
                return NULL;
-       }
-       fclose(file);
-       
-       chunk.ptr = buffer;
-       chunk.len = stb.st_size;
-       
-       return x509_create_from_chunk(chunk);
+
+       cert = x509_create_from_chunk(chunk);
+       free(chunk.ptr);
+       return cert;
 }
index 0e0782b31431a527b34c6766943a0b6e7e2a5a2b..4af9bc43db6dcb53dee8809bfbd918fecda2a550 100644 (file)
@@ -37,6 +37,11 @@ typedef int bool;
 #define FALSE  0
 #define TRUE   1
 
+/**
+ *  error message, or NULL for success
+ */
+typedef const char *err_t;
+
 typedef enum status_t status_t;
 
 /**
index 1c82283d7ed85f2381928ff238ca2813fbe47bae..c04f3b1df5d822fc1bfd6dd723b3a66300224c33 100644 (file)
@@ -18,10 +18,14 @@ LIB_OBJS+= $(BUILD_DIR)leak_detective.o
 $(BUILD_DIR)leak_detective.o : $(UTILS_DIR)leak_detective.c $(UTILS_DIR)leak_detective.h
                                                                $(CC) $(CFLAGS) -c -o $@ $<
 
+LIB_OBJS+= $(BUILD_DIR)lexparser.o
+$(BUILD_DIR)lexparser.o :              $(UTILS_DIR)lexparser.c $(UTILS_DIR)lexparser.h
+                                                               $(CC) $(CFLAGS) -c -o $@ $<
+
 LIB_OBJS+= $(BUILD_DIR)linked_list.o
 $(BUILD_DIR)linked_list.o :            $(UTILS_DIR)linked_list.c $(UTILS_DIR)linked_list.h
                                                                $(CC) $(CFLAGS) -c -o $@ $<
-                                                               
+
 LIB_OBJS+= $(BUILD_DIR)logger.o
 $(BUILD_DIR)logger.o :                 $(UTILS_DIR)logger.c $(UTILS_DIR)logger.h
                                                                $(CC) $(CFLAGS) -c -o $@ $<
diff --git a/src/charon/lib/utils/lexparser.c b/src/charon/lib/utils/lexparser.c
new file mode 100644 (file)
index 0000000..e3bb3d1
--- /dev/null
@@ -0,0 +1,135 @@
+/**
+ * @file lexparser.c
+ * 
+ * @brief lexical parser for text-based configuration files
+ *  
+ */
+
+/*
+ * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * 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.
+ */
+
+#include <string.h>
+
+#include "lexparser.h"
+
+
+/**
+ * eat whitespace
+ */
+bool eat_whitespace(chunk_t *src)
+{
+       while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
+       {
+               src->ptr++;  src->len--;
+       }
+    return  src->len > 0 && *src->ptr != '#';
+}
+
+/**
+ * compare string with chunk
+ */
+bool match(const char *pattern, const chunk_t *ch)
+{
+       return ch->len == strlen(pattern) && strncmp(pattern, ch->ptr, ch->len) == 0;
+}
+
+/**
+ * extracts a token ending with a given termination symbol
+ */
+bool extract_token(chunk_t *token, const char termination, chunk_t *src)
+{
+       u_char *eot = memchr(src->ptr, termination, src->len);
+       
+       /* initialize empty token */
+       *token = CHUNK_INITIALIZER;
+       
+       if (eot == NULL) /* termination symbol not found */
+       {
+               return FALSE;
+       }
+       
+       /* extract token */
+       token->ptr = src->ptr;
+       token->len = (u_int)(eot - src->ptr);
+       
+       /* advance src pointer after termination symbol */
+       src->ptr = eot + 1;
+       src->len -= (token->len + 1);
+       
+       return TRUE;
+}
+
+/**
+ *  fetches a new line terminated by \n or \r\n
+ */
+bool fetchline(chunk_t *src, chunk_t *line)
+{
+       if (src->len == 0) /* end of src reached */
+               return FALSE;
+
+       if (extract_token(line, '\n', src))
+       {
+               if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
+                       line->len--;  /* remove optional \r */
+       }
+       else /*last line ends without newline */
+       {
+               *line = *src;
+               src->ptr += src->len;
+               src->len = 0;
+       }
+       return TRUE;
+}
+
+err_t extract_value(chunk_t *value, chunk_t *line)
+{
+       char delimiter = ' ';
+
+       if (!eat_whitespace(line))
+       {
+               return "missing value";
+       }
+       if (*line->ptr == '\'' || *line->ptr == '"')
+       {
+               delimiter = *line->ptr;
+               line->ptr++;  line->len--;
+       }
+       if (!extract_token(value, delimiter, line))
+       {
+               if (delimiter == ' ')
+               {
+                       *value = *line;
+               }
+               else
+               {
+                       return "missing second delimiter";
+               }
+       }
+       return NULL;
+}
+
+/**
+ * extracts a parameter: value pair
+ */
+err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line)
+{
+       /* extract name */
+       if (!extract_token(name,':', line))
+       {
+               return "missing ':'";
+       }
+
+       /* extract value */
+       return extract_value(value, line);
+}
diff --git a/src/charon/lib/utils/lexparser.h b/src/charon/lib/utils/lexparser.h
new file mode 100644 (file)
index 0000000..29c1bf7
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * @file lexparser.h
+ * 
+ * @brief lexical parser for text-based configuration files
+ *  
+ */
+
+/*
+ * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * 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.
+ */
+
+#include <types.h>
+
+/**
+ * @brief Eats whitespace
+ */
+bool eat_whitespace(chunk_t *src);
+
+/**
+ * @brief Compare null-terminated pattern with chunk
+ */
+bool match(const char *pattern, const chunk_t *ch);
+
+/**
+ * @brief Extracts a token ending with a given termination symbol
+ */
+bool extract_token(chunk_t *token, const char termination, chunk_t *src);
+
+/**
+ *  @brief Fetches a new text line terminated by \n or \r\n
+ */
+bool fetchline(chunk_t *src, chunk_t *line);
+
+/**
+ * @brief Extracts a value that might be single or double quoted
+ */
+err_t extract_value(chunk_t *value, chunk_t *line);
+
+/**
+ * @brief extracts a name: value pair from a text line
+ */
+err_t extract_name_value(chunk_t *name, chunk_t *value, chunk_t *line);
+
+/**
+ * @brief extracts a parameter: value from a text line
+ */
+err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line);
index fdaeddff000d5656b4db39e430127794d088537f..151fbfd504cd0800f5cbccebf2d4182a431f5697 100644 (file)
@@ -132,11 +132,15 @@ static void prepend_prefix(private_logger_t *this, log_level_t loglevel, const c
  */
 static int get_priority(log_level_t loglevel)
 {
+       if (loglevel & ERROR)
+       {
+               return LOG_AUTHPRIV|LOG_ERR;
+       }
        if (loglevel & AUDIT)
        {
                return LOG_AUTHPRIV|LOG_INFO;
        }
-       return LOG_DAEMON|LOG_DEBUG;
+       return LOG_AUTHPRIV|LOG_DEBUG;
 }
 
 /**
index 9ecda04137f91826a52b153aa6040a905f2b08b8..7a734a05fb9d3f7a5963d634cdccc79b079b2ccb 100644 (file)
@@ -239,19 +239,21 @@ static void exit_usage(char *error)
 int main(int argc, char *argv[])
 {
        int res;
+       char *op;
        
        if (argc < 2)
        {
                exit_usage(NULL);
        }
        
-       if (strcmp(argv[1], "status") == 0 || 
-               strcmp(argv[1], "statusall") == 0)
+       op = argv[1];
+
+       if (strcmp(op, "status") == 0 ||
+               strcmp(op, "statusall") == 0)
        {
-               res = show_status(argv[1], argc > 2 ? argv[2] : NULL);
+               res = show_status(op, argc > 2 ? argv[2] : NULL);
        }
-       
-       else if (strcmp(argv[1], "up") == 0)
+       else if (strcmp(op, "up") == 0)
        {
                if (argc < 3)
                {
@@ -259,7 +261,7 @@ int main(int argc, char *argv[])
                }
                res = initiate_connection(argv[2]);
        }
-       else if (strcmp(argv[1], "down") == 0)
+       else if (strcmp(op, "down") == 0)
        {
                if (argc < 3)
                {
@@ -267,7 +269,7 @@ int main(int argc, char *argv[])
                }
                res = terminate_connection(argv[2]);
        }
-       else if (strcmp(argv[1], "add") == 0)
+       else if (strcmp(op, "add") == 0)
        {
                if (argc < 11)
                {
@@ -279,7 +281,7 @@ int main(int argc, char *argv[])
                                                         argv[7], argv[8], 
                                                         atoi(argv[9]), atoi(argv[10]));
        }
-       else if (strcmp(argv[1], "logtype") == 0)
+       else if (strcmp(op, "logtype") == 0)
        {
                if (argc < 5)
                {
@@ -287,7 +289,7 @@ int main(int argc, char *argv[])
                }
                res = set_logtype(argv[2], argv[3], atoi(argv[4])); 
        }
-       else if (strcmp(argv[1], "loglevel") == 0)
+       else if (strcmp(op, "loglevel") == 0)
        {
                if (argc < 4)
                {
index 80f4192a4d9a5601c8ada5afc3d7f86b2a005b3c..8c1ad8a38a414c7a1c3894fcb79048265fc026e4 100644 (file)
@@ -1 +1,2 @@
-distributed by Andreas Steffen <andreas.steffen@strongswan.org>
+distributed by the Institute of Internet Technologies and Applications
+University of Applied Sciences Rapperswil, Switzerland (ITA-HSR)
index 04156e8ae790da49985b82b087719b2f5bd7ca96..1a5006eed70e8e66ef70ef22a0116440040b9745 100755 (executable)
@@ -1,6 +1,7 @@
 #! /bin/sh
 # prefix command to run stuff from our programs directory
 # Copyright (C) 1998-2002  Henry Spencer.
+# Copyright (C) 2006 Andreas Steffen
 # 
 # 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
@@ -26,6 +27,7 @@ IPSEC_DIR="$IPSEC_LIBDIR"
 export IPSEC_DIR IPSEC_CONFS IPSEC_LIBDIR IPSEC_EXECDIR
 
 IPSEC_STARTER_PID="/var/run/starter.pid"
+IPSEC_PLUTO_PID="/var/run/pluto.pid"
 IPSEC_CHARON_PID="/var/run/charon.pid"
 
 # standardize PATH, and export it for everything else's benefit
@@ -123,10 +125,13 @@ case "$1" in
        ;;
 down)
        shift
-       $IPSEC_EXECDIR/whack --name "$1" --terminate
+       if test -e $IPSEC_PLUTO_PID
+       then
+               $IPSEC_EXECDIR/whack --name "$1" --terminate
+       fi
        if test -e $IPSEC_CHARON_PID
        then
-           $IPSEC_EXECDIR/stroke down "$1"
+               $IPSEC_EXECDIR/stroke down "$1"
        fi
        exit 0
        ;;
@@ -138,16 +143,22 @@ rereadcacerts|rereadaacerts|rereadocspcerts|\
 rereadacerts|rereadcrls|rereadall)
        op="$1"
        shift
-        $IPSEC_EXECDIR/whack "$@" "--$op"
-       if test -e $IPSEC_CHARON_PID
+       if test -e $IPSEC_PLUTO_PID
        then
-            $IPSEC_EXECDIR/stroke "$op"
-        fi
+               $IPSEC_EXECDIR/whack "$@" "--$op"
+       fi
+       #if test -e $IPSEC_CHARON_PID
+       #then
+       #       $IPSEC_EXECDIR/stroke "$op"
+       #fi
        exit 0
        ;;
 ready)
        shift
-       $IPSEC_EXECDIR/whack --listen
+       if test -e $IPSEC_PLUTO_PID
+       then
+               $IPSEC_EXECDIR/whack --listen
+       fi
        exit 0
        ;;
 reload)
@@ -170,19 +181,28 @@ restart)
 route|unroute)
        op="$1"
        shift
-       $IPSEC_EXECDIR/whack --name "$1" "--$op"
+       if test -e $IPSEC_PLUTO_PID
+       then
+               $IPSEC_EXECDIR/whack --name "$1" "--$op"
+       fi
        exit 0
        ;;
 scencrypt|scdecrypt)
        op="$1"
        shift
-        $IPSEC_EXECDIR/whack "--$op" "$@"
+       if test -e $IPSEC_PLUTO_PID
+       then
+               $IPSEC_EXECDIR/whack "--$op" "$@"
+       fi
        exit 0
        ;;
 secrets)
-        $IPSEC_EXECDIR/whack --rereadsecrets
-        exit 0
-        ;;
+       if test -e $IPSEC_PLUTO_PID
+       then
+               $IPSEC_EXECDIR/whack --rereadsecrets
+       fi
+       exit 0
+       ;;
 start)
        shift
        exec $IPSEC_EXECDIR/starter "$@"
@@ -192,17 +212,23 @@ status|statusall)
        shift
        if test $# -eq 0
        then
-           $IPSEC_EXECDIR/whack "--$op"
-           if test -e $IPSEC_CHARON_PID
-           then
-               $IPSEC_EXECDIR/stroke "$op"
-           fi
+               if test -e $IPSEC_PLUTO_PID
+               then
+                       $IPSEC_EXECDIR/whack "--$op"
+               fi
+               if test -e $IPSEC_CHARON_PID
+               then
+                       $IPSEC_EXECDIR/stroke "$op"
+               fi
        else
-           $IPSEC_EXECDIR/whack --name "$1" "--$op"
-           if test -e $IPSEC_CHARON_PID
-           then
-               $IPSEC_EXECDIR/stroke "$op" "$1"
-           fi
+               if test -e $IPSEC_PLUTO_PID
+               then
+                       $IPSEC_EXECDIR/whack --name "$1" "--$op"
+               fi
+               if test -e $IPSEC_CHARON_PID
+               then
+                       $IPSEC_EXECDIR/stroke "$op" "$1"
+               fi
        fi
        exit 0
        ;;
@@ -218,7 +244,10 @@ stop)
        ;;
 up)
        shift
-       $IPSEC_EXECDIR/whack --name "$1" --initiate
+       if test -e $IPSEC_PLUTO_PID
+       then
+               $IPSEC_EXECDIR/whack --name "$1" --initiate
+       fi
        if test -e $IPSEC_CHARON_PID
        then
            $IPSEC_EXECDIR/stroke up "$1"
@@ -228,10 +257,10 @@ up)
 update)
        if test -e $IPSEC_STARTER_PID 
        then
-           echo "Updating strongSwan IPsec configuration..." >&2
-           kill -s HUP `cat $IPSEC_STARTER_PID`
+               echo "Updating strongSwan IPsec configuration..." >&2
+               kill -s HUP `cat $IPSEC_STARTER_PID`
        else
-           echo "ipsec starter is not running" >&2
+               echo "ipsec starter is not running" >&2
        fi
        exit 0
        ;;
@@ -241,7 +270,7 @@ version|--version)
        echo "See \`ipsec --copyright' for copyright information."
        if [ -f $IPSEC_LIBDIR/distro.txt ]
        then
-           cat $IPSEC_LIBDIR/distro.txt
+               cat $IPSEC_LIBDIR/distro.txt
        fi
        exit 0
        ;;
index 263bdbd1e67858f50b5b17c6a3d0f38c85f70f91..6cf6a6a8b796a4fdefeb6eafcdef0118beefc41a 100644 (file)
@@ -11,7 +11,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: connections.c,v 1.42 2006/04/22 21:59:20 as Exp $
+ * RCSID $Id: connections.c,v 1.43 2006/04/29 18:16:02 as Exp $
  */
 
 #include <string.h>
@@ -4022,7 +4022,7 @@ show_connections_status(bool all, const char *name)
     /* sort it! */
     qsort(array, count, sizeof(struct connection *), connection_compare_qsort);
 
-    for (i=0; i<count; i++)
+    for (i = 0; i < count; i++)
     {
        const char *ifn;
        char instance[1 + 10 + 1];
@@ -4076,7 +4076,7 @@ show_connections_status(bool all, const char *name)
            if (c->spd.that.groups != NULL)
            {
                char buf[BUF_LEN];
-           
+       
                format_groups(c->spd.that.groups, buf, BUF_LEN);
                whack_log(RC_COMMENT
                    , "\"%s\"%s:   groups: %s"
@@ -4097,7 +4097,7 @@ show_connections_status(bool all, const char *name)
                , (unsigned long) c->sa_keying_tries);
 
            /* show DPD parameters if defined */
-           
+       
            if (c->dpd_action != DPD_ACTION_NONE)
                whack_log(RC_COMMENT
                    , "\"%s\"%s:   dpd_action: %s;"
@@ -4141,6 +4141,9 @@ show_connections_status(bool all, const char *name)
            kernel_alg_show_connection(c, instance);
        }
     }
+    if (count > 0)
+       whack_log(RC_COMMENT, BLANK_FORMAT);    /* spacer */
+
     pfree(array);
 }
 
index 5d7c5f78aa546f0c5bf6105ffa43b4d6288e6aa9..d2070c0d4e81bdb54cc88642818cdd86f2f8ca82 100644 (file)
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: kernel.c,v 1.25 2006/04/17 14:58:09 as Exp $
+ * RCSID $Id: kernel.c,v 1.26 2006/04/29 18:16:02 as Exp $
  */
 
 #include <stddef.h>
@@ -934,6 +934,8 @@ show_shunt_status(void)
            , ourst, ourport, hist, hisport, sat, bs->transport_proto
            , prio, bs->why);
     }
+    if (bare_shunts != NULL)
+       whack_log(RC_COMMENT, BLANK_FORMAT);    /* spacer */
 }
 
 /* Setup an IPsec route entry.
index 137e929802613b61c9f22f1513e961f531405d12..73ffceccdf80e9390ae6f84aa82f209e034a594d 100644 (file)
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: log.c,v 1.7 2005/07/11 18:33:45 as Exp $
+ * RCSID $Id: log.c,v 1.8 2006/04/29 18:16:02 as Exp $
  */
 
 #include <stdio.h>
@@ -770,13 +770,11 @@ show_status(bool all, const char *name)
        show_ifaces_status();
        show_myid_status();
        show_debug_status();
+       whack_log(RC_COMMENT, BLANK_FORMAT);    /* spacer */
     }
-    whack_log(RC_COMMENT, BLANK_FORMAT);       /* spacer */
     show_connections_status(all, name);
-    whack_log(RC_COMMENT, BLANK_FORMAT);       /* spacer */
     show_states_status(name);
 #ifdef KLIPS
-    whack_log(RC_COMMENT, BLANK_FORMAT);       /* spacer */
     show_shunt_status();
 #endif
 }
index 5957654e32ea075df30882f71b5b9f4ab76307ce..0781d2eb3b27457daa4f2b609838aa79803720db 100644 (file)
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: state.c,v 1.12 2006/04/03 15:49:36 as Exp $
+ * RCSID $Id: state.c,v 1.13 2006/04/29 18:16:02 as Exp $
  */
 
 #include <stdio.h>
@@ -902,6 +902,8 @@ show_states_status(const char *name)
        if (IS_PHASE1(st->st_state))
            show_pending_phase2(st->st_connection->host_pair, st);
     }
+    if (count > 0)
+       whack_log(RC_COMMENT, BLANK_FORMAT);    /* spacer */
 
     /* free the array */
     pfree(array);
index 51931c23924d2d1c2a2d1418ca26099d33438c92..1616fed28ae82d15fe3512842cb48666cc08c2b9 100644 (file)
@@ -198,7 +198,8 @@ static struct vid_struct _vid_tab[] = {
        /*
         * strongSwan
         */
-       DEC_MD5_VID(STRONGSWAN,       "strongSwan 2.7.0")
+       DEC_MD5_VID(STRONGSWAN,       "strongSwan 4.0.0")
+       DEC_MD5_VID(STRONGSWAN_2_7_0, "strongSwan 2.7.0")
        DEC_MD5_VID(STRONGSWAN_2_6_4, "strongSwan 2.6.4")
        DEC_MD5_VID(STRONGSWAN_2_6_3, "strongSwan 2.6.3")
        DEC_MD5_VID(STRONGSWAN_2_6_2, "strongSwan 2.6.2")
index d6b414be2db47bbbcbeaa249d6c8b8b978311d5a..7c2030d76ade5c9252c5c4cf049e10fff90f2d46 100644 (file)
@@ -76,6 +76,7 @@ enum known_vendorid {
   VID_STRONGSWAN_2_6_2         = 55,
   VID_STRONGSWAN_2_6_3         = 56,
   VID_STRONGSWAN_2_6_4         = 57,
+  VID_STRONGSWAN_2_7_0         = 58,
 
   /* 101 - 200 : NAT-Traversal */
   VID_NATT_STENBERG_01         =101,
index a3b1b7379e33690d3900ddeaf64f9546a6bfea30..9793a55a53086be62cb98e2c920329fa9fcad322 100644 (file)
@@ -40,6 +40,12 @@ typedef enum {
        STATE_INVALID
 } starter_state_t;
 
+typedef enum {
+       KEY_EXCHANGE_IKE,
+       KEY_EXCHANGE_IKEV1,
+       KEY_EXCHANGE_IKEV2
+} keyexchange_t;
+
 typedef struct starter_end starter_end_t;
 
 struct starter_end {
@@ -89,7 +95,7 @@ struct starter_conn {
        startup_t       startup;
        starter_state_t state;
 
-       int             keyexchange;
+       keyexchange_t   keyexchange;
        lset_t          policy;
        time_t          sa_ike_life_seconds;
        time_t          sa_ipsec_life_seconds;
index 4b4e23fb3ad20cb973cc020eb9f7f349b44335df..1f857ce44254821e22836882ead6158d63e466c7 100644 (file)
@@ -36,6 +36,7 @@
 #include "confread.h"
 #include "files.h"
 #include "starterwhack.h"
+#include "starterstroke.h"
 #include "invokepluto.h"
 #include "invokecharon.h"
 #include "netkey.h"
 #define FLAG_ACTION_RELOAD        0x04
 #define FLAG_ACTION_QUIT          0x08
 #define FLAG_ACTION_LISTEN        0x10
-#ifdef IKEV2
 #define FLAG_ACTION_START_CHARON  0x20
-#endif /* IKEV2 */
 
 static unsigned int _action_ = 0;
 
 static void
 fsig(int signal)
 {
-    switch (signal)
-    {
-    case SIGCHLD:
+       switch (signal)
        {
-           int status;
-           pid_t pid;
-           char *name = NULL;
-
-           while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
-           {
-               if (pid == starter_pluto_pid())
-                   name = " (Pluto)";
+       case SIGCHLD:
+               {
+                       int status;
+                       pid_t pid;
+                       char *name = NULL;
+
+                       while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
+               {
+                               if (pid == starter_pluto_pid())
+                               name = " (Pluto)";
 #ifdef IKEV2
-               if (pid == starter_charon_pid())
-                   name = " (Charon)";
+                               if (pid == starter_charon_pid())
+                                       name = " (Charon)";
 #endif /* IKEV2 */
-               if (WIFSIGNALED(status))
-                   DBG(DBG_CONTROL,
-                       DBG_log("child %d%s has been killed by sig %d\n",
-                               pid, name?name:"", WTERMSIG(status))
-                   )
-               else if (WIFSTOPPED(status))
-                   DBG(DBG_CONTROL,
-                       DBG_log("child %d%s has been stopped by sig %d\n",
-                               pid, name?name:"", WSTOPSIG(status))
-                   )
-               else if (WIFEXITED(status))
-                   DBG(DBG_CONTROL,
-                       DBG_log("child %d%s has quit (exit code %d)\n",
-                               pid, name?name:"", WEXITSTATUS(status))
-                   )
-               else
-                   DBG(DBG_CONTROL,
-                       DBG_log("child %d%s has quit", pid, name?name:"")
-                   )
-
-               if (pid == starter_pluto_pid())
-                   starter_pluto_sigchild(pid);
+                               if (WIFSIGNALED(status))
+                                       DBG(DBG_CONTROL,
+                                               DBG_log("child %d%s has been killed by sig %d\n",
+                                                       pid, name?name:"", WTERMSIG(status))
+                               )
+                               else if (WIFSTOPPED(status))
+                                       DBG(DBG_CONTROL,
+                                               DBG_log("child %d%s has been stopped by sig %d\n",
+                                                       pid, name?name:"", WSTOPSIG(status))
+                               )
+                               else if (WIFEXITED(status))
+                               DBG(DBG_CONTROL,
+                                               DBG_log("child %d%s has quit (exit code %d)\n",
+                                                       pid, name?name:"", WEXITSTATUS(status))
+                                       )
+                               else
+                                       DBG(DBG_CONTROL,
+                                               DBG_log("child %d%s has quit", pid, name?name:"")
+                               )
+
+                               if (pid == starter_pluto_pid())
+                                       starter_pluto_sigchild(pid);
 #ifdef IKEV2
-               if (pid == starter_charon_pid())
-                   starter_charon_sigchild(pid);
+                               if (pid == starter_charon_pid())
+                                       starter_charon_sigchild(pid);
 #endif /* IKEV2 */
-           }
-       }
-       break;
+                       }
+               }
+               break;
 
     case SIGPIPE:
-       /** ignore **/
-       break;
+               /** ignore **/
+               break;
 
     case SIGALRM:
-       _action_ |= FLAG_ACTION_START_PLUTO;
+               _action_ |= FLAG_ACTION_START_PLUTO;
 #ifdef IKEV2
-       _action_ |= FLAG_ACTION_START_CHARON;
+               _action_ |= FLAG_ACTION_START_CHARON;
 #endif /* IKEV2 */
-       break;
+               break;
 
     case SIGHUP:
-       _action_ |= FLAG_ACTION_UPDATE;
-       break;
+               _action_ |= FLAG_ACTION_UPDATE;
+               break;
 
     case SIGTERM:
     case SIGQUIT:
     case SIGINT:
        _action_ |= FLAG_ACTION_QUIT;
-       break;
+               break;
 
     case SIGUSR1:
-       _action_ |= FLAG_ACTION_RELOAD;
-       _action_ |= FLAG_ACTION_UPDATE;
-       break;
+               _action_ |= FLAG_ACTION_RELOAD;
+               _action_ |= FLAG_ACTION_UPDATE;
+               break;
 
     default:
-       plog("fsig(): unknown signal %d -- investigate", signal);
-       break;
+               plog("fsig(): unknown signal %d -- investigate", signal);
+               break;
     }
 }
 
 static void
 usage(char *name)
 {
-    fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>] "
-                   "[--debug|--debug-more|--debug-all]\n");
-    exit(1);
+       fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>] "
+                                       "[--debug|--debug-more|--debug-all]\n");
+       exit(1);
 }
 
 int main (int argc, char **argv)
 {
-    starter_config_t *cfg = NULL;
-    starter_config_t *new_cfg;
-    starter_conn_t *conn, *conn2;
-    starter_ca_t *ca, *ca2;
+       starter_config_t *cfg = NULL;
+       starter_config_t *new_cfg;
+       starter_conn_t *conn, *conn2;
+       starter_ca_t *ca, *ca2;
 
-    struct stat stb;
+       struct stat stb;
 
-    char *err = NULL;
-    int i;
-    int id = 1;
-    struct timeval tv;
-    unsigned long auto_update = 0;
-    time_t last_reload;
-    bool no_fork = FALSE;
+       char *err = NULL;
+       int i;
+       int id = 1;
+       struct timeval tv;
+       unsigned long auto_update = 0;
+       time_t last_reload;
+       bool no_fork = FALSE;
 
-    /* global variables defined in log.h */
-    log_to_stderr = TRUE;
-    base_debugging = DBG_NONE;
+       /* global variables defined in log.h */
+       log_to_stderr = TRUE;
+       base_debugging = DBG_NONE;
 
     /* parse command line */
-    for (i = 1; i < argc; i++)
-    {
-       if (streq(argv[i], "--debug"))
+       for (i = 1; i < argc; i++)
        {
-           base_debugging |= DBG_CONTROL;
+               if (streq(argv[i], "--debug"))
+               {
+                       base_debugging |= DBG_CONTROL;
+               }
+               else if (streq(argv[i], "--debug-more"))
+               {
+                       base_debugging |= DBG_CONTROLMORE;
+               }
+               else if (streq(argv[i], "--debug-all"))
+               {
+                       base_debugging |= DBG_ALL;
+               }
+               else if (streq(argv[i], "--nofork"))
+               {
+                       no_fork = TRUE;
+               }
+               else if (streq(argv[i], "--auto-update") && i+1 < argc)
+               {
+                       auto_update = atoi(argv[++i]);
+                       if (!auto_update)
+                               usage(argv[0]);
+               }
+               else
+               {
+                       usage(argv[0]);
+               }
        }
-       else if (streq(argv[i], "--debug-more"))
+
+       /* Init */
+       init_log("ipsec_starter");
+       cur_debugging = base_debugging;
+
+       signal(SIGHUP,  fsig);
+       signal(SIGCHLD, fsig);
+       signal(SIGPIPE, fsig);
+       signal(SIGINT,  fsig);
+       signal(SIGTERM, fsig);
+       signal(SIGQUIT, fsig);
+       signal(SIGALRM, fsig);
+       signal(SIGUSR1, fsig);
+
+       plog("Starting strongSwan IPsec %s [starter]...", ipsec_version_code());
+
+       /* verify that we can start */
+       if (getuid() != 0)
        {
-           base_debugging |= DBG_CONTROLMORE;
+               plog("permission denied (must be superuser)");
+               exit(1);
        }
-       else if (streq(argv[i], "--debug-all"))
+
+       if (stat(PLUTO_PID_FILE, &stb) == 0)
        {
-           base_debugging |= DBG_ALL;
+               plog("pluto is already running (%s exists) -- skipping pluto start", PLUTO_PID_FILE);
        }
-       else if (streq(argv[i], "--nofork"))
+       else
        {
-           no_fork = TRUE;
+               _action_ |= FLAG_ACTION_START_PLUTO;
        }
-       else if (streq(argv[i], "--auto-update") && i+1 < argc)
+#ifdef IKEV2
+       if (stat(CHARON_PID_FILE, &stb) == 0)
        {
-           auto_update = atoi(argv[++i]);
-           if (!auto_update)
-               usage(argv[0]);
+               plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE);
        }
        else
        {
-          usage(argv[0]);
+               _action_ |= FLAG_ACTION_START_CHARON;
        }
-    }
-
-    /* Init */
-    init_log("ipsec_starter");
-    cur_debugging = base_debugging;
-
-    signal(SIGHUP,  fsig);
-    signal(SIGCHLD, fsig);
-    signal(SIGPIPE, fsig);
-    signal(SIGINT,  fsig);
-    signal(SIGTERM, fsig);
-    signal(SIGQUIT, fsig);
-    signal(SIGALRM, fsig);
-    signal(SIGUSR1, fsig);
-       
-       
-       plog("Starting strongSwan IPsec %s [starter]...", ipsec_version_code());
-
-    /* verify that we can start */
-    if (getuid() != 0)
-    {
-       plog("permission denied (must be superuser)");
-       exit(1);
-    }
-
-    if (stat(PLUTO_PID_FILE, &stb) == 0)
-    {
-       plog("pluto is already running (%s exists) -- skipping pluto start", PLUTO_PID_FILE);
-    }
-    else
-    {
-       _action_ |= FLAG_ACTION_START_PLUTO;
-    }
-#ifdef IKEV2
-    if (stat(CHARON_PID_FILE, &stb) == 0)
-    {
-       plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE);
-    }
-    else
-    {
-       _action_ |= FLAG_ACTION_START_CHARON;
-    }
 #endif /* IKEV2 */
-    if (stat(DEV_RANDOM, &stb) != 0)
-    {
-       plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
-       exit(1);
-    }
-
-    if (stat(DEV_URANDOM, &stb)!= 0)
-    {
-       plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
-       exit(1);
-    }
+       if (stat(DEV_RANDOM, &stb) != 0)
+       {
+               plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
+               exit(1);
+       }
 
-    cfg = confread_load(CONFIG_FILE);
-    if (!cfg)
-    {
-       plog("unable to start strongSwan -- errors in config");
-       exit(1);
-    }
+       if (stat(DEV_URANDOM, &stb)!= 0)
+       {
+               plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
+               exit(1);
+       }
 
-    /* determine if we have a native netkey IPsec stack */
-    if (!starter_netkey_init())
-    {
-       plog("nor netkey IPSec stack detected");
-       exit(1);
-    }
+       cfg = confread_load(CONFIG_FILE);
+       if (!cfg)
+       {
+               plog("unable to start strongSwan -- errors in config");
+               exit(1);
+       }
 
-    last_reload = time(NULL);
+       /* determine if we have a native netkey IPsec stack */
+       if (!starter_netkey_init())
+       {
+               plog("nor netkey IPSec stack detected");
+               exit(1);
+       }
 
-    if (stat(MY_PID_FILE, &stb) == 0)
-    {
-       plog("starter is already running (%s exists) -- no fork done", MY_PID_FILE);
-       exit(0);
-    }
+       last_reload = time(NULL);
 
-    /* fork if we're not debugging stuff */
-    if (!no_fork)
-    {
-       log_to_stderr = FALSE;
+       if (stat(MY_PID_FILE, &stb) == 0)
+       {
+               plog("starter is already running (%s exists) -- no fork done", MY_PID_FILE);
+               exit(0);
+       }
 
-       switch (fork())
+       /* fork if we're not debugging stuff */
+       if (!no_fork)
        {
-       case 0:
-           {
-               int fnull = open("/dev/null", O_RDWR);
+               log_to_stderr = FALSE;
 
-               if (fnull >= 0)
+               switch (fork())
                {
-                   dup2(fnull, STDIN_FILENO);
-                   dup2(fnull, STDOUT_FILENO);
-                   dup2(fnull, STDERR_FILENO);
-                   close(fnull);
+               case 0:
+                       {
+                               int fnull = open("/dev/null", O_RDWR);
+
+                               if (fnull >= 0)
+                               {
+                                       dup2(fnull, STDIN_FILENO);
+                                       dup2(fnull, STDOUT_FILENO);
+                                       dup2(fnull, STDERR_FILENO);
+                                       close(fnull);
+                               }
+                       }
+                       break;
+               case -1:
+                       plog("can't fork: %s", strerror(errno));
+                       break;
+               default:
+                       exit(0);
                }
-           }
-           break;
-       case -1:
-           plog("can't fork: %s", strerror(errno));
-           break;
-       default:
-           exit(0);
-       }
     }
 
     /* save pid file in /var/run/starter.pid */
     {
-       FILE *fd = fopen(MY_PID_FILE, "w");
+               FILE *fd = fopen(MY_PID_FILE, "w");
 
-       if (fd)
-       {
-           fprintf(fd, "%u\n", getpid());
-           fclose(fd);
-       }
+               if (fd)
+               {
+                       fprintf(fd, "%u\n", getpid());
+                       fclose(fd);
+               }
     }
 
     for (;;)
     {
-       /*
-        * Stop pluto/charon (if started) and exit
-        */
-       if (_action_ & FLAG_ACTION_QUIT)
-       {
-           if (starter_pluto_pid())
-               starter_stop_pluto();
+               /*
+                * Stop pluto/charon (if started) and exit
+                */
+               if (_action_ & FLAG_ACTION_QUIT)
+               {
+                       if (starter_pluto_pid())
+                               starter_stop_pluto();
 #ifdef IKEV2
-               if (starter_charon_pid())
-               starter_stop_charon();
-#endif IKEV2
-           starter_netkey_cleanup();
-           confread_free(cfg);
-           unlink(MY_PID_FILE);
-           unlink(INFO_FILE);
+                       if (starter_charon_pid())
+                               starter_stop_charon();
+#endif /* IKEV2 */
+                       starter_netkey_cleanup();
+                       confread_free(cfg);
+                       unlink(MY_PID_FILE);
+                       unlink(INFO_FILE);
 #ifdef LEAK_DETECTIVE
-           report_leaks();
+                       report_leaks();
 #endif /* LEAK_DETECTIVE */
-           close_log();
-           plog("ipsec starter stopped");
-           exit(0);
-       }
+                       close_log();
+                       plog("ipsec starter stopped");
+                       exit(0);
+               }
 
-       /*
-        * Delete all connections. Will be added below
-        */
-       if (_action_ & FLAG_ACTION_RELOAD)
-       {
-           if (starter_pluto_pid())
-           {
-               for (conn = cfg->conn_first; conn; conn = conn->next)
+               /*
+                * Delete all connections. Will be added below
+                */
+               if (_action_ & FLAG_ACTION_RELOAD)
                {
-                   if (conn->state == STATE_ADDED)
-                   {
-                       starter_whack_del_conn(conn);
+                       if (starter_pluto_pid())
+                       {
+                               for (conn = cfg->conn_first; conn; conn = conn->next)
+                               {
+                                       if (conn->state == STATE_ADDED)
+                                       {
 #ifdef IKEV2
-                       starter_stroke_del_conn(conn);
+                                               if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
+                                               {
+                                                       starter_stroke_del_conn(conn);
+                                               }
 #endif /* IKEV2 */
-                       conn->state = STATE_TO_ADD;
-                   }
-               }
-               for (ca = cfg->ca_first; ca; ca = ca->next)
-               {
-                   if (ca->state == STATE_ADDED)
-                   {
-                       starter_whack_del_ca(ca);
-                       ca->state = STATE_TO_ADD;
-                   }
-               }
-           }
-           _action_ &= ~FLAG_ACTION_RELOAD;
-       }
-
-       /*
-        * Update configuration
-        */
-       if (_action_ & FLAG_ACTION_UPDATE)
-       {
-           err = NULL;
-           DBG(DBG_CONTROL,
-               DBG_log("Reloading config...")
-           )
-           new_cfg = confread_load(CONFIG_FILE);
-
-           if (new_cfg)
-           {
-               /* Switch to new config. New conn will be loaded below */
-               if (!starter_cmp_defaultroute(&new_cfg->defaultroute
-                   , &cfg->defaultroute))
-               {
-                   _action_ |= FLAG_ACTION_LISTEN;
+                                               else
+                                               {
+                                                       starter_whack_del_conn(conn);
+                                               }
+                                               conn->state = STATE_TO_ADD;
+                               }
+                               }
+                               for (ca = cfg->ca_first; ca; ca = ca->next)
+                               {
+                                       if (ca->state == STATE_ADDED)
+                                       {
+                                               starter_whack_del_ca(ca);
+                                               ca->state = STATE_TO_ADD;
+                                       }
+                               }
+                       }
+                       _action_ &= ~FLAG_ACTION_RELOAD;
                }
 
-               if (!starter_cmp_pluto(cfg, new_cfg)) 
-               {
-                   plog("Pluto has changed");
-                   if (starter_pluto_pid())
-                       starter_stop_pluto();
-                   _action_ &= ~FLAG_ACTION_LISTEN;
-                   _action_ |= FLAG_ACTION_START_PLUTO;
-               }
-               else
+               /*
+                * Update configuration
+                */
+               if (_action_ & FLAG_ACTION_UPDATE)
                {
-                   /* Only reload conn and ca sections if pluto is not killed */
+                       err = NULL;
+                       DBG(DBG_CONTROL,
+                               DBG_log("Reloading config...")
+                       )
+                       new_cfg = confread_load(CONFIG_FILE);
 
-                   /* Look for new connections that are already loaded */
-                   for (conn = cfg->conn_first; conn; conn = conn->next)
-                   {
-                       if (conn->state == STATE_ADDED)
+                       if (new_cfg)
                        {
-                           for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
-                           {
-                               if (conn2->state == STATE_TO_ADD
-                               && starter_cmp_conn(conn, conn2))
+                               /* Switch to new config. New conn will be loaded below */
+                               if (!starter_cmp_defaultroute(&new_cfg->defaultroute
+                               , &cfg->defaultroute))
                                {
-                                   conn->state = STATE_REPLACED;
-                                   conn2->state = STATE_ADDED;
-                                   conn2->id = conn->id;
-                                   break;
+                                       _action_ |= FLAG_ACTION_LISTEN;
                                }
-                           }
-                       }
-                   }
 
-                   /* Remove conn sections that have become unused */
-                   for (conn = cfg->conn_first; conn; conn = conn->next)
-                   {
-                       if (conn->state == STATE_ADDED)
-                           starter_whack_del_conn(conn);
+                               if (!starter_cmp_pluto(cfg, new_cfg)) 
+                               {
+                                       plog("Pluto has changed");
+                                       if (starter_pluto_pid())
+                                               starter_stop_pluto();
+                                       _action_ &= ~FLAG_ACTION_LISTEN;
+                                       _action_ |= FLAG_ACTION_START_PLUTO;
+                               }
+                               else
+                               {
+                                       /* Only reload conn and ca sections if pluto is not killed */
+
+                                       /* Look for new connections that are already loaded */
+                                       for (conn = cfg->conn_first; conn; conn = conn->next)
+                                       {
+                                               if (conn->state == STATE_ADDED)
+                                               {
+                                                       for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
+                                                       {
+                                                               if (conn2->state == STATE_TO_ADD
+                                                               && starter_cmp_conn(conn, conn2))
+                                                               {
+                                                                       conn->state = STATE_REPLACED;
+                                                                       conn2->state = STATE_ADDED;
+                                                                       conn2->id = conn->id;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                       }
+
+                                       /* Remove conn sections that have become unused */
+                                       for (conn = cfg->conn_first; conn; conn = conn->next)
+                                       {
+                                               if (conn->state == STATE_ADDED)
+                                               {
 #ifdef IKEV2
-                           starter_stroke_del_conn(conn);
+                                                       if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
+                                                       {
+                                                               starter_stroke_del_conn(conn);
+                                                       }
+                                                       else
 #endif /* IKEV2 */
-                   }
+                                                       {
+                                                               starter_whack_del_conn(conn);
+                                                       }
+                                               }
+                                       }
+
+                                       /* Look for new ca sections that are already loaded */
+                                       for (ca = cfg->ca_first; ca; ca = ca->next)
+                                       {
+                                               if (ca->state == STATE_ADDED)
+                                               {
+                                                       for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
+                                                       {
+                                                               if (ca2->state == STATE_TO_ADD
+                                                               && starter_cmp_ca(ca, ca2))
+                                                               {
+                                                                       ca->state = STATE_REPLACED;
+                                                                       ca2->state = STATE_ADDED;
+                                                                       break;
+                                                               }
+                                               }
+                                               }
+                                       }
+
+                                       /* Remove ca sections that have become unused */
+                                       for (ca = cfg->ca_first; ca; ca = ca->next)
+                                       {
+                                               if (ca->state == STATE_ADDED)
+                                               starter_whack_del_ca(ca);
+                                       }
+                               }
+                               confread_free(cfg);
+                               cfg = new_cfg;
+                       }
+                       else
+                       {
+                               plog("can't reload config file: %s -- keeping old one");
+                       }
+                       _action_ &= ~FLAG_ACTION_UPDATE;
+                       last_reload = time(NULL);
+               }
 
-                   /* Look for new ca sections that are already loaded */
-                   for (ca = cfg->ca_first; ca; ca = ca->next)
-                   {
-                       if (ca->state == STATE_ADDED)
+               /*
+                * Start pluto
+                */
+               if (_action_ & FLAG_ACTION_START_PLUTO)
+               {
+                       if (starter_pluto_pid() == 0)
                        {
-                           for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
-                           {
-                               if (ca2->state == STATE_TO_ADD
-                               && starter_cmp_ca(ca, ca2))
+                               DBG(DBG_CONTROL,
+                                       DBG_log("Attempting to start pluto...")
+                               )
+
+                               if (starter_start_pluto(cfg, no_fork) == 0)
                                {
-                                   ca->state = STATE_REPLACED;
-                                   ca2->state = STATE_ADDED;
-                                   break;
+                                       starter_whack_listen();
+                               }
+                               else
+                               {
+                                       /* schedule next try */
+                                       alarm(PLUTO_RESTART_DELAY);
                                }
-                           }
                        }
-                   }
-
-                   /* Remove ca sections that have become unused */
-                   for (ca = cfg->ca_first; ca; ca = ca->next)
-                   {
-                       if (ca->state == STATE_ADDED)
-                           starter_whack_del_ca(ca);
-                   }
-               }
-               confread_free(cfg);
-               cfg = new_cfg;
-           }
-           else
-           {
-               plog("can't reload config file: %s -- keeping old one");
-           }
-           _action_ &= ~FLAG_ACTION_UPDATE;
-           last_reload = time(NULL);
-       }
+                       _action_ &= ~FLAG_ACTION_START_PLUTO;
 
-       /*
-        * Start pluto
-        */
-       if (_action_ & FLAG_ACTION_START_PLUTO)
-       {
-           if (starter_pluto_pid() == 0)
-           {
-               DBG(DBG_CONTROL,
-                   DBG_log("Attempting to start pluto...")
-               )
+                       for (ca = cfg->ca_first; ca; ca = ca->next)
+                       {
+                               if (ca->state == STATE_ADDED)
+                               ca->state = STATE_TO_ADD;
+                       }
 
-               if (starter_start_pluto(cfg, no_fork) == 0)
-               {
-                   starter_whack_listen();
-               }
-               else
-               {
-                   /* schedule next try */
-                   alarm(PLUTO_RESTART_DELAY);
+                       for (conn = cfg->conn_first; conn; conn = conn->next)
+                       {
+                               if (conn->state == STATE_ADDED)
+                                       conn->state = STATE_TO_ADD;
+                       }
                }
-           }
-           _action_ &= ~FLAG_ACTION_START_PLUTO;
-
-           for (ca = cfg->ca_first; ca; ca = ca->next)
-           {
-               if (ca->state == STATE_ADDED)
-                   ca->state = STATE_TO_ADD;
-           }
-
-           for (conn = cfg->conn_first; conn; conn = conn->next)
-           {
-               if (conn->state == STATE_ADDED)
-                   conn->state = STATE_TO_ADD;
-           }
-       }
        
 #ifdef IKEV2
-       /*
-        * Start charon
-        */
-       if (_action_ & FLAG_ACTION_START_CHARON)
-       {
-               if (starter_charon_pid() == 0)
+               /*
+                * Start charon
+                */
+               if (_action_ & FLAG_ACTION_START_CHARON)
                {
-                       DBG(DBG_CONTROL,
-                               DBG_log("Attempting to start charon...")
-                          )
-                       if (starter_start_charon(cfg, no_fork) != 0)
+                       if (starter_charon_pid() == 0)
                        {
-                               /* schedule next try */
-                               alarm(PLUTO_RESTART_DELAY);
+                               DBG(DBG_CONTROL,
+                                       DBG_log("Attempting to start charon...")
+                               )
+                               if (starter_start_charon(cfg, no_fork) != 0)
+                               {
+                                       /* schedule next try */
+                                       alarm(PLUTO_RESTART_DELAY);
+                               }
                        }
+                       _action_ &= ~FLAG_ACTION_START_CHARON;
                }
-               _action_ &= ~FLAG_ACTION_START_CHARON;
-       }
 #endif /* IKEV2 */
 
-       /*
-        * Tell pluto to reread its interfaces
-        */
-       if (_action_ & FLAG_ACTION_LISTEN)
-       {
-           starter_whack_listen();
-           _action_ &= ~FLAG_ACTION_LISTEN;
-       }
-
-       /*
-        * Add stale conn and ca sections
-        */
-       if (starter_pluto_pid() != 0)
-       {
-           for (ca = cfg->ca_first; ca; ca = ca->next)
-           {
-               if (ca->state == STATE_TO_ADD)
+               /*
+                * Tell pluto to reread its interfaces
+                */
+               if (_action_ & FLAG_ACTION_LISTEN)
                {
-                   starter_whack_add_ca(ca);
-                   ca->state = STATE_ADDED;
+                       starter_whack_listen();
+                       _action_ &= ~FLAG_ACTION_LISTEN;
                }
-           }
 
-           for (conn = cfg->conn_first; conn; conn = conn->next)
-           {
-               if (conn->state == STATE_TO_ADD)
+               /*
+                * Add stale conn and ca sections
+                */
+               if (starter_pluto_pid() != 0)
                {
-                   if (conn->id == 0)
-                   {
-                       /* affect new unique id */
-                       conn->id = id++;
-                   }
-                   starter_whack_add_conn(conn);
+                       for (ca = cfg->ca_first; ca; ca = ca->next)
+                       {
+                               if (ca->state == STATE_TO_ADD)
+                               {
+                                       starter_whack_add_ca(ca);
+                                       ca->state = STATE_ADDED;
+                               }
+                       }
+
+                       for (conn = cfg->conn_first; conn; conn = conn->next)
+                       {
+                               if (conn->state == STATE_TO_ADD)
+                               {
+                                       if (conn->id == 0)
+                                       {
+                                               /* affect new unique id */
+                                               conn->id = id++;
+                               }
 #ifdef IKEV2
-                   starter_stroke_add_conn(conn);
+                                       if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
+                                       {
+                                               starter_stroke_add_conn(conn);
+                                       }
+                                       else
 #endif /* IKEV2 */
-                   conn->state = STATE_ADDED;
-                   if (conn->startup == STARTUP_START)
-                   {
+                                       {
+                                               starter_whack_add_conn(conn);
+                                       }
+                                       conn->state = STATE_ADDED;
+
+                                       if (conn->startup == STARTUP_START)
+                                       {
 #ifdef IKEV2
-                       if (conn->keyexchange == 2)
-                       {
-                           starter_stroke_initiate_conn(conn);
-                       }
-                       else
+                                               if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
+                                               {
+                                                       starter_stroke_initiate_conn(conn);
+                                               }
+                                               else
 #endif /* IKEV2 */
-                       {
-                           starter_whack_initiate_conn(conn);
-                       }
-                   }
-                   else if (conn->startup == STARTUP_ROUTE)
-                   {
+                                               {
+                                                       starter_whack_initiate_conn(conn);
+                                               }
+                                       }
+                                       else if (conn->startup == STARTUP_ROUTE)
+                                       {
 #ifdef IKEV2
-                       if (conn->keyexchange == 2)
-                       {
-                               starter_stroke_route_conn(conn);
-                       }
-                       else
+                                               if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
+                                               {
+                                                       starter_stroke_route_conn(conn);
+                                               }
+                                               else
 #endif /* IKEV2 */
-                       {
-                               starter_whack_route_conn(conn); 
+                                               {
+                                                       starter_whack_route_conn(conn);
+                                               }
+                                       }
+                               }
                        }
-                   }
                }
-           }
-       }
 
-       /*
-        * If auto_update activated, when to stop select
-        */
-       if (auto_update)
-       {
-           time_t now = time(NULL);
-           tv.tv_sec = (now < last_reload + auto_update)
-                       ? (last_reload + auto_update-now) : 0;
-           tv.tv_usec = 0;
-       }
+               /*
+                * If auto_update activated, when to stop select
+                */
+               if (auto_update)
+               {
+                       time_t now = time(NULL);
 
-       /*
-        * Wait for something to happen
-        */
-       if (select(0, NULL, NULL, NULL, auto_update ? &tv : NULL) == 0)
-       {
-           /* timeout -> auto_update */
-           _action_ |= FLAG_ACTION_UPDATE;
+                       tv.tv_sec = (now < last_reload + auto_update)
+                               ? (last_reload + auto_update-now) : 0;
+                       tv.tv_usec = 0;
+               }
+
+               /*
+                * Wait for something to happen
+                */
+               if (select(0, NULL, NULL, NULL, auto_update ? &tv : NULL) == 0)
+               {
+                       /* timeout -> auto_update */
+                       _action_ |= FLAG_ACTION_UPDATE;
+               }
        }
-    }
 
-    return 0;
+       return 0;
 }
 
index ceddd72d8dd3f0af1148ecd9ac6e38413194a1e9..c4c624ea918aaed5e05cd5884e58c8c7f673641e 100755 (executable)
@@ -374,6 +374,9 @@ do
        eval HOSTLOGIN=root@\$ip_${host}
        ssh $HOSTLOGIN grep pluto /var/log/auth.log \
            > $TESTRESULTDIR/${host}.auth.log
+       echo >> $TESTRESULTDIR/${host}.auth.log
+       ssh $HOSTLOGIN grep charon /var/log/auth.log \
+           >> $TESTRESULTDIR/${host}.auth.log
     done
 
 
index ba103838f857536e06e1a54448d82d1d5882ca5d..c2726cfc9bc8de4f1a79af23bb6ef52ba25e43ee 100755 (executable)
@@ -128,6 +128,7 @@ echo "export USERCOMPILE=\'-DRANDOM_DEVICE=\\\"/dev/urandom\\\"\'" >> $INSTALLSH
 echo "cd /root/${STRONGSWANVERSION}" >> $INSTALLSHELL
 echo "make programs" >> $INSTALLSHELL
 echo "make install" >> $INSTALLSHELL
+echo "ldconfig" >> $INSTALLSHELL
 
 cecho-n " * Compiling $STRONGSWANVERSION within the root file system as chroot.."
 chroot $LOOPDIR /bin/bash /install.sh >> $LOGFILE 2>&1
diff --git a/testing/tests/ikev2-net2net/description.txt b/testing/tests/ikev2-net2net/description.txt
new file mode 100644 (file)
index 0000000..7eea919
--- /dev/null
@@ -0,0 +1,6 @@
+A connection between the subnets behind the gateways <b>moon</b> and <b>sun</b> is set up.
+The authentication is based on <b>X.509 certificates</b>. Upon the successful
+establishment of the IPsec tunnel, <b>leftfirewall=yes</b> automatically
+inserts iptables-based firewall rules that let pass the tunneled traffic.
+In order to test both tunnel and firewall, client <b>alice</b> behind gateway <b>moon</b>
+pings client <b>bob</b> located behind gateway <b>sun</b>.
diff --git a/testing/tests/ikev2-net2net/evaltest.dat b/testing/tests/ikev2-net2net/evaltest.dat
new file mode 100644 (file)
index 0000000..bb4eac4
--- /dev/null
@@ -0,0 +1,5 @@
+moon::ipsec statusall::net-net.*IKE_SA_ESTABLISHED::YES
+sun::ipsec statusall::net-net.*IKE_SA_ESTABLISHED::YES
+alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_seq=1::YES
+sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
+sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
diff --git a/testing/tests/ikev2-net2net/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2-net2net/hosts/moon/etc/ipsec.conf
new file mode 100644 (file)
index 0000000..9a95d40
--- /dev/null
@@ -0,0 +1,13 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+version        2.0     # conforms to second version of ipsec.conf specification
+
+conn net-net 
+       left=192.168.0.1
+       leftcert=moonCert.pem
+       leftsubnet=10.1.0.0/16
+       right=192.168.0.2
+       rightcert=sunCert.pem
+       rightsubnet=10.2.0.0/16
+       keyexchange=ikev2
+       auto=add
diff --git a/testing/tests/ikev2-net2net/hosts/moon/etc/ipsec.d/certs/sunCert.pem b/testing/tests/ikev2-net2net/hosts/moon/etc/ipsec.d/certs/sunCert.pem
new file mode 100644 (file)
index 0000000..e7825e3
--- /dev/null
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIECzCCAvOgAwIBAgIBAjANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
+b290IENBMB4XDTA0MDkxMDExMTU1M1oXDTA5MDkwOTExMTU1M1owRTELMAkGA1UE
+BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMTEnN1bi5z
+dHJvbmdzd2FuLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOQ8
+foB9h5BZ92gA5JkQTJNuoF6FAzoq91Gh7To27/g74p01+SUnsSaBfPmNfGp4avdS
+Ewy2dWMA/7uj0Dbe8MEKssNztp0JQubp2s7n8mrrQLGsqB6YAS09l75XDjS3yqTC
+AtH1kD4zAl/j/AyeQBuLR4CyJEmC/rqD3/a+pr42CaljuFBgBRpCTUpU4mlslZSe
+zv9wu61PwTFxb8VDlBHUd/lwkXThKgU3uEhWRxLahpSldEGmiTTmx30k/XbOMF2n
+HObEHt5EY9uWRGGbj81ZRWiNk0dNtbpneUHv/NvdWLc591M8cEGEQdWW2XTVbL2G
+N67q8hdzGgIvb7QJPMcCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAwCwYDVR0PBAQD
+AgOoMB0GA1UdDgQWBBQ9xLkyCBbyQmRet0vvV1Fg6z5q2DBtBgNVHSMEZjBkgBRd
+p91wBlEyfue2bbO15eBg6i5N76FJpEcwRTELMAkGA1UEBhMCQ0gxGTAXBgNVBAoT
+EExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMTEnN0cm9uZ1N3YW4gUm9vdCBDQYIB
+ADAdBgNVHREEFjAUghJzdW4uc3Ryb25nc3dhbi5vcmcwOQYDVR0fBDIwMDAuoCyg
+KoYoaHR0cDovL2NybC5zdHJvbmdzd2FuLm9yZy9zdHJvbmdzd2FuLmNybDANBgkq
+hkiG9w0BAQQFAAOCAQEAGQQroiAa0SwwhJprGd7OM+rfBJAGbsa3DPzFCfHX1R7i
+ZyDs9aph1DK+IgUa377Ev1U7oB0EldpmOoJJugCjtNLfpW3t1RXBERL/QfpO2+VP
+Wt3SfZ0Oq48jiqB1MVLMZRPCICZEQjT4sJ3HYs5ZuucuvoxeMx3rQ4HxUtHtMD3S
+5JNMwFFiOXAjyIyrTlb7YuRJTT5hE+Rms8GUQ5Xnt7zKZ7yfoSLFzy0/cLFPdQvE
+JA7w8crODCZpDgEKVHVyUWuyt1O46N3ydUfDcnKJoQ9HWHm3xCbDex5MHTnvm1lk
+Stx71CGM7TE6VPy028UlrSw0JqEwCVwstei2cMzwgA==
+-----END CERTIFICATE-----
diff --git a/testing/tests/ikev2-net2net/hosts/sun/etc/ipsec.conf b/testing/tests/ikev2-net2net/hosts/sun/etc/ipsec.conf
new file mode 100644 (file)
index 0000000..b2c2b71
--- /dev/null
@@ -0,0 +1,13 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+version        2.0     # conforms to second version of ipsec.conf specification
+
+conn net-net 
+       left=192.168.0.2
+       leftcert=sunCert.pem
+       leftsubnet=10.2.0.0/16
+       right=192.168.0.1
+       rightcert=moonCert.pem
+       rightsubnet=10.1.0.0/16
+       keyexchange=ikev2
+       auto=add
diff --git a/testing/tests/ikev2-net2net/hosts/sun/etc/ipsec.d/certs/moonCert.pem b/testing/tests/ikev2-net2net/hosts/sun/etc/ipsec.d/certs/moonCert.pem
new file mode 100644 (file)
index 0000000..d8fbfa1
--- /dev/null
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIEDTCCAvWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
+b290IENBMB4XDTA0MDkxMDExMTcyNVoXDTA5MDkwOTExMTcyNVowRjELMAkGA1UE
+BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xHDAaBgNVBAMTE21vb24u
+c3Ryb25nc3dhbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv
+ri4QmsCnG0N7bxqeUZTQhcmZ/iyN4RsmHwFsiOc06xpnZ7Fbx9gzi/OswU6KGL+F
+f9PfvOY36bDTZU8V2QaL30RQUXz3JlG+jUyP9zjqlhsvVYS/cImvqgo3uUkQ0YCD
+v2SafTlaQfBOaPFElNEP/H2YSiyB6X80IcHsOMYpskVqPY8785FehjF+pxuyRCK+
+9HXmd+iWdnC09u4qgKRa3L0IamU3q1/BK/afkHK2IAIN4YgM7GzepHVD0f7Exf9U
+esJEeh4hDZwSjcMzdybrY9XBxzGqLGPOF128jr+5weUZiBW+RzeBw/gsK1nSPeuX
+Od2lPJjTGj+6V3YK6qibAgMBAAGjggEFMIIBATAJBgNVHRMEAjAAMAsGA1UdDwQE
+AwIDqDAdBgNVHQ4EFgQU5eQQh2wqxL6thUlCpt52WDA6n8EwbQYDVR0jBGYwZIAU
+XafdcAZRMn7ntm2zteXgYOouTe+hSaRHMEUxCzAJBgNVBAYTAkNIMRkwFwYDVQQK
+ExBMaW51eCBzdHJvbmdTd2FuMRswGQYDVQQDExJzdHJvbmdTd2FuIFJvb3QgQ0GC
+AQAwHgYDVR0RBBcwFYITbW9vbi5zdHJvbmdzd2FuLm9yZzA5BgNVHR8EMjAwMC6g
+LKAqhihodHRwOi8vY3JsLnN0cm9uZ3N3YW4ub3JnL3N0cm9uZ3N3YW4uY3JsMA0G
+CSqGSIb3DQEBBAUAA4IBAQAvLykhZnqldrsMcbYB36WzWKk+hOihr5dU3fv8Z4ec
+tsa3gzxXSefDCxGoezVJ4QXdpdNxxFn31A+r1gxKyGI5JL6EyWz6Y462zp9lE7nW
+EIC4ldJwxAXqzDEMcJphO29hApyU9TWsWDa4kL5AKtLFLwH3/Uv/jAzAy+qXIO8h
+wLtB+wcmhSo8OFY9kX/cyhht7eb7yD/r2e3wVBOCRk7jePe4yWhN8NJAKwfrEd1K
+iGq15ymdmeomhplHRsLZwA2VsCspUNZ/eXjG21s3nEoxcCOcQUz3Q7q4ZgBTZoCW
+kAc6FQ5zxoZrmzNWFqzb06jmUVlt7baGtdjT7rEt+dcp
+-----END CERTIFICATE-----
diff --git a/testing/tests/ikev2-net2net/posttest.dat b/testing/tests/ikev2-net2net/posttest.dat
new file mode 100644 (file)
index 0000000..63c76ec
--- /dev/null
@@ -0,0 +1,4 @@
+moon::ipsec stop
+sun::ipsec stop
+moon::rm /etc/ipsec.d/certs/*
+sun::rm /etc/ipsec.d/certs/*
diff --git a/testing/tests/ikev2-net2net/pretest.dat b/testing/tests/ikev2-net2net/pretest.dat
new file mode 100644 (file)
index 0000000..33f8388
--- /dev/null
@@ -0,0 +1,7 @@
+moon::echo 1 > /proc/sys/net/ipv4/ip_forward
+sun::echo 1 > /proc/sys/net/ipv4/ip_forward
+moon::ipsec start
+sun::ipsec start
+moon::sleep 1 
+moon::ipsec up net-net
+moon::sleep 1
diff --git a/testing/tests/ikev2-net2net/test.conf b/testing/tests/ikev2-net2net/test.conf
new file mode 100644 (file)
index 0000000..d9a6159
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon winnetou sun bob"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-w-s-b.png"
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="sun"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon sun"