]> git.ipfire.org Git - people/ms/strongswan.git/commitdiff
- added separate implementation for connection_store, credential_store, policy_store
authorMartin Willi <martin@strongswan.org>
Tue, 25 Apr 2006 10:06:30 +0000 (10:06 -0000)
committerMartin Willi <martin@strongswan.org>
Tue, 25 Apr 2006 10:06:30 +0000 (10:06 -0000)
- added folder structure to config
- credentials are fetched solely on IDs now

36 files changed:
Source/Makefile
Source/charon/config/Makefile.config
Source/charon/config/connections/Makefile.connections [new file with mode: 0644]
Source/charon/config/connections/connection.c [moved from Source/charon/config/connection.c with 100% similarity]
Source/charon/config/connections/connection.h [moved from Source/charon/config/connection.h with 100% similarity]
Source/charon/config/connections/connection_store.h [moved from Source/charon/config/connection_store.h with 82% similarity]
Source/charon/config/connections/local_connection_store.c [new file with mode: 0644]
Source/charon/config/connections/local_connection_store.h [new file with mode: 0644]
Source/charon/config/credentials/Makefile.credentials [new file with mode: 0644]
Source/charon/config/credentials/credential_store.h [moved from Source/charon/config/credential_store.h with 79% similarity]
Source/charon/config/credentials/local_credential_store.c [new file with mode: 0644]
Source/charon/config/credentials/local_credential_store.h [new file with mode: 0644]
Source/charon/config/policies/Makefile.policies [new file with mode: 0644]
Source/charon/config/policies/local_policy_store.c [new file with mode: 0644]
Source/charon/config/policies/local_policy_store.h [new file with mode: 0644]
Source/charon/config/policies/policy.c [moved from Source/charon/config/policy.c with 100% similarity]
Source/charon/config/policies/policy.h [moved from Source/charon/config/policy.h with 100% similarity]
Source/charon/config/policies/policy_store.h [moved from Source/charon/config/policy_store.h with 84% similarity]
Source/charon/daemon.c
Source/charon/daemon.h
Source/charon/encoding/payloads/auth_payload.h
Source/charon/queues/jobs/initiate_ike_sa_job.h
Source/charon/sa/authenticator.c
Source/charon/sa/ike_sa.c
Source/charon/sa/ike_sa.h
Source/charon/threads/stroke_interface.c
Source/charon/threads/stroke_interface.h
Source/doc/Todo-list.txt
Source/lib/crypto/rsa/rsa_private_key.c
Source/lib/crypto/x509.c
Source/lib/utils/logger.c
Source/scripts/to-alice.sh
Source/scripts/to-bob.sh
Source/stroke/stroke.c
Source/testing/connection_test.c
Source/testing/policy_test.c

index 3e6d71c7d5532250fdf67b4a65c1878f3ac263b4..d1aff1e073ba2a2d037e50c18bf42e1c2572eeb5 100644 (file)
@@ -16,8 +16,14 @@ FREESWANSRCDIR=../..
 # include strongswan Makefile, if charon sits in its tree
 ifeq ($(shell ls $(FREESWANSRCDIR)/Makefile.inc 2>&1), ../../Makefile.inc)
   include ${FREESWANSRCDIR}/Makefile.inc
+else
+  # use leak detective by default
+  USE_LEAK_DETECTIVE?=true
 endif
 
+
+
+
 BUILD_DIR= ./bin/
 
 BINNAMECHARON= $(BUILD_DIR)charon
@@ -27,8 +33,10 @@ BINNAMELIB=  $(BUILD_DIR)libstrongswan.so
 
 MAIN_DIR= ./
 
-CFLAGS= -Icharon -Ilib -Istroke -fPIC -Wall -g -DLEAK_DETECTIVE
-#CFLAGS= -Icharon -Ilib -Istroke -fPIC -O3
+CFLAGS= -Icharon -Ilib -Istroke -fPIC -Wall -g
+ifeq ($(USE_LEAK_DETECTIVE),true)
+  CFLAGS+= -DLEAK_DETECTIVE
+endif
 
 # objects is extended by each included Makefile
 CHARON_OBJS=
index c95bccb8dfbc9ed1f45c9e79656fbdc0a55d7ead..d4638b31892c432f3df045d76991a34d78036b09 100644 (file)
 CONFIG_DIR= $(CHARON_DIR)config/
 
 
-                                               
-CHARON_OBJS+= $(BUILD_DIR)connection.o
-$(BUILD_DIR)connection.o :                                     $(CONFIG_DIR)connection.c $(CONFIG_DIR)connection.h
-                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
-                                                                                       
-CHARON_OBJS+= $(BUILD_DIR)policy.o
-$(BUILD_DIR)policy.o :                                         $(CONFIG_DIR)policy.c $(CONFIG_DIR)policy.h
-                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
-
 CHARON_OBJS+= $(BUILD_DIR)traffic_selector.o
 $(BUILD_DIR)traffic_selector.o :                       $(CONFIG_DIR)traffic_selector.c $(CONFIG_DIR)traffic_selector.h
                                                                                        $(CC) $(CFLAGS) -c -o $@ $<
@@ -34,4 +25,8 @@ $(BUILD_DIR)proposal.o :                                      $(CONFIG_DIR)proposal.c $(CONFIG_DIR)proposal.h
 
 CHARON_OBJS+= $(BUILD_DIR)configuration.o
 $(BUILD_DIR)configuration.o :                          $(CONFIG_DIR)configuration.c $(CONFIG_DIR)configuration.h
-                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
\ No newline at end of file
+                                                                                       $(CC) $(CFLAGS) -c -o $@ $<
+
+include $(CONFIG_DIR)connections/Makefile.connections
+include $(CONFIG_DIR)credentials/Makefile.credentials
+include $(CONFIG_DIR)policies/Makefile.policies
\ No newline at end of file
diff --git a/Source/charon/config/connections/Makefile.connections b/Source/charon/config/connections/Makefile.connections
new file mode 100644 (file)
index 0000000..8fbc983
--- /dev/null
@@ -0,0 +1,24 @@
+# Copyright (C) 2006 Martin Willi
+# Hochschule fuer Technik Rapperswil
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# 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.
+#
+
+CONNECTIONS_DIR= $(CONFIG_DIR)connections/
+
+
+CHARON_OBJS+= $(BUILD_DIR)connection.o
+$(BUILD_DIR)connection.o :                             $(CONNECTIONS_DIR)connection.c $(CONNECTIONS_DIR)connection.h
+                                                                               $(CC) $(CFLAGS) -c -o $@ $<
+
+CHARON_OBJS+= $(BUILD_DIR)local_connection_store.o
+$(BUILD_DIR)local_connection_store.o : $(CONNECTIONS_DIR)local_connection_store.c $(CONNECTIONS_DIR)local_connection_store.h
+                                                                               $(CC) $(CFLAGS) -c -o $@ $<
\ No newline at end of file
similarity index 82%
rename from Source/charon/config/connection_store.h
rename to Source/charon/config/connections/connection_store.h
index 8b80c0fea13bd039d129717e80242843b459656c..f1814a00d25b75dc4324e323bd5a4bef7cba368d 100755 (executable)
@@ -24,7 +24,7 @@
 #define CONNECTION_STORE_H_
 
 #include <types.h>
-#include <config/connection.h>
+#include <config/connections/connection.h>
 
 
 typedef struct connection_store_t connection_store_t;
@@ -33,17 +33,17 @@ typedef struct connection_store_t connection_store_t;
  * @brief The interface for a store of connection_t's.
  * 
  * @b Constructors:
- *     - stroke_create()
+ *     - stroke_create()
  * 
  * @ingroup config
  */
