aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-10-29 10:34:08 +0200
committerMartin Willi <martin@revosec.ch>2011-01-05 16:45:40 +0100
commitd1041fa463c14339b439ba24d86e678b8c37d00a (patch)
tree1d9575237ba8be234fc19aab06f1fafc87a9e539
parentf452a5a1f8c94359601cf843f635ba385d08ad5e (diff)
downloadstrongswan-d1041fa463c14339b439ba24d86e678b8c37d00a.tar.bz2
strongswan-d1041fa463c14339b439ba24d86e678b8c37d00a.tar.xz
Load test and suite specific connection configurations
-rw-r--r--src/conftest/Makefile.am2
-rw-r--r--src/conftest/config.c316
-rw-r--r--src/conftest/config.h56
-rw-r--r--src/conftest/conftest.c11
-rw-r--r--src/conftest/conftest.h7
5 files changed, 391 insertions, 1 deletions
diff --git a/src/conftest/Makefile.am b/src/conftest/Makefile.am
index 0b041a42c..ce009e4c7 100644
--- a/src/conftest/Makefile.am
+++ b/src/conftest/Makefile.am
@@ -2,7 +2,7 @@ ipsec_PROGRAMS = conftest
AM_CFLAGS = -rdynamic
-conftest_SOURCES = conftest.c hooks/hook.h
+conftest_SOURCES = conftest.c conftest.h config.c config.h hooks/hook.h
INCLUDES = \
-I$(top_srcdir)/src/libstrongswan \
diff --git a/src/conftest/config.c b/src/conftest/config.c
new file mode 100644
index 000000000..1e7002595
--- /dev/null
+++ b/src/conftest/config.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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 "config.h"
+
+#include <daemon.h>
+#include <conftest.h>
+
+typedef struct private_config_t private_config_t;
+
+/**
+ * Private data of an config_t object.
+ */
+struct private_config_t {
+
+ /**
+ * Public config_t interface.
+ */
+ config_t public;
+
+ /**
+ * List of loaded peer configs
+ */
+ linked_list_t *configs;
+};
+
+/**
+ * filter function for ike configs
+ */
+static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out)
+{
+ *out = (*in)->get_ike_cfg(*in);
+ return TRUE;
+}
+
+METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
+ private_config_t *this, host_t *me, host_t *other)
+{
+
+ return enumerator_create_filter(
+ this->configs->create_enumerator(this->configs),
+ (void*)ike_filter, NULL, NULL);
+}
+
+METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
+ private_config_t *this, identification_t *me, identification_t *other)
+{
+ return this->configs->create_enumerator(this->configs);
+}
+
+METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
+ private_config_t *this, char *name)
+{
+ enumerator_t *e1, *e2;
+ peer_cfg_t *current, *found = NULL;
+ child_cfg_t *child;
+
+ e1 = this->configs->create_enumerator(this->configs);
+ while (e1->enumerate(e1, &current))
+ {
+ e2 = current->create_child_cfg_enumerator(current);
+ while (e2->enumerate(e2, &child))
+ {
+ if (streq(child->get_name(child), name))
+ {
+ found = current;
+ found->get_ref(found);
+ break;
+ }
+ }
+ e2->destroy(e2);
+ if (found)
+ {
+ break;
+ }
+ }
+ e1->destroy(e1);
+ return found;
+}
+
+/**
+ * Load IKE config for a given section name
+ */
+static ike_cfg_t *load_ike_config(private_config_t *this,
+ settings_t *settings, char *config)
+{
+ enumerator_t *enumerator;
+ ike_cfg_t *ike_cfg;
+ proposal_t *proposal;
+ char *token;
+
+ ike_cfg = ike_cfg_create(TRUE, FALSE,
+ settings->get_str(settings, "configs.%s.lhost", "%any", config), 500,
+ settings->get_str(settings, "configs.%s.rhost", "%any", config), 500);
+ token = settings->get_str(settings, "configs.%s.proposal", NULL, config);
+ if (token)
+ {
+ enumerator = enumerator_create_token(token, ",", " ");
+ while (enumerator->enumerate(enumerator, &token))
+ {
+ proposal = proposal_create_from_string(PROTO_IKE, token);
+ if (proposal)
+ {
+ ike_cfg->add_proposal(ike_cfg, proposal);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "parsing proposal '%s' failed, skipped", token);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+ }
+ return ike_cfg;
+}
+/**
+ * Load CHILD config for given section names
+ */
+static child_cfg_t *load_child_config(private_config_t *this,
+ settings_t *settings, char *config, char *child)
+{
+ child_cfg_t *child_cfg;
+ lifetime_cfg_t lifetime = {};
+ enumerator_t *enumerator;
+ proposal_t *proposal;
+ traffic_selector_t *ts;
+ host_t *net;
+ char *token;
+ int bits;
+
+ child_cfg = child_cfg_create(child, &lifetime, NULL, FALSE,
+ settings->get_bool(settings, "configs.%s.%s.transport",
+ FALSE, config, child),
+ ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL, NULL);
+
+ token = settings->get_str(settings, "configs.%s.%s.proposal",
+ NULL, config, child);
+ if (token)
+ {
+ enumerator = enumerator_create_token(token, ",", " ");
+ while (enumerator->enumerate(enumerator, &token))
+ {
+ proposal = proposal_create_from_string(PROTO_ESP, token);
+ if (proposal)
+ {
+ child_cfg->add_proposal(child_cfg, proposal);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "parsing proposal '%s' failed, skipped", token);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+ }
+
+ token = settings->get_str(settings, "configs.%s.%s.lts", NULL, config);
+ if (token)
+ {
+ enumerator = enumerator_create_token(token, ",", " ");
+ while (enumerator->enumerate(enumerator, &token))
+ {
+ net = host_create_from_subnet(token, &bits);
+ if (net)
+ {
+ ts = traffic_selector_create_from_subnet(net, bits, 0, 0);
+ child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "invalid local ts: %s, skipped", token);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ ts = traffic_selector_create_dynamic(0, 0, 65535);
+ child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
+ }
+
+ token = settings->get_str(settings, "configs.%s.%s.rts", NULL, config);
+ if (token)
+ {
+ enumerator = enumerator_create_token(token, ",", " ");
+ while (enumerator->enumerate(enumerator, &token))
+ {
+ net = host_create_from_subnet(token, &bits);
+ if (net)
+ {
+ ts = traffic_selector_create_from_subnet(net, bits, 0, 0);
+ child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "invalid remote ts: %s, skipped", token);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ ts = traffic_selector_create_dynamic(0, 0, 65535);
+ child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+ }
+ return child_cfg;
+}
+
+/**
+ * Load peer config for a given section name
+ */
+static peer_cfg_t *load_peer_config(private_config_t *this,
+ settings_t *settings, char *config)
+{
+ ike_cfg_t *ike_cfg;
+ peer_cfg_t *peer_cfg;
+ auth_cfg_t *auth;
+ child_cfg_t *child_cfg;
+ enumerator_t *enumerator;
+ identification_t *lid, *rid;
+ char *child;
+
+ ike_cfg = load_ike_config(this, settings, config);
+ peer_cfg = peer_cfg_create(config, 2, ike_cfg, CERT_ALWAYS_SEND,
+ UNIQUE_NO, 1, 0, 0, 0, 0, TRUE, 0,
+ NULL, NULL, FALSE, NULL, NULL);
+
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ lid = identification_create_from_string(
+ settings->get_str(settings, "configs.%s.lid", "%any", config));
+ auth->add(auth, AUTH_RULE_IDENTITY, lid);
+ peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
+
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ rid = identification_create_from_string(
+ settings->get_str(settings, "configs.%s.rid", "%any", config));
+ auth->add(auth, AUTH_RULE_IDENTITY, rid);
+ peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
+
+ DBG1(DBG_CFG, "loaded config %s: %Y - %Y", config, lid, rid);
+
+ enumerator = settings->create_section_enumerator(settings,
+ "configs.%s", config);
+ while (enumerator->enumerate(enumerator, &child))
+ {
+ child_cfg = load_child_config(this, settings, config, child);
+ peer_cfg->add_child_cfg(peer_cfg, child_cfg);
+ }
+ enumerator->destroy(enumerator);
+ return peer_cfg;
+}
+
+METHOD(config_t, load, void,
+ private_config_t *this, settings_t *settings)
+{
+ enumerator_t *enumerator;
+ char *config;
+
+ enumerator = settings->create_section_enumerator(settings, "configs");
+ while (enumerator->enumerate(enumerator, &config))
+ {
+ this->configs->insert_last(this->configs,
+ load_peer_config(this, settings, config));
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(config_t, destroy, void,
+ private_config_t *this)
+{
+ this->configs->destroy_offset(this->configs, offsetof(peer_cfg_t, destroy));
+ free(this);
+}
+
+/**
+ * See header
+ */
+config_t *config_create()
+{
+ private_config_t *this;
+
+ INIT(this,
+ .public = {
+ .backend = {
+ .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
+ .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
+ .get_peer_cfg_by_name = _get_peer_cfg_by_name,
+ },
+ .load = _load,
+ .destroy = _destroy,
+ },
+ .configs = linked_list_create(),
+ );
+
+ return &this->public;
+}
diff --git a/src/conftest/config.h b/src/conftest/config.h
new file mode 100644
index 000000000..2a62b9ce0
--- /dev/null
+++ b/src/conftest/config.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup config config
+ * @{ @ingroup conftest
+ */
+
+#ifndef CONFIG_H_
+#define CONFIG_H_
+
+typedef struct config_t config_t;
+
+#include <config/backend.h>
+
+/**
+ * Conftest IKE and CHILD config backend
+ */
+struct config_t {
+
+ /**
+ * Implements the backend_t interface.
+ */
+ backend_t backend;
+
+ /**
+ * Load configurations from a settings file.
+ *
+ * @param settings settings file to load configs from
+ */
+ void (*load)(config_t *this, settings_t *settings);
+
+ /**
+ * Destroy a config_t.
+ */
+ void (*destroy)(config_t *this);
+};
+
+/**
+ * Create a config instance.
+ */
+config_t *config_create();
+
+#endif /** CONFIG_H_ @}*/
diff --git a/src/conftest/conftest.c b/src/conftest/conftest.c
index 881db5d92..9db59b053 100644
--- a/src/conftest/conftest.c
+++ b/src/conftest/conftest.c
@@ -23,6 +23,7 @@
#include <libgen.h>
#include "conftest.h"
+#include "config.h"
#include "hooks/hook.h"
#include <threading/thread.h>
@@ -192,6 +193,12 @@ static void cleanup()
hook->destroy(hook);
}
conftest->hooks->destroy(conftest->hooks);
+ if (conftest->config)
+ {
+ charon->backends->remove_backend(charon->backends,
+ &conftest->config->backend);
+ conftest->config->destroy(conftest->config);
+ }
free(conftest->suite_dir);
free(conftest->test_dir);
free(conftest);
@@ -241,6 +248,7 @@ int main(int argc, char *argv[])
lib->credmgr->add_set(lib->credmgr, &conftest->creds->set);
conftest->hooks = linked_list_create();
+ conftest->config = config_create();
atexit(cleanup);
@@ -292,6 +300,9 @@ int main(int argc, char *argv[])
{
return 1;
}
+ charon->backends->add_backend(charon->backends, &conftest->config->backend);
+ conftest->config->load(conftest->config, conftest->suite);
+ conftest->config->load(conftest->config, conftest->test);
/* set up thread specific handlers */
action.sa_handler = segv_handler;
diff --git a/src/conftest/conftest.h b/src/conftest/conftest.h
index 614248ef4..5fa2e376b 100644
--- a/src/conftest/conftest.h
+++ b/src/conftest/conftest.h
@@ -25,6 +25,8 @@
#include <daemon.h>
#include <credentials/sets/mem_cred.h>
+#include "config.h"
+
typedef struct conftest_t conftest_t;
/**
@@ -58,6 +60,11 @@ struct conftest_t {
mem_cred_t *creds;
/**
+ * Configurations loaded from config
+ */
+ config_t *config;
+
+ /**
* Loaded hooks
*/
linked_list_t *hooks;