diff options
author | Martin Willi <martin@revosec.ch> | 2010-10-29 10:34:08 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2011-01-05 16:45:40 +0100 |
commit | d1041fa463c14339b439ba24d86e678b8c37d00a (patch) | |
tree | 1d9575237ba8be234fc19aab06f1fafc87a9e539 | |
parent | f452a5a1f8c94359601cf843f635ba385d08ad5e (diff) | |
download | strongswan-d1041fa463c14339b439ba24d86e678b8c37d00a.tar.bz2 strongswan-d1041fa463c14339b439ba24d86e678b8c37d00a.tar.xz |
Load test and suite specific connection configurations
-rw-r--r-- | src/conftest/Makefile.am | 2 | ||||
-rw-r--r-- | src/conftest/config.c | 316 | ||||
-rw-r--r-- | src/conftest/config.h | 56 | ||||
-rw-r--r-- | src/conftest/conftest.c | 11 | ||||
-rw-r--r-- | src/conftest/conftest.h | 7 |
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, ¤t)) + { + 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; |