-struct connection_store_t { 
+struct connection_store_t {
 
        /**
         * @brief Returns a connection definition identified by two IDs.
         * 
-        * This call is usefull to get a connection identified by addresses.
-        * It may be used after kernel request for traffic protection.
+        * This call is useful to get a connection which is identified by IDs
+        * rather than addresses, e.g. for connection setup on user request.
         * The returned connection gets created/cloned and therefore must
         * be destroyed after usage.
         * 
@@ -59,8 +59,8 @@ struct connection_store_t {
        /**
         * @brief Returns a connection definition identified by two hosts.
         * 
-        * This call is useful to get a connection which is identified by IDs
-        * rather than addresses, e.g. for connection setup on user request.
+        * This call is usefull to get a connection identified by addresses.
+        * It may be used after kernel request for traffic protection.
         * The returned connection gets created/cloned and therefore must
         * be destroyed after usage.
         * 
@@ -73,6 +73,20 @@ struct connection_store_t {
         */
        connection_t *(*get_connection_by_hosts) (connection_store_t *this, host_t *my_host, host_t *other_host);
 
+       /**
+        * @brief Add a connection to the store.
+        * 
+        * After a successful call, the connection is owned by the store and may 
+        * not be manipulated nor destroyed.
+        * 
+        * @param this                          calling object
+        * @param connection            connection to add
+        * @return
+        *                                                      - SUCCESS, or
+        *                                                      - FAILED
+        */
+       status_t (*add_connection) (connection_store_t *this, connection_t *connection);
+       
        /**
         * @brief Destroys a connection_store_t object.
         * 
@@ -81,4 +95,4 @@ struct connection_store_t {
        void (*destroy) (connection_store_t *this);
 };
 
-#endif /*CONNECTION_STORE_H_*/
+#endif /* CONNECTION_STORE_H_ */
diff --git a/Source/charon/config/connections/local_connection_store.c b/Source/charon/config/connections/local_connection_store.c
new file mode 100644 (file)
index 0000000..3eee2ba
--- /dev/null
@@ -0,0 +1,202 @@
+/**
+ * @file local_connection_store.c
+ * 
+ * @brief Implementation of local_connection_store_t.
+ *  
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * 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 "local_connection_store.h"
+
+#include <utils/linked_list.h>
+#include <utils/logger_manager.h>
+
+
+typedef struct private_local_connection_store_t private_local_connection_store_t;
+
+/**
+ * Private data of an local_connection_store_t object
+ */
+struct private_local_connection_store_t {
+
+       /**
+        * Public part
+        */
+       local_connection_store_t public;
+       
+       /**
+        * stored connection
+        */
+       linked_list_t *connections;
+       
+       /**
+        * Assigned logger
+        */
+       logger_t *logger;
+};
+
+
+/**
+ * Implementation of connection_store_t.get_connection_by_hosts.
+ */
+static connection_t *get_connection_by_hosts(private_local_connection_store_t *this, host_t *my_host, host_t *other_host)
+{
+       iterator_t *iterator;
+       connection_t *current, *found = NULL;
+       
+       this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for hosts %s - %s", 
+                                         my_host->get_address(my_host), other_host->get_address(other_host));
+       
+       iterator = this->connections->create_iterator(this->connections, TRUE);
+       while (iterator->has_next(iterator))
+       {
+               host_t *config_my_host, *config_other_host;
+               
+               iterator->current(iterator, (void**)&current);
+
+               config_my_host = current->get_my_host(current);
+               config_other_host = current->get_other_host(current);
+
+               /* first check if ip is equal */
+               if(config_other_host->ip_equals(config_other_host, other_host))
+               {
+                       this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote host %s", 
+                                                         config_other_host->get_address(config_other_host));
+                       /* could be right one, check my_host for default route*/
+                       if (config_my_host->is_default_route(config_my_host))
+                       {
+                               found = current->clone(current);
+                               break;
+                       }
+                       /* check now if host informations are the same */
+                       else if (config_my_host->ip_equals(config_my_host,my_host))
+                       {
+                               found = current->clone(current);
+                               break;
+                       }
+                       
+               }
+               /* Then check for wildcard hosts!
+               * TODO
+               * actually its only checked if other host with default route can be found! */
+               else if (config_other_host->is_default_route(config_other_host))
+               {
+                       /* could be right one, check my_host for default route*/
+                       if (config_my_host->is_default_route(config_my_host))
+                       {
+                               found = current->clone(current);
+                               break;
+                       }
+                       /* check now if host informations are the same */
+                       else if (config_my_host->ip_equals(config_my_host,my_host))
+                       {
+                               found = current->clone(current);
+                               break;
+                       }
+               }
+       }
+       iterator->destroy(iterator);
+       
+       /* apply hosts as they are supplied since my_host may be %defaultroute, and other_host may be %any. */
+       if (found)
+       {
+               found->update_my_host(found, my_host->clone(my_host));
+               found->update_other_host(found, other_host->clone(other_host));
+       }
+       
+       return found;
+}
+
+/**
+ * Implementation of connection_store_t.get_connection_by_ids.
+ */
+static connection_t *get_connection_by_ids(private_local_connection_store_t *this, identification_t *my_id, identification_t *other_id)
+{
+       iterator_t *iterator;
+       connection_t *current, *found = NULL;
+       
+       this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for ids %s - %s", 
+                                         my_id->get_string(my_id), other_id->get_string(other_id));
+       
+       iterator = this->connections->create_iterator(this->connections, TRUE);
+       while (iterator->has_next(iterator))
+       {
+               identification_t *config_my_id, *config_other_id;
+               
+               iterator->current(iterator, (void**)&current);
+               
+               config_my_id = current->get_my_id(current);
+               config_other_id = current->get_other_id(current);
+               
+               /* first check if ids are equal 
+               * TODO: Add wildcard checks */
+               if (config_other_id->equals(config_other_id, other_id) &&
+                       config_my_id->equals(config_my_id, my_id))
+               {
+                       this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote id %s", 
+                                                         config_other_id->get_string(config_other_id));
+                       found = current->clone(current);
+                       break;
+               }
+       }
+       iterator->destroy(iterator);
+       
+       return found;
+}
+
+/**
+ * Implementation of connection_store_t.add_connection.
+ */
+status_t add_connection(private_local_connection_store_t *this, connection_t *connection)
+{
+       this->connections->insert_last(this->connections, connection);
+       return SUCCESS;
+}
+
+/**
+ * Implementation of connection_store_t.destroy.
+ */
+static void destroy (private_local_connection_store_t *this)
+{
+       connection_t *connection;
+       
+       while (this->connections->remove_last(this->connections, (void**)&connection) == SUCCESS)
+       {
+               connection->destroy(connection);
+       }
+       this->connections->destroy(this->connections);
+       free(this);
+}
+
+/**
+ * Described in header.
+ */
+local_connection_store_t * local_connection_store_create()
+{
+       private_local_connection_store_t *this = malloc_thing(private_local_connection_store_t);
+
+       this->public.connection_store.get_connection_by_hosts = (connection_t*(*)(connection_store_t*,host_t*,host_t*))get_connection_by_hosts;
+       this->public.connection_store.get_connection_by_ids = (connection_t*(*)(connection_store_t*,identification_t*,identification_t*))get_connection_by_ids;
+       this->public.connection_store.add_connection = (status_t(*)(connection_store_t*,connection_t*))add_connection;
+       this->public.connection_store.destroy = (void(*)(connection_store_t*))destroy;
+       
+       /* private variables */
+       this->connections = linked_list_create();
+       this->logger = logger_manager->get_logger(logger_manager, CONFIG);
+
+       return (&this->public);
+}
diff --git a/Source/charon/config/connections/local_connection_store.h b/Source/charon/config/connections/local_connection_store.h
new file mode 100644 (file)
index 0000000..14a0a24
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * @file local_connection_store.h
+ * 
+ * @brief Interface of local_connection_store_t.
+ *  
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * 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.
+ */
+#ifndef LOCAL_CONNECTION_H_
+#define LOCAL_CONNECTION_H_
+
+#include <types.h>
+#include <config/connections/connection_store.h>
+
+
+typedef struct local_connection_store_t local_connection_store_t;
+
+/**
+ * @brief A connection_store_t implementation using a simple connection list.
+ *
+ * The local_connection_store_t class implements the connection_store_t interface
+ * as simple as possible. connection_t's are stored in an in-memory list.
+ *
+ * @b Constructors:
+ *  - local_connection_store_create()
+ *
+ * @todo Make thread-save first
+ * @todo Add remove_connection method
+ *
+ * @ingroup config
+ */
+struct local_connection_store_t {
+       
+       /**
+        * Implements connection_store_t interface
+        */
+       connection_store_t connection_store;
+};
+
+/**
+ * @brief Creates a local_connection_store_t instance.
+ *
+ * @return connection store instance.
+ * 
+ * @ingroup config
+ */
+local_connection_store_t * local_connection_store_create();
+
+#endif /* LOCAL_CONNECTION_H_ */
diff --git a/Source/charon/config/credentials/Makefile.credentials b/Source/charon/config/credentials/Makefile.credentials
new file mode 100644 (file)
index 0000000..720d566
--- /dev/null
@@ -0,0 +1,20 @@
+# Copyright (C) 2006 Martin Willi
+# Hochschule fuer Technik Rapperswil
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# 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.
+#
+
+CREDENTIALS_DIR= $(CONFIG_DIR)credentials/
+
+
+CHARON_OBJS+= $(BUILD_DIR)local_credential_store.o
+$(BUILD_DIR)local_credential_store.o : $(CREDENTIALS_DIR)local_credential_store.c $(CREDENTIALS_DIR)local_credential_store.h
+                                                                               $(CC) $(CFLAGS) -c -o $@ $<
similarity index 79%
rename from Source/charon/config/credential_store.h
rename to Source/charon/config/credentials/credential_store.h
index 27f1a287d12dd66d11baec42bce79e39c482dc5a..2339469c04d6de45de6849b46f56ac014b88de97 100755 (executable)
@@ -26,6 +26,7 @@
 #include <types.h>
 #include <crypto/rsa/rsa_private_key.h>
 #include <crypto/rsa/rsa_public_key.h>
+#include <utils/identification.h>
 
 
 typedef struct credential_store_t credential_store_t;
@@ -48,10 +49,12 @@ struct credential_store_t {
         * @param this                                  calling object
         * @param identification                identification_t object identifiying the secret.
         * @param[out] preshared_secret the preshared secret will be written there.
-        * 
-        * @return              
+        * @return
         *                                                              - NOT_FOUND     if no preshared secrets for specific ID could be found
         *                                                              - SUCCESS
+        *
+        * @todo We should use two IDs to query shared secrets, since we want to use different
+        * keys for different peers...
         */     
        status_t (*get_shared_secret) (credential_store_t *this, identification_t *identification, chunk_t *preshared_secret);
        
@@ -62,13 +65,9 @@ struct credential_store_t {
         * 
         * @param this                                  calling object
         * @param identification                identification_t object identifiying the key.
-        * @param[out] public_key               the public key will be written there
-        * 
-        * @return              
-        *                                                              - NOT_FOUND     if no key is configured for specific id
-        *                                                              - SUCCESS
-        */     
-       status_t (*get_rsa_public_key) (credential_store_t *this, identification_t *identification, rsa_public_key_t **public_key);
+        * @return                                              public key, or NULL if not found
+        */
+       rsa_public_key_t * (*get_rsa_public_key) (credential_store_t *this, identification_t *identification);
        
        /**
         * @brief Returns the RSA private key of a specific ID.
@@ -77,13 +76,9 @@ struct credential_store_t {
         * 
         * @param this                                  calling object
         * @param identification                identification_t object identifiying the key
-        * @param[out] private_key              the private key will be written there
-        * 
-        * @return              
-        *                                                              - NOT_FOUND     if no key is configured for specific id
-        *                                                              - SUCCESS
+        * @return                                              private key, or NULL if not found
         */     
-       status_t (*get_rsa_private_key) (credential_store_t *this, identification_t *identification, rsa_private_key_t **private_key);
+       rsa_private_key_t *(*get_rsa_private_key) (credential_store_t *this, identification_t *identification);
 
        /**
         * @brief Destroys a credential_store_t object.
diff --git a/Source/charon/config/credentials/local_credential_store.c b/Source/charon/config/credentials/local_credential_store.c
new file mode 100644 (file)
index 0000000..dc6cb6c
--- /dev/null
@@ -0,0 +1,315 @@
+/**
+ * @file local_credential_store.c
+ * 
+ * @brief Implementation of local_credential_store_t.
+ *  
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * 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 <sys/stat.h>
+#include <dirent.h>
+
+#include "local_credential_store.h"
+
+#include <utils/linked_list.h>
+#include <utils/logger_manager.h>
+#include <crypto/x509.h>
+
+
+typedef struct key_entry_t key_entry_t;
+
+/**
+ * Private key with an associated ID to find it
+ */
+struct key_entry_t {
+       
+       /**
+        * ID, as added
+        */
+       identification_t *id;
+       
+       /**
+        * Associated rsa private key
+        */
+       rsa_private_key_t *key;
+};
+
+
+typedef struct private_local_credential_store_t private_local_credential_store_t;
+
+/**
+ * Private data of an local_credential_store_t object
+ */
+struct private_local_credential_store_t {
+
+       /**
+        * Public part
+        */
+       local_credential_store_t public;
+       
+       /**
+        * list of key_entry_t's with private keys
+        */
+       linked_list_t *private_keys;
+       
+       /**
+        * list of x509 certificates with public keys
+        */
+       linked_list_t *certificates;
+       
+       /**
+        * Assigned logger
+        */
+       logger_t *logger;
+};
+
+
+/**
+ * Implementation of credential_store_t.get_shared_secret.
+ */    
+static status_t get_shared_secret(private_local_credential_store_t *this, identification_t *identification, chunk_t *preshared_secret)
+{
+       return FAILED;
+}
+
+/**
+ * Implementation of credential_store_t.get_rsa_public_key.
+ */
+static rsa_public_key_t * get_rsa_public_key(private_local_credential_store_t *this, identification_t *identification)
+{
+       x509_t *current;
+       rsa_public_key_t *found = NULL;
+       iterator_t *iterator;
+       
+       this->logger->log(this->logger, CONTROL|LEVEL2, "Looking for public key for %s",
+                                         identification->get_string(identification));
+       iterator = this->certificates->create_iterator(this->certificates, TRUE);
+       while (iterator->has_next(iterator))
+       {
+               iterator->current(iterator, (void**)&current);
+               identification_t *stored = current->get_subject(current);
+               this->logger->log(this->logger, CONTROL|LEVEL2, "there is one for %s",
+                                                 stored->get_string(stored));
+               if (identification->equals(identification, stored))
+               {
+                       found = current->get_public_key(current);
+                       break;
+               }
+       }
+       iterator->destroy(iterator);
+       return found;
+}
+
+/**
+ * Implementation of credential_store_t.get_rsa_private_key.
+ */
+static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t *this, identification_t *identification)
+{
+       rsa_private_key_t *found = NULL;
+       key_entry_t *current;
+       iterator_t *iterator;
+       
+       iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
+       while (iterator->has_next(iterator))
+       {
+               iterator->current(iterator, (void**)&current);
+               if (identification->equals(identification, current->id))
+               {
+                       found = current->key->clone(current->key);
+                       break;
+               }
+       }
+       iterator->destroy(iterator);
+       return found;
+}
+
+/**
+ * Implements local_credential_store_t.load_private_keys
+ */
+static void load_certificates(private_local_credential_store_t *this, char *path)
+{
+       struct dirent* entry;
+       struct stat stb;
+       DIR* dir;
+       x509_t *cert;
+       
+       dir = opendir(path);
+       if (dir == NULL) {
+               this->logger->log(this->logger, ERROR, "error opening certificate directory \"%s\"", path);
+               return;
+       }
+       while ((entry = readdir(dir)) != NULL)
+       {
+               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)
+               {
+                       cert = x509_create_from_file(file);
+                       if (cert)
+                       {
+                               this->certificates->insert_last(this->certificates, (void*)cert);
+                               this->logger->log(this->logger, CONTROL|LEVEL1, "loaded certificate \"%s\"", file);
+                       }
+                       else
+                       {
+                               this->logger->log(this->logger, ERROR, "certificate \"%s\" invalid, skipped", file);
+                       }
+               }
+       }
+       closedir(dir);
+}
+
+/**
+ * Query the ID for a private key, by doing a lookup in the certificates
+ */
+static identification_t *get_id_for_private_key(private_local_credential_store_t *this, rsa_private_key_t *private_key)
+{
+       iterator_t *iterator;
+       x509_t *cert;
+       identification_t *found = NULL;
+       rsa_public_key_t *public_key;
+       
+       this->logger->log(this->logger, CONTROL|LEVEL2, "Getting ID for a private key...");
+       
+       iterator = this->certificates->create_iterator(this->certificates, TRUE);
+       while (!found && iterator->has_next(iterator))
+       {
+               iterator->current(iterator, (void**)&cert);
+               public_key = cert->get_public_key(cert);
+               if (public_key)
+               {
+                       if (private_key->belongs_to(private_key, public_key))
+                       {
+                               this->logger->log(this->logger, CONTROL|LEVEL2, "found a match");
+                               found = cert->get_subject(cert);
+                               found = found->clone(found);
+                       }
+                       else
+                       {
+                               this->logger->log(this->logger, CONTROL|LEVEL3, "this one did not match");
+                       }
+                       public_key->destroy(public_key);
+               }
+       }
+       iterator->destroy(iterator);
+       return found;
+}
+
+/**
+ * Implements local_credential_store_t.load_private_keys
+ */
+static void load_private_keys(private_local_credential_store_t *this, char *path)
+{
+       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)
+       {
+               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)
+               {
+                       key = rsa_private_key_create_from_file(file, 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", file);
+                                       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);
+                               this->logger->log(this->logger, CONTROL|LEVEL1, "loaded private key \"%s\"", file);
+                       }
+                       else
+                       {
+                               this->logger->log(this->logger, ERROR, "private key \"%s\" invalid, skipped", file);
+                       }
+               }
+       }
+       closedir(dir);
+}
+
+/**
+ * Implementation of credential_store_t.destroy.
+ */
+static void destroy(private_local_credential_store_t *this)
+{
+       x509_t *certificate;
+       key_entry_t *key_entry;
+       
+       while (this->certificates->remove_last(this->certificates, (void**)&certificate) == SUCCESS)
+       {
+               certificate->destroy(certificate);
+       }
+       this->certificates->destroy(this->certificates);
+       while (this->private_keys->remove_last(this->private_keys, (void**)&key_entry) == SUCCESS)
+       {
+               key_entry->id->destroy(key_entry->id);
+               key_entry->key->destroy(key_entry->key);
+               free(key_entry);
+       }
+       this->private_keys->destroy(this->private_keys);
+       free(this);
+}
+
+/**
+ * Described in header.
+ */
+local_credential_store_t * local_credential_store_create()
+{
+       private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
+
+       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.credential_store.destroy = (void(*)(credential_store_t*))destroy;
+       
+       /* private variables */
+       this->private_keys = linked_list_create();
+       this->certificates = linked_list_create();
+       this->logger = logger_manager->get_logger(logger_manager, CONFIG);
+
+       return (&this->public);
+}
diff --git a/Source/charon/config/credentials/local_credential_store.h b/Source/charon/config/credentials/local_credential_store.h
new file mode 100644 (file)
index 0000000..ab9ef88
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * @file local_credential_store.h
+ *
+ * @brief Interface of local_credential_store_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * 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.
+ */
+#ifndef LOCAL_CREDENTIAL_H_
+#define LOCAL_CREDENTIAL_H_
+
+#include <types.h>
+#include <config/credentials/credential_store.h>
+
+
+typedef struct local_credential_store_t local_credential_store_t;
+
+/**
+ * @brief A credential_store_t implementation using simple credentail lists.
+ *
+ * The local_credential_store_t class implements the credential_store_t interface
+ * as simple as possible. The credentials are stored in lists, and can be loaded
+ * from folders.
+ * Shared secret are not handled yet, so get_shared_secret always returns NOT_FOUND.
+ *
+ * @b Constructors:
+ *  - local_credential_store_create()
+ * 
+ * @ingroup config
+ */
+struct local_credential_store_t {
+       
+       /**
+        * Implements credential_store_t interface
+        */
+       credential_store_t credential_store;
+       
+       /**
+        * @brief Loads trusted certificates from a folder.
+        *
+        * Currently, all keys must be in binary DER format.
+        *
+        * @param this          calling object
+        * @param path          directory to load certificates from
+        */
+       void (*load_certificates) (local_credential_store_t *this, char *path);
+       
+       /**
+        * @brief Loads RSA private keys from a folder.
+        * 
+        * Currently, all keys must be unencrypted in binary DER format. Anything
+        * 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
+        */
+       void (*load_private_keys) (local_credential_store_t *this, char *path);
+};
+
+/**
+ * @brief Creates a local_credential_store_t instance.
+ *
+ * @return credential store instance.
+ * 
+ * @ingroup config
+ */
+local_credential_store_t *local_credential_store_create();
+
+#endif /* LOCAL_CREDENTIAL_H_ */
diff --git a/Source/charon/config/policies/Makefile.policies b/Source/charon/config/policies/Makefile.policies
new file mode 100644 (file)
index 0000000..e7ed8ab
--- /dev/null
@@ -0,0 +1,24 @@
+# Copyright (C) 2006 Martin Willi
+# Hochschule fuer Technik Rapperswil
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# 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.
+#
+
+POLICIES_DIR= $(CONFIG_DIR)policies/
+
+
+CHARON_OBJS+= $(BUILD_DIR)policy.o
+$(BUILD_DIR)policy.o :                                 $(POLICIES_DIR)policy.c $(POLICIES_DIR)policy.h
+                                                                               $(CC) $(CFLAGS) -c -o $@ $<
+
+CHARON_OBJS+= $(BUILD_DIR)local_policy_store.o
+$(BUILD_DIR)local_policy_store.o :             $(POLICIES_DIR)local_policy_store.c $(POLICIES_DIR)local_policy_store.h
+                                                                               $(CC) $(CFLAGS) -c -o $@ $<
\ No newline at end of file
diff --git a/Source/charon/config/policies/local_policy_store.c b/Source/charon/config/policies/local_policy_store.c
new file mode 100644 (file)
index 0000000..a03b86a
--- /dev/null
@@ -0,0 +1,137 @@
+/**
+ * @file local_policy_store.c
+ * 
+ * @brief Implementation of local_policy_store_t.
+ *  
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * 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 "local_policy_store.h"
+
+#include <utils/linked_list.h>
+#include <utils/logger_manager.h>
+
+
+typedef struct private_local_policy_store_t private_local_policy_store_t;
+
+/**
+ * Private data of an local_policy_store_t object
+ */
+struct private_local_policy_store_t {
+
+       /**
+        * Public part
+        */
+       local_policy_store_t public;
+       
+       /**
+        * list of policy_t's
+        */
+       linked_list_t *policies;
+       
+       /**
+        * Assigned logger
+        */
+       logger_t *logger;
+};
+
+/**
+ * Implementation of policy_store_t.add_policy.
+ */
+static void add_policy(private_local_policy_store_t *this, policy_t *policy)
+{
+       this->policies->insert_last(this->policies, (void*)policy);
+}
+
+
+/**
+ * Implementation of policy_store_t.get_policy.
+ */
+static policy_t *get_policy(private_local_policy_store_t *this, identification_t *my_id, identification_t *other_id)
+{
+       iterator_t *iterator;
+       policy_t *current, *found = NULL;
+       
+       iterator = this->policies->create_iterator(this->policies, TRUE);
+       while (iterator->has_next(iterator))
+       {
+               iterator->current(iterator, (void **)&current);
+               identification_t *config_my_id = current->get_my_id(current);
+               identification_t *config_other_id = current->get_other_id(current);
+               
+               /* check other host first */
+               if (config_other_id->belongs_to(config_other_id, other_id))
+               {
+                       /* get it if my_id not specified */
+                       if (my_id == NULL)
+                       {
+                               found = current->clone(current);
+                               break;
+                       }
+                       if (config_my_id->belongs_to(config_my_id, my_id))
+                       {
+                               found = current->clone(current);
+                               break;
+                       }
+               }
+       }
+       iterator->destroy(iterator);
+       
+       /* apply IDs as they are requsted, since they may be configured as %any or such */
+       if (found)
+       {
+               if (my_id)
+               {
+                       found->update_my_id(found, my_id->clone(my_id));
+               }
+               found->update_other_id(found, other_id->clone(other_id));
+       }
+       return found;
+}
+
+/**
+ * Implementation of policy_store_t.destroy.
+ */
+static void destroy(private_local_policy_store_t *this)
+{
+       policy_t *policy;
+       
+       while (this->policies->remove_last(this->policies, (void**)&policy) == SUCCESS)
+       {
+               policy->destroy(policy);
+       }
+       this->policies->destroy(this->policies);
+       free(this);
+}
+
+/**
+ * Described in header.
+ */
+local_policy_store_t *local_policy_store_create()
+{
+       private_local_policy_store_t *this = malloc_thing(private_local_policy_store_t);
+       
+       this->public.policy_store.add_policy = (void(*)(policy_store_t*,policy_t*))add_policy;
+       this->public.policy_store.get_policy = (policy_t*(*)(policy_store_t*,identification_t*,identification_t*))get_policy;
+       this->public.policy_store.destroy = (void(*)(policy_store_t*))destroy;
+       
+       /* private variables */
+       this->policies = linked_list_create();
+       this->logger = logger_manager->get_logger(logger_manager, CONFIG);
+       
+       return (&this->public);
+}
diff --git a/Source/charon/config/policies/local_policy_store.h b/Source/charon/config/policies/local_policy_store.h
new file mode 100644 (file)
index 0000000..7ab9e0e
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * @file local_policy_store.h
+ *
+ * @brief Interface of local_policy_store_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * 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.
+ */
+#ifndef LOCAL_POLICY_STORE_H_
+#define LOCAL_POLICY_STORE_H_
+
+#include <types.h>
+#include <config/policies/policy_store.h>
+
+
+typedef struct local_policy_store_t local_policy_store_t;
+
+/**
+ * @brief A policy_store_t implementation using a simple policy lists.
+ *
+ * The local_policy_store_t class implements the policy_store_t interface
+ * as simple as possible. The policies are stored in a in-memory list.
+ *
+ * @b Constructors:
+ *  - local_policy_store_create()
+ * 
+ * @ingroup config
+ */
+struct local_policy_store_t {
+       
+       /**
+        * Implements policy_store_t interface
+        */
+       policy_store_t policy_store;
+};
+
+/**
+ * @brief Creates a local_policy_store_t instance.
+ *
+ * @return policy store instance.
+ * 
+ * @ingroup config
+ */
+local_policy_store_t *local_policy_store_create();
+
+#endif /* LOCAL_POLICY_STORE_H_ */
similarity index 84%
rename from Source/charon/config/policy_store.h
rename to Source/charon/config/policies/policy_store.h
index 467e27d1d7e9dd38097ffe5791ba00fa681c1b6e..651dea6342b7f39bc833afd50caa69b96c8b14d7 100755 (executable)
@@ -24,7 +24,7 @@
 #define POLICY_STORE_H_
 
 #include <types.h>
-#include <config/policy.h>
+#include <config/policies/policy.h>
 
 
 typedef struct policy_store_t policy_store_t;
@@ -53,6 +53,17 @@ struct policy_store_t {
         *                                      - NULL otherwise
         */
        policy_t *(*get_policy) (policy_store_t *this, identification_t *my_id, identification_t *other_id);
+
+       /**
+        * @brief Add a policy to the list.
+        * 
+        * The policy is owned by the store after the call. Do
+        * not modify nor free.
+        * 
+        * @param this          calling object
+        * @param policy        policy to add
+        */
+       void (*add_policy) (policy_store_t *this, policy_t *policy);
        
        /**
         * @brief Destroys a policy_store_t object.
index 376a09979f1c40e9e0d46bb86798edce1d102747..680519228fcf47cbe2ba81b9a659930e129f7541 100644 (file)
@@ -32,6 +32,9 @@
 #include "daemon.h" 
 
 #include <types.h>
+#include <config/connections/local_connection_store.h>
+#include <config/credentials/local_credential_store.h>
+#include <config/policies/local_policy_store.h>
 
 
 typedef struct private_daemon_t private_daemon_t;
@@ -162,17 +165,25 @@ static void kill_daemon(private_daemon_t *this, char *reason)
  */
 static void initialize(private_daemon_t *this)
 {
+       local_credential_store_t* cred_store;
+       
        this->public.configuration = configuration_create();
        this->public.socket = socket_create(IKEV2_UDP_PORT);
        this->public.ike_sa_manager = ike_sa_manager_create();
        this->public.job_queue = job_queue_create();
        this->public.event_queue = event_queue_create();
        this->public.send_queue = send_queue_create();
-       this->public.stroke = stroke_create();
-       this->public.connections = &this->public.stroke->connections;
-       this->public.policies = &this->public.stroke->policies;
-       this->public.credentials = &this->public.stroke->credentials;
+       this->public.connections = (connection_store_t*)local_connection_store_create();
+       this->public.policies = (policy_store_t*)local_policy_store_create();
+       this->public.credentials = (credential_store_t*)(cred_store = local_credential_store_create());
+       
+       /* load keys & certs */
+       cred_store->load_certificates(cred_store, CERTIFICATE_DIR);
+       cred_store->load_private_keys(cred_store, PRIVATE_KEY_DIR);
        
+       
+       /* start building threads, we are multi-threaded NOW */
+       this->public.stroke = stroke_create();
        this->public.sender = sender_create();
        this->public.receiver = receiver_create();
        this->public.scheduler = scheduler_create();
index 57372cc512f778f151874fdcf9eaadc4042881d6..037f40cc51a2666c2829c2a9420661db11e937b7 100644 (file)
@@ -36,9 +36,9 @@
 #include <queues/event_queue.h>
 #include <utils/logger_manager.h>
 #include <config/configuration.h>
-#include <config/connection_store.h>
-#include <config/policy_store.h>
-#include <config/credential_store.h>
+#include <config/connections/connection_store.h>
+#include <config/policies/policy_store.h>
+#include <config/credentials/credential_store.h>
 
 /**
  * @defgroup charon charon
  */
 #define PID_FILE "/var/run/charon.pid"
 
+/**
+ * Directory of IPsec relevant files
+ * 
+ * @ingroup charon
+ */
+#define IPSEC_DIR "/etc/ipsec.d/"
+
+/**
+ * Directory for private keys
+ * 
+ * @ingroup charon
+ */
+#define PRIVATE_KEY_DIR IPSEC_DIR "private/"
+
+/**
+ * Directory for trusted certificates
+ * 
+ * @ingroup charon
+ */
+#define CERTIFICATE_DIR IPSEC_DIR "certs/"
+
 
 typedef struct daemon_t daemon_t;
 
index 699ea2cdd01d43af2f60cee9c214cf4af700b74b..e099cdfeffd88797e8aa105c27acbe8b70c33d52 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <types.h>
 #include <encoding/payloads/payload.h>
-#include <config/connection.h>
+#include <config/connections/connection.h>
 
 /**
  * Length of a auth payload without the auth data in bytes.
index d15ddf2a98092a6a31d324bf01b39ecd87dbd7a1..cee31f07b89ae226e9c091db2fea534e8eac50c4 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <types.h>
 #include <queues/jobs/job.h>
-#include <config/connection.h>
+#include <config/connections/connection.h>
 
 
 typedef struct initiate_ike_sa_job_t initiate_ike_sa_job_t;
index 32817b0a1fc439e90f7581ce2097d518d2746914..3aeb8795fda2784c48b4e7aa3a128fe4c4a69d2a 100644 (file)
@@ -250,15 +250,14 @@ static status_t verify_auth_data (private_authenticator_t *this,
                        
                        auth_data = auth_payload->get_data(auth_payload);
                        
-                       status = charon->credentials->get_rsa_public_key(charon->credentials,
-                                                                                                                        other_id,
-                                                                                                                        &public_key);
-                       if (status != SUCCESS)
+                       public_key = charon->credentials->get_rsa_public_key(charon->credentials,
+                                                                                                                        other_id);
+                       if (public_key == NULL)
                        {
                                this->logger->log(this->logger, ERROR|LEVEL1, "No RSA public key found for %s",
                                                                  other_id->get_string(other_id));
                                other_id->destroy(other_id);
-                               return status;  
+                               return NOT_FOUND;       
                        }
                        
                        octets = this->allocate_octets(this,last_received_packet, my_nonce,other_id_payload, initiator);
@@ -338,13 +337,13 @@ static status_t compute_auth_data (private_authenticator_t *this,
                        status_t status;
                        chunk_t octets, auth_data;
                        
-                       status = charon->credentials->get_rsa_private_key(charon->credentials, my_id, &private_key);
-                       if (status != SUCCESS)
+                       private_key = charon->credentials->get_rsa_private_key(charon->credentials, my_id);
+                       if (private_key == NULL)
                        {
                                this->logger->log(this->logger, ERROR|LEVEL1, "No RSA private key found for %s",
                                                                  my_id->get_string(my_id));
                                my_id->destroy(my_id);
-                               return status;  
+                               return NOT_FOUND;       
                        }
                        my_id->destroy(my_id);
                        
index 63879f1f2b737629096b89edcdd4b7146e19681c..def0013fcf4abfcaf12622a79cf86a213dcbb36d 100644 (file)
@@ -373,6 +373,22 @@ static host_t* get_other_host(private_ike_sa_t *this)
        return this->connection->get_other_host(this->connection);;
 }
 
+/**
+ * Implementation of ike_sa_t.get_my_id.
+ */
+static identification_t* get_my_id(private_ike_sa_t *this)
+{
+       return this->connection->get_my_id(this->connection);;
+}
+
+/**
+ * Implementation of ike_sa_t.get_other_id.
+ */
+static identification_t* get_other_id(private_ike_sa_t *this)
+{
+       return this->connection->get_other_id(this->connection);;
+}
+
 /**
  * Implementation of private_ike_sa_t.resend_last_reply.
  */
@@ -1054,6 +1070,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->protected.public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id;
        this->protected.public.get_my_host = (host_t*(*)(ike_sa_t*)) get_my_host;
        this->protected.public.get_other_host = (host_t*(*)(ike_sa_t*)) get_other_host;
+       this->protected.public.get_my_id = (identification_t*(*)(ike_sa_t*)) get_my_id;
+       this->protected.public.get_other_id = (identification_t*(*)(ike_sa_t*)) get_other_id;
        this->protected.public.retransmit_request = (status_t (*) (ike_sa_t *, u_int32_t)) retransmit_request;
        this->protected.public.get_state = (ike_sa_state_t (*) (ike_sa_t *this)) get_state;
        this->protected.public.send_delete_ike_sa_request = (void (*)(ike_sa_t*)) send_delete_ike_sa_request;
index 92c73391faf64ceb9c7b8c0c69bdd89f889762e7..8b58bfe68d0af5da3bbe7ae0e7c6ceb8100f2451 100644 (file)
@@ -35,8 +35,8 @@
 #include <crypto/prfs/prf.h>
 #include <crypto/crypters/crypter.h>
 #include <crypto/signers/signer.h>
-#include <config/connection.h>
-#include <config/policy.h>
+#include <config/connections/connection.h>
+#include <config/policies/policy.h>
 
 /**
  * Nonce size in bytes for nonces sending to other peer.
@@ -136,6 +136,22 @@ struct ike_sa_t {
         * @return                              remote host_t
         */
        host_t* (*get_other_host) (ike_sa_t *this);
+
+       /**
+        * @brief Get own ID of the IKE_SA.
+        *
+        * @param this                  calling object
+        * @return                              local identification_t
+        */
+       identification_t* (*get_my_id) (ike_sa_t *this);
+
+       /**
+        * @brief Get remote ID the IKE_SA.
+        *
+        * @param this                  calling object
+        * @return                              remote identification_t
+        */
+       identification_t* (*get_other_id) (ike_sa_t *this);
        
        /**
         * @brief Get the state of type of associated state object.
index 2881cb26ad8cbeb1fa811425b854d46d039dfb8e..77c15283f975ee1fcb06f303c514844fcb4af3b2 100755 (executable)
 
 struct sockaddr_un socket_addr = { AF_UNIX, STROKE_SOCKET};
 
-typedef struct configuration_entry_t configuration_entry_t;
+typedef struct connection_entry_t connection_entry_t;
 
 /**
- * A configuration entry combines a configuration name with a connection
- * and a policy.
- * 
- * @b Constructors:
- *  - configuration_entry_create()
+ * A connection entry combines a connection name with a connection.
  */
-struct configuration_entry_t {
+struct connection_entry_t {
        
        /**
-        * Configuration name.
-        *
+        * connection name.
         */
        char *name;
        
@@ -63,64 +58,8 @@ struct configuration_entry_t {
         * Configuration for IKE_SA_INIT exchange.
         */
        connection_t *connection;
-
-       /**
-        * Configuration for all phases after IKE_SA_INIT exchange.
-        */
-       policy_t *policy;
-       
-       /**
-        * Public key of other peer
-        */
-       rsa_public_key_t *public_key;
-       
-       /**
-        * Own private key
-        */
-       rsa_private_key_t *private_key;
-       
-       /**
-        * Destroys a configuration_entry_t
-        */
-       void (*destroy) (configuration_entry_t *this);
 };
 
-/**
- * Implementation of configuration_entry_t.destroy.
- */
-static void configuration_entry_destroy (configuration_entry_t *this)
-{
-       this->connection->destroy(this->connection);
-       this->policy->destroy(this->policy);
-       if (this->public_key)
-       {
-               this->public_key->destroy(this->public_key);
-       }
-       free(this->name);
-       free(this);
-}
-
-/**
- * Creates a configuration_entry_t object.
- */
-static configuration_entry_t * configuration_entry_create(char *name, connection_t* connection, policy_t *policy, 
-                                                                                                                 rsa_private_key_t *private_key, rsa_public_key_t *public_key)
-{
-       configuration_entry_t *entry = malloc_thing(configuration_entry_t);
-
-       /* functions */
-       entry->destroy = configuration_entry_destroy;
-
-       /* private data */
-       entry->connection = connection;
-       entry->policy = policy;
-       entry->public_key = public_key;
-       entry->private_key = private_key;
-       entry->name = malloc(strlen(name) + 1);
-       strcpy(entry->name, name);
-       
-       return entry;
-}
 
 typedef struct private_stroke_t private_stroke_t;
 
@@ -135,14 +74,9 @@ struct private_stroke_t {
        stroke_t public;
 
        /**
-        * Holding all configurations.
+        * Holding all connections as connection_entry_t's.
         */
-       linked_list_t *configurations;
-       
-       /**
-        * The list of RSA private keys accessible through crendial_store_t interface
-        */
-       linked_list_t *private_keys;
+       linked_list_t *connections;
 
        /**
         * Assigned logger_t object in charon.
@@ -202,73 +136,6 @@ static void pop_string(stroke_msg_t *msg, char **string)
        }
 }
 
-/**
- * Find the private key for a public key
- */
-static rsa_private_key_t *find_private_key(private_stroke_t *this, rsa_public_key_t *public_key)
-{
-       rsa_private_key_t *private_key = NULL;
-       iterator_t *iterator;
-       
-       this->logger->log(this->logger, CONTROL|LEVEL2, "Looking up private key by public key...");
-       
-       iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
-       while (iterator->has_next(iterator))
-       {
-               iterator->current(iterator, (void**)&private_key);
-               if (private_key->belongs_to(private_key, public_key))
-               {
-                       this->logger->log(this->logger, CONTROL|LEVEL2, "found a match");
-                       break;
-               }
-               this->logger->log(this->logger, CONTROL|LEVEL2, "this one did not match");
-       }
-       iterator->destroy(iterator);
-       return private_key;
-}
-
-/**
- * Load all private keys form "/etc/ipsec.d/private/"
- */
-static void load_private_keys(private_stroke_t *this)
-{
-       struct dirent* entry;
-       struct stat stb;
-       DIR* dir;
-       rsa_private_key_t *key;
-       
-       /* currently only unencrypted binary DER files are loaded */
-       dir = opendir(PRIVATE_KEY_DIR);
-       if (dir == NULL || chdir(PRIVATE_KEY_DIR) == -1) {
-               this->logger->log(this->logger, ERROR, "error opening private key directory \"%s\"", PRIVATE_KEY_DIR);
-               return;
-       }
-       while ((entry = readdir(dir)) != NULL)
-       {
-               if (stat(entry->d_name, &stb) == -1)
-               {
-                       continue;
-               }
-               /* try to parse all regular files */
-               if (stb.st_mode & S_IFREG)
-               {
-                       key = rsa_private_key_create_from_file(entry->d_name, NULL);
-                       if (key)
-                       {
-                               this->private_keys->insert_last(this->private_keys, (void*)key);
-                               this->logger->log(this->logger, CONTROL|LEVEL1, "loaded private key \"%s%s\"", 
-                                                                 PRIVATE_KEY_DIR, entry->d_name);
-                       }
-                       else
-                       {
-                               this->logger->log(this->logger, ERROR, "private key \"%s%s\" invalid, skipped", 
-                                                                 PRIVATE_KEY_DIR, entry->d_name);
-                       }
-               }
-       }
-       closedir(dir);
-}
-
 /**
  * Add a connection to the configuration list
  */
@@ -280,9 +147,8 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
        host_t *my_host, *other_host, *my_subnet, *other_subnet;
        proposal_t *proposal;
        traffic_selector_t *my_ts, *other_ts;
-       x509_t *my_cert, *other_cert;
-       rsa_private_key_t *private_key = NULL;
-       rsa_public_key_t *public_key = NULL;
+       connection_entry_t *entry;
+       x509_t *cert;
                                
        pop_string(msg, &msg->add_conn.name);
        pop_string(msg, &msg->add_conn.me.address);
@@ -360,12 +226,12 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
        if (charon->socket->is_listening_on(charon->socket, other_host))
        {
                this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "left is other host, switching");
-                                       
+               
                host_t *tmp_host = my_host;
                identification_t *tmp_id = my_id;
                traffic_selector_t *tmp_ts = my_ts;
                char *tmp_cert = msg->add_conn.me.cert;
-                                       
+               
                my_host = other_host;
                other_host = tmp_host;
                my_id = other_id;
@@ -382,7 +248,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
        else
        {
                this->stroke_logger->log(this->stroke_logger, ERROR, "left nor right host is our, aborting");
-                                       
+               
                my_host->destroy(my_host);
                other_host->destroy(other_host);
                my_id->destroy(my_id);
@@ -392,7 +258,39 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
                return;
        }
        
-                               
+       if (msg->add_conn.me.cert)
+       {
+               char file[128];
+               snprintf(file, sizeof(file), "%s%s", CERTIFICATE_DIR,  msg->add_conn.me.cert);
+               cert = x509_create_from_file(file);
+               if (cert)
+               {
+                       my_id->destroy(my_id);
+                       my_id = cert->get_subject(cert);
+                       my_id = my_id->clone(my_id);
+                       cert->destroy(cert);
+                       this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, 
+                                                                       "defined a valid certificate, using its ID \"%s\"",
+                                                                       my_id->get_string(my_id));
+               }
+       }
+       if (msg->add_conn.other.cert)
+       {
+               char file[128];
+               snprintf(file, sizeof(file), "%s%s", CERTIFICATE_DIR,  msg->add_conn.other.cert);
+               cert = x509_create_from_file(file);
+               if (cert)
+               {
+                       other_id->destroy(other_id);
+                       other_id = cert->get_subject(cert);
+                       other_id = other_id->clone(other_id);
+                       cert->destroy(cert);
+                       this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, 
+                                                                        "defined a valid certificate, using its ID \"%s\"",
+                                                                        other_id->get_string(other_id));
+               }
+       }
+       
        connection = connection_create(my_host, other_host, my_id->clone(my_id), other_id->clone(other_id), 
                                                                   RSA_DIGITAL_SIGNATURE);
        proposal = proposal_create(1);
@@ -407,7 +305,14 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
        proposal->add_algorithm(proposal, PROTO_IKE, DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0);
        proposal->add_algorithm(proposal, PROTO_IKE, DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0);
        connection->add_proposal(connection, proposal);
-                               
+       /* add in our list, so we can manipulate the connection further via name */
+       entry = malloc_thing(connection_entry_t);
+       entry->name = strdup(msg->add_conn.name);
+       entry->connection = connection;
+       this->connections->insert_last(this->connections, entry);
+       /* add to global connection list */
+       charon->connections->add_connection(charon->connections, connection);
+       
        policy = policy_create(my_id, other_id);
        proposal = proposal_create(1);
        proposal->add_algorithm(proposal, PROTO_ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
@@ -416,53 +321,10 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
        policy->add_proposal(policy, proposal);
        policy->add_my_traffic_selector(policy, my_ts);
        policy->add_other_traffic_selector(policy, other_ts);
-                               
-                               
-       chdir(CERTIFICATE_DIR);
-       my_cert = x509_create_from_file(msg->add_conn.me.cert);
-       if (my_cert == NULL)
-       {
-               this->stroke_logger->log(this->stroke_logger, ERROR, "loading own certificate \"%s%s\" failed", 
-                                                 CERTIFICATE_DIR, msg->add_conn.me.cert);
-       }
-       else
-       {
-               public_key = my_cert->get_public_key(my_cert);
-               private_key = find_private_key(this, public_key);
-               public_key->destroy(public_key);
-               if (private_key)
-               {
-                       this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "found private key for certificate \"%s%s\"", 
-                                                         CERTIFICATE_DIR, msg->add_conn.me.cert);
-               }
-               else
-               {
-                       this->stroke_logger->log(this->stroke_logger, ERROR, "no private key for certificate \"%s%s\" found", 
-                                                         CERTIFICATE_DIR, msg->add_conn.me.cert);
-               }
-               my_cert->destroy(my_cert);
-       }
-       other_cert = x509_create_from_file(msg->add_conn.other.cert);
-       public_key = NULL;
-       if (other_cert == NULL)
-       {
-               this->stroke_logger->log(this->stroke_logger, ERROR, "loading peers certificate \"%s%s\" failed", 
-                                                 CERTIFICATE_DIR, msg->add_conn.other.cert);
-       }
-       else
-       {
-               public_key = other_cert->get_public_key(other_cert);
-               this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "loaded certificate \"%s%s\" (%p)", 
-                                                 CERTIFICATE_DIR, msg->add_conn.other.cert, public_key);
-               other_cert->destroy(other_cert);
-       }
-                               
-       this->configurations->insert_last(this->configurations, 
-                                                                         configuration_entry_create(msg->add_conn.name, connection, policy, private_key, public_key));
-                               
-       this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "connection \"%s\" added (%d in store)", 
-                                         msg->add_conn.name,
-                                         this->configurations->get_count(this->configurations));
+       /* add to global policy list */
+       charon->policies->add_policy(charon->policies, policy);
+       
+       this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "connection \"%s\" added", msg->add_conn.name);
 }
 
 /**
@@ -550,22 +412,30 @@ static void stroke_status(private_stroke_t *this, stroke_msg_t *msg)
                status = charon->ike_sa_manager->checkout(charon->ike_sa_manager, ike_sa_id, &ike_sa);
                if (status == SUCCESS)
                {
-                       host_t *me, *other;
-                       me = ike_sa->get_my_host(ike_sa);
-                       other = ike_sa->get_other_host(ike_sa);
-                       
+                       host_t *my_host, *other_host;
+                       identification_t *my_id, *other_id;
+                       my_host = ike_sa->get_my_host(ike_sa);
+                       other_host = ike_sa->get_other_host(ike_sa);
+                       my_id = ike_sa->get_my_id(ike_sa);
+                       other_id = ike_sa->get_other_id(ike_sa);
                        
-                       this->stroke_logger->log(this->stroke_logger, CONTROL, "IKE SA in state %s as %s",
-                                                                        mapping_find(ike_sa_state_m, ike_sa->get_state(ike_sa)),
-                                                                        ike_sa_id->is_initiator ? "initiator" : "responder");
+                       this->stroke_logger->log(this->stroke_logger, CONTROL, "IKE_SA in state %s ",
+                                                                        mapping_find(ike_sa_state_m, ike_sa->get_state(ike_sa)));
                        
-                       this->stroke_logger->log(this->stroke_logger, CONTROL, " SPIs: %15lld - %-15lld",
-                                                                        ike_sa_id->get_initiator_spi(ike_sa_id),
+                       this->stroke_logger->log(this->stroke_logger, CONTROL, " SPIs: %lld",
+                                                                        ike_sa_id->get_initiator_spi(ike_sa_id));
+                       this->stroke_logger->log(this->stroke_logger, CONTROL, "       %lld",
                                                                         ike_sa_id->get_responder_spi(ike_sa_id));
                        
-
-                       this->stroke_logger->log(this->stroke_logger, CONTROL, " Addr: %15s - %-15s",
-                                                                        me->get_address(me), other->get_address(other));
+                       this->stroke_logger->log(this->stroke_logger, CONTROL, " Addr: %s",
+                                                                        my_host->get_address(my_host));
+                       this->stroke_logger->log(this->stroke_logger, CONTROL, "       %s",
+                                                                        other_host->get_address(other_host));
+                       
+                       this->stroke_logger->log(this->stroke_logger, CONTROL, " ID:   %s",
+                                                                        my_id->get_string(my_id));
+                       this->stroke_logger->log(this->stroke_logger, CONTROL, "       %s",
+                                                                        other_id->get_string(other_id));
                                                
                        charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
                }
@@ -785,117 +655,6 @@ static void stroke_receive(private_stroke_t *this)
        }
 }
 
-/**
- * Implementation of connection_store_t.get_connection_by_hosts.
- */
-static connection_t *get_connection_by_hosts(connection_store_t *store, host_t *my_host, host_t *other_host)
-{
-       private_stroke_t *this = (private_stroke_t*)((u_int8_t*)store - offsetof(stroke_t, connections));
-       iterator_t *iterator;
-       connection_t *found = NULL;
-       
-       this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for hosts %s - %s", 
-                                         my_host->get_address(my_host), other_host->get_address(other_host));
-       
-       iterator = this->configurations->create_iterator(this->configurations,TRUE);
-       while (iterator->has_next(iterator))
-       {
-               configuration_entry_t *entry;
-               host_t *config_my_host, *config_other_host;
-               
-               iterator->current(iterator,(void **) &entry);
-
-               config_my_host = entry->connection->get_my_host(entry->connection);
-               config_other_host = entry->connection->get_other_host(entry->connection);
-
-               /* first check if ip is equal */
-               if(config_other_host->ip_equals(config_other_host, other_host))
-               {
-                       this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote host %s", 
-                                               config_other_host->get_address(config_other_host));
-                       /* could be right one, check my_host for default route*/
-                       if (config_my_host->is_default_route(config_my_host))
-                       {
-                               found = entry->connection->clone(entry->connection);
-                               break;
-                       }
-                       /* check now if host informations are the same */
-                       else if (config_my_host->ip_equals(config_my_host,my_host))
-                       {
-                               found = entry->connection->clone(entry->connection);
-                               break;
-                       }
-                       
-               }
-               /* Then check for wildcard hosts!
-                * TODO
-                * actually its only checked if other host with default route can be found! */
-               else if (config_other_host->is_default_route(config_other_host))
-               {
-                       /* could be right one, check my_host for default route*/
-                       if (config_my_host->is_default_route(config_my_host))
-                       {
-                               found = entry->connection->clone(entry->connection);
-                               break;
-                       }
-                       /* check now if host informations are the same */
-                       else if (config_my_host->ip_equals(config_my_host,my_host))
-                       {
-                               found = entry->connection->clone(entry->connection);
-                               break;
-                       }
-               }
-       }
-       iterator->destroy(iterator);
-       
-       /* apply hosts as they are supplied since my_host may be %defaultroute, and other_host may be %any. */
-       if (found)
-       {
-               found->update_my_host(found, my_host->clone(my_host));
-               found->update_other_host(found, other_host->clone(other_host));
-       }
-       
-       return found;
-}
-
-/**
- * Implementation of connection_store_t.get_connection_by_ids.
- */
-static connection_t *get_connection_by_ids(connection_store_t *store, identification_t *my_id, identification_t *other_id)
-{
-       private_stroke_t *this = (private_stroke_t*)((u_int8_t*)store - offsetof(stroke_t, connections));
-       iterator_t *iterator;
-       connection_t *found = NULL;
-       
-       this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for ids %s - %s", 
-                                         my_id->get_string(my_id), other_id->get_string(other_id));
-       
-       iterator = this->configurations->create_iterator(this->configurations,TRUE);
-       while (iterator->has_next(iterator))
-       {
-               configuration_entry_t *entry;
-               identification_t *config_my_id, *config_other_id;
-               
-               iterator->current(iterator,(void **) &entry);
-               
-               config_my_id = entry->connection->get_my_id(entry->connection);
-               config_other_id = entry->connection->get_other_id(entry->connection);
-
-               /* first check if ids are equal 
-               * TODO: Add wildcard checks */
-               if (config_other_id->equals(config_other_id, other_id) &&
-                       config_my_id->equals(config_my_id, my_id))
-               {
-                       this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote id %s", 
-                                                         config_other_id->get_string(config_other_id));
-                       found = entry->connection->clone(entry->connection);
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       
-       return found;
-}
 
 /**
  * Implementation of private_stroke_t.get_connection_by_name.
@@ -905,10 +664,10 @@ static connection_t *get_connection_by_name(private_stroke_t *this, char *name)
        iterator_t *iterator;
        connection_t *found = NULL;
        
-       iterator = this->configurations->create_iterator(this->configurations, TRUE);
+       iterator = this->connections->create_iterator(this->connections, TRUE);
        while (iterator->has_next(iterator))
        {
-               configuration_entry_t *entry;
+               connection_entry_t *entry;
                iterator->current(iterator,(void **) &entry);
 
                if (strcmp(entry->name,name) == 0)
@@ -923,166 +682,29 @@ static connection_t *get_connection_by_name(private_stroke_t *this, char *name)
        return found;
 }
 
-/**
- * Implementation of policy_store_t.get_policy.
- */
-static policy_t *get_policy(policy_store_t *store,identification_t *my_id, identification_t *other_id)
-{      
-       private_stroke_t *this = (private_stroke_t*)((u_int8_t*)store - offsetof(stroke_t, policies));
-       iterator_t *iterator;
-       policy_t *found = NULL;
-       
-       iterator = this->configurations->create_iterator(this->configurations, TRUE);
-       while (iterator->has_next(iterator))
-       {
-               configuration_entry_t *entry;
-               iterator->current(iterator,(void **) &entry);
-               identification_t *config_my_id = entry->policy->get_my_id(entry->policy);
-               identification_t *config_other_id = entry->policy->get_other_id(entry->policy);
-               
-               /* check other host first */
-               if (config_other_id->belongs_to(config_other_id, other_id))
-               {               
-                       /* get it if my_id not specified */
-                       if (my_id == NULL)
-                       {
-                               found = entry->policy->clone(entry->policy);
-                               break;
-                       }
-
-                       if (config_my_id->belongs_to(config_my_id, my_id))
-                       {
-                               found = entry->policy->clone(entry->policy);
-                               break;
-                       }
-               }
-       }
-       iterator->destroy(iterator);
-       
-       /* apply IDs as they are requsted, since they may be configured as %any or such */
-       if (found)
-       {
-               if (my_id)
-               {
-                       found->update_my_id(found, my_id->clone(my_id));
-               }
-               found->update_other_id(found, other_id->clone(other_id));
-       }
-       return found;
-}
-
-/**
- * Implementation of credential_store_t.get_shared_secret.
- */    
-static status_t get_shared_secret(credential_store_t *this, identification_t *identification, chunk_t *preshared_secret)
-{
-       char *secret = "schluessel\n";
-       preshared_secret->ptr = secret;
-       preshared_secret->len = strlen(secret) + 1;
-       
-       *preshared_secret = chunk_clone(*preshared_secret);
-       return SUCCESS;
-}
-
-/**
- * Implementation of credential_store_t.get_rsa_public_key.
- */
-static status_t get_rsa_public_key(credential_store_t *store, identification_t *identification, rsa_public_key_t **public_key)
-{
-       private_stroke_t *this = (private_stroke_t*)((u_int8_t*)store - offsetof(stroke_t, credentials));
-       iterator_t *iterator;
-       
-       this->logger->log(this->logger, CONTROL|LEVEL2, "Looking for public key for %s",
-                                         identification->get_string(identification));
-       iterator = this->configurations->create_iterator(this->configurations, TRUE);
-       while (iterator->has_next(iterator))
-       {
-               configuration_entry_t *config;
-               iterator->current(iterator, (void**)&config);
-               identification_t *stored = config->policy->get_other_id(config->policy);
-               this->logger->log(this->logger, CONTROL|LEVEL2, "there is one for %s",
-                                                 stored->get_string(stored));
-               if (identification->equals(identification, stored))
-               {
-                       this->logger->log(this->logger, CONTROL|LEVEL2, "found a match: %p",
-                                                         config->public_key);
-                       if (config->public_key)
-                       {
-                               iterator->destroy(iterator);
-                               *public_key = config->public_key->clone(config->public_key);
-                               return SUCCESS;
-                       }
-               }
-       }
-       iterator->destroy(iterator);
-       return NOT_FOUND;
-}
-
-/**
- * Implementation of credential_store_t.get_rsa_private_key.
- */
-static status_t get_rsa_private_key(credential_store_t *store, identification_t *identification, rsa_private_key_t **private_key)
-{
-       private_stroke_t *this = (private_stroke_t*)((u_int8_t*)store - offsetof(stroke_t, credentials));
-       iterator_t *iterator;
-       
-       iterator = this->configurations->create_iterator(this->configurations, TRUE);
-       while (iterator->has_next(iterator))
-       {
-               configuration_entry_t *config;
-               iterator->current(iterator, (void**)&config);
-               identification_t *stored = config->policy->get_my_id(config->policy);
-               if (identification->equals(identification, stored))
-               {
-                       if (config->private_key)
-                       {
-                               iterator->destroy(iterator);
-                               *private_key = config->private_key->clone(config->private_key);
-                               return SUCCESS;
-                       }
-               }
-       }
-       iterator->destroy(iterator);
-       return NOT_FOUND;
-}
-
 /**
  * Implementation of stroke_t.destroy.
  */
 static void destroy(private_stroke_t *this)
 {
-       configuration_entry_t *entry;
-       rsa_private_key_t *priv_key;
+       connection_entry_t *entry;
        
        pthread_cancel(this->assigned_thread);
        pthread_join(this->assigned_thread, NULL);
        
-       while (this->configurations->remove_first(this->configurations, (void **)&entry) == SUCCESS)
-       {
-               entry->destroy(entry);
-       }
-       this->configurations->destroy(this->configurations);
-       
-       while (this->private_keys->remove_first(this->private_keys, (void **)&priv_key) == SUCCESS)
+       while (this->connections->remove_first(this->connections, (void **)&entry) == SUCCESS)
        {
-               priv_key->destroy(priv_key);
+               /* connection is destroyed by global list */
+               free(entry->name);
+               free(entry);
        }
-       this->private_keys->destroy(this->private_keys);
+       this->connections->destroy(this->connections);
 
        close(this->socket);
        unlink(socket_addr.sun_path);
        free(this);
 }
 
-/**
- * Dummy function which does nothing.
- * Used for connection_store_t.destroy and policy_store_t.destroy,
- * since destruction is done in store_t's destructor...
- */
-void do_nothing(void *nothing)
-{
-       return;
-}
 
 /*
  * Described in header-file
@@ -1093,15 +715,6 @@ stroke_t *stroke_create()
        mode_t old;
 
        /* public functions */
-       this->public.connections.get_connection_by_ids = get_connection_by_ids;
-       this->public.connections.get_connection_by_hosts = get_connection_by_hosts;
-       this->public.connections.destroy = (void (*) (connection_store_t*))do_nothing;
-       this->public.policies.get_policy = get_policy;
-       this->public.policies.destroy = (void (*) (policy_store_t*))do_nothing;
-       this->public.credentials.get_shared_secret = (status_t (*)(credential_store_t*,identification_t*,chunk_t*))get_shared_secret;
-       this->public.credentials.get_rsa_public_key = (status_t (*)(credential_store_t*,identification_t*,rsa_public_key_t**))get_rsa_public_key;
-       this->public.credentials.get_rsa_private_key = (status_t (*)(credential_store_t*,identification_t*,rsa_private_key_t**))get_rsa_private_key;
-       this->public.credentials.destroy = (void (*) (credential_store_t*))do_nothing;
        this->public.destroy = (void (*)(stroke_t*))destroy;
        
        /* private functions */
@@ -1149,10 +762,7 @@ stroke_t *stroke_create()
        }
        
        /* private variables */
-       this->configurations = linked_list_create();
-       this->private_keys = linked_list_create();
-       
-       load_private_keys(this);
+       this->connections = linked_list_create();
        
        return (&this->public);
 }
index 0bb0bb48b7c1a9babd5e751279a47e7989b35fff..f8efc9c67790500235f2544af005f41d165a66ea 100644 (file)
 #ifndef STROKE_INTERFACE_H_
 #define STROKE_INTERFACE_H_
 
-#include <config/policy_store.h>
-#include <config/connection_store.h>
-#include <config/credential_store.h>
-
-
-#define IPSEC_DIR "/etc/ipsec.d/"
-#define PRIVATE_KEY_DIR IPSEC_DIR "private/"
-#define CERTIFICATE_DIR IPSEC_DIR "certs/"
+#include <config/policies/policy_store.h>
+#include <config/connections/connection_store.h>
+#include <config/credentials/credential_store.h>
 
 
 typedef struct stroke_t stroke_t;
@@ -59,11 +54,6 @@ typedef struct stroke_t stroke_t;
  * @ingroup threads
  */
 struct stroke_t {
-
-       /**
-        * Implements connection_store_t interface
-        */
-       connection_store_t connections;
        
        /**
         * Implements policy_store_t interface
index 44d8b985ca53c40185aae7d43691fab317b35905..11b30fb7d50b42004547e7c03fe26de9b656b18d 100644 (file)
 
 + doxygen cleanup (charon/lib)
 
-- useable certificate support
+/ useable certificate support
   + more id types (use atodn from pluto)
-  - rewrite certificate storage the clean way
+  + rewrite certificate storage the clean way
+  - further subjectAltName support
   - certificate validation/chaining
   - certificate exchange
 
index 8286612a96caba81ce61d87a5ec5e9d73a91a88c..358653f0e7205f711d9fd28fd0c3511bb209a755 100644 (file)
@@ -327,7 +327,6 @@ static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this, hash
        memcpy(em.ptr + em.len - hash.len, hash.ptr, hash.len);
        /* set oid */
        memcpy(em.ptr + em.len - hash.len - oid.len, oid.ptr, oid.len);
-
        
        /* build signature */
        *signature = this->rsasp1(this, em);
index 28e7d1898115d4f0ef48a2e3dc44690a371a70b0..86a59561829bcf864d63149bd8a17bb18c26cc42 100755 (executable)
@@ -883,7 +883,8 @@ x509_t *x509_create_from_chunk(chunk_t chunk)
        /* we do not use a per-instance logger right now, since its not always accessible */
        logger = logger_manager->get_logger(logger_manager, ASN1);
        
-       if (!parse_x509cert(chunk, 0, this))
+       if (!is_asn1(chunk) ||
+               !parse_x509cert(chunk, 0, this))
        {
                destroy(this);
                return NULL;
index 663ccaec52459314e16ec314670005c6a125e6ef..413d3019cd5af5364a364d36d1bab4c125240110 100644 (file)
  */
 #define MAX_LOG 8192
 
+/**
+ * Maximum number of logged bytes pre line
+ */
+#define MAX_BYTES 16
 
 typedef struct private_logger_t private_logger_t;
 
@@ -70,13 +74,13 @@ struct private_logger_t {
         * 
         * @warning: buffer must be at least have MAX_LOG size.
         */
-       void (*prepend_prefix) (private_logger_t *this, log_level_t loglevel, char *string, char *buffer);
+       void (*prepend_prefix) (private_logger_t *this, log_level_t loglevel, const char *string, char *buffer);
 };
 
 /**
  * Implementation of private_logger_t.prepend_prefix.
  */
-static void prepend_prefix(private_logger_t *this, log_level_t loglevel, char *string, char *buffer)
+static void prepend_prefix(private_logger_t *this, log_level_t loglevel, const char *string, char *buffer)
 {
        char log_type, log_details;
        if (loglevel & CONTROL)
@@ -168,55 +172,62 @@ static void logg(private_logger_t *this, log_level_t loglevel, char *format, ...
 /**
  * Implementation of logger_t.log_bytes.
  */
-static void log_bytes(private_logger_t *this, log_level_t loglevel, char *label, char *bytes, size_t len)
+static void log_bytes(private_logger_t *this, log_level_t loglevel, const char *label, const char *bytes, size_t len)
 {
        static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
-       
        if ((this->level & loglevel) == loglevel)
        {
                char buffer[MAX_LOG];
-               char ascii_buffer[17];
-               char *format;
-               char *buffer_pos;
-               char *bytes_pos, *bytes_roof;
-               int i;
+               char ascii_buffer[MAX_BYTES+1];
+
+               char *buffer_pos = buffer;
+               const char format[] = "%s   %d bytes @ %p";
+               const char *bytes_pos  = bytes;
+               const char *bytes_roof = bytes + len;
+
                int line_start = 0;
-                       
+               int i = 0;
+
                /* since me can't do multi-line output to syslog, 
                * we must do multiple syslogs. To avoid
                * problems in output order, lock this by a mutex.
                */
                pthread_mutex_lock(&mutex);
-               
-               
-               format = "%s (%d bytes @%p)";
+
                this->prepend_prefix(this, loglevel, format, buffer);
 
                if (this->output == NULL)
                {
-                       syslog(LOG_INFO, buffer, label, len);   
+                       syslog(LOG_INFO, buffer, label, len, bytes);
                }
                else
                {
                        fprintf(this->output, buffer, label, len, bytes);
                        fprintf(this->output, "\n");
                }
-       
-               bytes_pos = bytes;
-               bytes_roof = bytes + len;
-               buffer_pos = buffer;
-               memset(ascii_buffer, 0, 17);
 
-               for (i = 1; bytes_pos < bytes_roof; i++)
+               while (bytes_pos < bytes_roof)
                {
                        static char hexdig[] = "0123456789ABCDEF";
+
                        *buffer_pos++ = hexdig[(*bytes_pos >> 4) & 0xF];
                        *buffer_pos++ = hexdig[ *bytes_pos       & 0xF];
-                       if ((i % 16) == 0) 
+
+                       ascii_buffer[i++] = (*bytes_pos > 31 && *bytes_pos < 127)
+                               ? *bytes_pos : '.';
+
+                       if (++bytes_pos == bytes_roof || i == MAX_BYTES) 
                        {
+                               int padding = 3 * (MAX_BYTES - i);
+
+                               while (padding--)
+                               {
+                                       *buffer_pos++ = ' ';
+                               }
                                *buffer_pos++ = '\0';
-                               buffer_pos = buffer;
+                               ascii_buffer[i] = '\0';
+
                                if (this->output == NULL)
                                {
                                        syslog(LOG_INFO, "[  :%5d] %s %s", line_start, buffer, ascii_buffer);   
@@ -225,43 +236,14 @@ static void log_bytes(private_logger_t *this, log_level_t loglevel, char *label,
                                {
                                        fprintf(this->output, "[  :%5d] %s %s\n", line_start, buffer, ascii_buffer);
                                }
-                               memset(ascii_buffer, 0, 16);
+                               buffer_pos = buffer;
                                line_start += 16;
-                       }
-                       else if ((i % 4) == 0)
-                       {
-                               *buffer_pos++ = ' ';
-               //              *buffer_pos++ = ' ';
+                               i = 0;
                        }
                        else 
                        {       
                                *buffer_pos++ = ' ';
                        }
-                       
-                       if (*bytes_pos > 31 && *bytes_pos < 127)
-                       {
-                               ascii_buffer[(i % 16)] = *bytes_pos;
-                       }
-                       else
-                       {
-                               ascii_buffer[(i % 16)] = '*';
-                       }
-                       
-                       bytes_pos++;
-               }
-               
-               *buffer_pos++ = '\0';
-               if (buffer_pos > buffer + 1)
-               {
-                       buffer_pos = buffer;
-                       if (this->output == NULL)
-                       {               
-                               syslog(LOG_INFO, "[  :%5d] %s %16s", line_start, buffer, ascii_buffer);
-                       }
-                       else
-                       {
-                               fprintf(this->output, "[  :%5d] %s %16s\n", line_start, buffer, ascii_buffer);
-                       }
                }
                pthread_mutex_unlock(&mutex);
        }
index fa2f84dd00d9b82e23ab766e4d06a7979e6c64ba..01ba27f5b5fa68a99a43ee265532c4d1dd4f1954 100755 (executable)
@@ -4,18 +4,17 @@
 echo 1 > /proc/sys/net/ipv4/ip_forward
 
 # add connection to alice
-MY_ADDR=192.168.0.2      # Address of local peer, also used as ID
-OTHER_ADDR=192.168.0.1   # Address of remote peer, also used as ID
-MY_CERT=bob.der          # own certificate
-OTHER_CERT=alice.der     # certificate for remote peer
-MY_NET=10.2.0.0          # protected local subnet
-OTHER_NET=10.1.0.0       # protected remote subnet
-MY_BITS=16               # size of subnet
-OTHER_BITS=16            # size of subnet
-CONN_NAME=to-alice       # connection name
+MY_ADDR=192.168.0.2                           # Address of local peer
+OTHER_ADDR=192.168.0.1                        # Address of remote peer
+MY_ID="C=CH, O=Linux strongSwan, CN=bob"      # ID of local peer
+OTHER_ID="C=CH, O=Linux strongSwan, CN=alice" # ID of remote peer
+MY_NET=10.2.0.0                               # protected local subnet
+OTHER_NET=10.1.0.0                            # protected remote subnet
+MY_BITS=16                                    # size of subnet
+OTHER_BITS=16                                 # size of subnet
+CONN_NAME=to-alice                            # connection name
 
-bin/stroke add $CONN_NAME $MY_ADDR $OTHER_ADDR $MY_CERT $OTHER_CERT \
-               $MY_ADDR $OTHER_ADDR $MY_NET $OTHER_NET $MY_BITS $OTHER_BITS
+bin/stroke add $CONN_NAME "$MY_ID" "$OTHER_ID" $MY_ADDR $OTHER_ADDR $MY_NET $OTHER_NET $MY_BITS $OTHER_BITS
 
 # initiate
 i=0
index 01298648485d2e16e172958bc41abfeeda20c0a7..df30bd893a75f271fb248cb4eaec7722c1909c7e 100755 (executable)
@@ -4,16 +4,24 @@
 echo 1 > /proc/sys/net/ipv4/ip_forward
 
 # add connection to bob
-MY_ADDR=192.168.0.1      # Address of local peer, also used as ID
-OTHER_ADDR=192.168.0.2   # Address of remote peer, also used as ID
-MY_CERT=alice.der        # own certificate
-OTHER_CERT=bob.der       # certificate for remote peer
-MY_NET=10.1.0.0          # protected local subnet
-OTHER_NET=10.2.0.0       # protected remote subnet
-MY_BITS=16               # size of subnet
-OTHER_BITS=16            # size of subnet
-CONN_NAME=to-bob         # connection name
+MY_ADDR=192.168.0.1                           # Address of local peer
+OTHER_ADDR=192.168.0.2                        # Address of remote peer
+MY_ID="C=CH, O=Linux strongSwan, CN=alice"    # ID of local peer
+OTHER_ID="C=CH, O=Linux strongSwan, CN=bob"   # ID of remote peer
+MY_NET=10.1.0.0                               # protected local subnet
+OTHER_NET=10.2.0.0                            # protected remote subnet
+MY_BITS=16                                    # size of subnet
+OTHER_BITS=16                                 # size of subnet
+CONN_NAME=to-bob                              # connection name
 
-bin/stroke add $CONN_NAME $MY_ADDR $OTHER_ADDR $MY_CERT $OTHER_CERT \
-               $MY_ADDR $OTHER_ADDR $MY_NET $OTHER_NET $MY_BITS $OTHER_BITS
-               
\ No newline at end of file
+bin/stroke add $CONN_NAME "$MY_ID" "$OTHER_ID" $MY_ADDR $OTHER_ADDR $MY_NET $OTHER_NET $MY_BITS $OTHER_BITS
+
+# initiate
+i=0
+LIMIT=0
+
+while [ "$i" -lt "$LIMIT" ]
+do
+  bin/stroke up $CONN_NAME
+  let "i += 1"
+done
index 5062c26f7d28cd5baa1f2edf02c159cac919822f..e4876ced06fe6c4754cbdf31640f620ade3bc8ce 100644 (file)
@@ -91,7 +91,6 @@ static int send_stroke_msg (stroke_msg_t *msg)
 
 static int add_connection(char *name,
                                                  char *my_id, char *other_id, 
-                                                 char *my_cert, char *other_cert,
                                                  char *my_addr, char *other_addr,
                                                  char *my_net, char *other_net,
                                                  u_int my_netmask, u_int other_netmask)
@@ -105,16 +104,16 @@ static int add_connection(char *name,
        msg->add_conn.name = push_string(&msg, name);
        
        msg->add_conn.me.id = push_string(&msg, my_id);
-       msg->add_conn.me.cert = push_string(&msg, my_cert);
        msg->add_conn.me.address = push_string(&msg, my_addr);
        msg->add_conn.me.subnet = push_string(&msg, my_net);
        msg->add_conn.me.subnet_mask = my_netmask;
+       msg->add_conn.me.cert = NULL;
        
        msg->add_conn.other.id = push_string(&msg, other_id);
-       msg->add_conn.other.cert = push_string(&msg, other_cert);
        msg->add_conn.other.address = push_string(&msg, other_addr);
        msg->add_conn.other.subnet = push_string(&msg, other_net);
        msg->add_conn.other.subnet_mask = other_netmask;
+       msg->add_conn.other.cert = NULL;
        
        res = send_stroke_msg(msg);
        free(msg);
@@ -201,11 +200,9 @@ static void exit_usage(char *error)
 {
        printf("Usage:\n");
        printf("  Add a connection:\n");
-       printf("    stroke add NAME MY_ID OTHER_ID MY_CERT OTHER_CERT\\\n");
-       printf("           MY_ADDR OTHER_ADDR MY_NET OTHER_NET\\\n");
-       printf("           MY_NETBITS OTHER_NETBITS\n");
-       printf("    where: ID is any IKEv2 ID (currently only IPv4 adresses\n");
-       printf("           CERT is a certificate filename\n");
+       printf("    stroke add NAME MY_ID OTHER_ID MY_ADDR OTHER_ADDR\\\n");
+       printf("           MY_NET OTHER_NET MY_NETBITS OTHER_NETBITS\n");
+       printf("    where: ID is any IKEv2 ID \n");
        printf("           ADDR is a IPv4 address\n");
        printf("           NET is a IPv4 address of the subnet to tunnel\n");
        printf("           NETBITS is the size of the subnet, as the \"24\" in 192.168.0.0/24\n");
@@ -264,7 +261,7 @@ int main(int argc, char *argv[])
        }
        else if (strcmp(argv[1], "add") == 0)
        {
-               if (argc < 13)
+               if (argc < 11)
                {
                        exit_usage("\"add\" needs more parameters...");
                }
@@ -272,8 +269,7 @@ int main(int argc, char *argv[])
                                                         argv[3], argv[4], 
                                                         argv[5], argv[6], 
                                                         argv[7], argv[8], 
-                                                        argv[9], argv[10], 
-                                                        atoi(argv[11]), atoi(argv[12])); 
+                                                        atoi(argv[9]), atoi(argv[10]));
        }
        else if (strcmp(argv[1], "logtype") == 0)
        {
@@ -296,9 +292,5 @@ int main(int argc, char *argv[])
                exit_usage(NULL);
        }
        
-       if (res)
-       {
-               exit_error("communication with charon failed!\n");
-       }
-       return 0;
+       return res;
 }
index 2b2a4d4d86790f17839215d6dd75fbbf2e18acfb..6b12afc1dc8ad7506fa117f64daa85bcde3207d2 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "connection_test.h"
 
-#include <config/connection.h>
+#include <config/connections/connection.h>
 #include <crypto/prfs/prf.h>
 
 
index 38fc7cd53305a8ee5c0e48a940596ae39e54cbd1..9003eeff0f9ec6a6ee18a25bf75135125dbe86b3 100644 (file)
@@ -23,7 +23,7 @@
 #include "policy_test.h"
 
 #include <daemon.h>
-#include <config/policy.h>
+#include <config/policies/policy.h>
 #include <config/traffic_selector.h>
 #include <utils/logger.h>
 #include <encoding/payloads/ts_payload.h>