diff options
Diffstat (limited to 'src/charon/config')
-rw-r--r-- | src/charon/config/auth_cfg.c | 768 | ||||
-rw-r--r-- | src/charon/config/auth_cfg.h | 201 | ||||
-rw-r--r-- | src/charon/config/backend.h | 83 | ||||
-rw-r--r-- | src/charon/config/backend_manager.c | 444 | ||||
-rw-r--r-- | src/charon/config/backend_manager.h | 114 | ||||
-rw-r--r-- | src/charon/config/child_cfg.c | 552 | ||||
-rw-r--r-- | src/charon/config/child_cfg.h | 310 | ||||
-rw-r--r-- | src/charon/config/ike_cfg.c | 286 | ||||
-rw-r--r-- | src/charon/config/ike_cfg.h | 145 | ||||
-rw-r--r-- | src/charon/config/peer_cfg.c | 699 | ||||
-rw-r--r-- | src/charon/config/peer_cfg.h | 358 | ||||
-rw-r--r-- | src/charon/config/proposal.c | 945 | ||||
-rw-r--r-- | src/charon/config/proposal.h | 226 |
13 files changed, 0 insertions, 5131 deletions
diff --git a/src/charon/config/auth_cfg.c b/src/charon/config/auth_cfg.c deleted file mode 100644 index 94362c756..000000000 --- a/src/charon/config/auth_cfg.c +++ /dev/null @@ -1,768 +0,0 @@ -/* - * Copyright (C) 2007-2009 Martin Willi - * Copyright (C) 2008 Tobias Brunner - * 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 "auth_cfg.h" - -#include <daemon.h> -#include <utils/linked_list.h> -#include <utils/identification.h> -#include <credentials/certificates/certificate.h> - -ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_SUBJECT_HASH_URL, - "RULE_IDENTITY", - "RULE_AUTH_CLASS", - "RULE_EAP_IDENTITY", - "RULE_EAP_TYPE", - "RULE_EAP_VENDOR", - "RULE_CA_CERT", - "RULE_IM_CERT", - "RULE_SUBJECT_CERT", - "RULE_CRL_VALIDATION", - "RULE_OCSP_VALIDATION", - "RULE_AC_GROUP", - "HELPER_IM_CERT", - "HELPER_SUBJECT_CERT", - "HELPER_IM_HASH_URL", - "HELPER_SUBJECT_HASH_URL", -); - -typedef struct private_auth_cfg_t private_auth_cfg_t; - -/** - * private data of item_set - */ -struct private_auth_cfg_t { - - /** - * public functions - */ - auth_cfg_t public; - - /** - * list of entry_t - */ - linked_list_t *entries; -}; - -typedef struct entry_t entry_t; - -struct entry_t { - /** rule type */ - auth_rule_t type; - /** associated value */ - void *value; -}; - -/** - * enumerator for auth_cfg_t.create_enumerator() - */ -typedef struct { - /** implements enumerator_t */ - enumerator_t public; - /** inner enumerator from linked_list_t */ - enumerator_t *inner; - /** current entry */ - entry_t *current; -} entry_enumerator_t; - -/** - * enumerate function for item_enumerator_t - */ -static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value) -{ - entry_t *entry; - - if (this->inner->enumerate(this->inner, &entry)) - { - this->current = entry; - *type = entry->type; - *value = entry->value; - return TRUE; - } - return FALSE; -} - -/** - * destroy function for item_enumerator_t - */ -static void entry_enumerator_destroy(entry_enumerator_t *this) -{ - this->inner->destroy(this->inner); - free(this); -} - -/** - * Implementation of auth_cfg_t.create_enumerator. - */ -static enumerator_t* create_enumerator(private_auth_cfg_t *this) -{ - entry_enumerator_t *enumerator; - - enumerator = malloc_thing(entry_enumerator_t); - enumerator->inner = this->entries->create_enumerator(this->entries); - enumerator->public.enumerate = (void*)enumerate; - enumerator->public.destroy = (void*)entry_enumerator_destroy; - enumerator->current = NULL; - return &enumerator->public; -} - -/** - * Destroy the value associated with an entry - */ -static void destroy_entry_value(entry_t *entry) -{ - switch (entry->type) - { - case AUTH_RULE_IDENTITY: - case AUTH_RULE_EAP_IDENTITY: - case AUTH_RULE_AC_GROUP: - { - identification_t *id = (identification_t*)entry->value; - id->destroy(id); - break; - } - case AUTH_RULE_CA_CERT: - case AUTH_RULE_IM_CERT: - case AUTH_RULE_SUBJECT_CERT: - case AUTH_HELPER_IM_CERT: - case AUTH_HELPER_SUBJECT_CERT: - { - certificate_t *cert = (certificate_t*)entry->value; - cert->destroy(cert); - break; - } - case AUTH_HELPER_IM_HASH_URL: - case AUTH_HELPER_SUBJECT_HASH_URL: - { - free(entry->value); - break; - } - case AUTH_RULE_AUTH_CLASS: - case AUTH_RULE_EAP_TYPE: - case AUTH_RULE_EAP_VENDOR: - case AUTH_RULE_CRL_VALIDATION: - case AUTH_RULE_OCSP_VALIDATION: - break; - } -} - -/** - * Implementation of auth_cfg_t.replace. - */ -static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator, - auth_rule_t type, ...) -{ - if (enumerator->current) - { - va_list args; - - va_start(args, type); - - destroy_entry_value(enumerator->current); - enumerator->current->type = type; - switch (type) - { - case AUTH_RULE_AUTH_CLASS: - case AUTH_RULE_EAP_TYPE: - case AUTH_RULE_EAP_VENDOR: - case AUTH_RULE_CRL_VALIDATION: - case AUTH_RULE_OCSP_VALIDATION: - /* integer type */ - enumerator->current->value = (void*)(uintptr_t)va_arg(args, u_int); - break; - case AUTH_RULE_IDENTITY: - case AUTH_RULE_EAP_IDENTITY: - case AUTH_RULE_AC_GROUP: - case AUTH_RULE_CA_CERT: - case AUTH_RULE_IM_CERT: - case AUTH_RULE_SUBJECT_CERT: - case AUTH_HELPER_IM_CERT: - case AUTH_HELPER_SUBJECT_CERT: - case AUTH_HELPER_IM_HASH_URL: - case AUTH_HELPER_SUBJECT_HASH_URL: - /* pointer type */ - enumerator->current->value = va_arg(args, void*); - break; - } - va_end(args); - } -} - -/** - * Implementation of auth_cfg_t.get. - */ -static void* get(private_auth_cfg_t *this, auth_rule_t type) -{ - enumerator_t *enumerator; - void *current_value, *best_value = NULL; - auth_rule_t current_type; - bool found = FALSE; - - enumerator = create_enumerator(this); - while (enumerator->enumerate(enumerator, ¤t_type, ¤t_value)) - { - if (type == current_type) - { - if (type == AUTH_RULE_CRL_VALIDATION || - type == AUTH_RULE_OCSP_VALIDATION) - { /* for CRL/OCSP validation, always get() the highest value */ - if (!found || current_value > best_value) - { - best_value = current_value; - } - found = TRUE; - continue; - } - best_value = current_value; - found = TRUE; - break; - } - } - enumerator->destroy(enumerator); - if (found) - { - return best_value; - } - switch (type) - { - /* use some sane defaults if we don't find an entry */ - case AUTH_RULE_AUTH_CLASS: - return (void*)AUTH_CLASS_ANY; - case AUTH_RULE_EAP_TYPE: - return (void*)EAP_NAK; - case AUTH_RULE_EAP_VENDOR: - return (void*)0; - case AUTH_RULE_CRL_VALIDATION: - case AUTH_RULE_OCSP_VALIDATION: - return (void*)VALIDATION_FAILED; - case AUTH_RULE_IDENTITY: - case AUTH_RULE_EAP_IDENTITY: - case AUTH_RULE_AC_GROUP: - case AUTH_RULE_CA_CERT: - case AUTH_RULE_IM_CERT: - case AUTH_RULE_SUBJECT_CERT: - case AUTH_HELPER_IM_CERT: - case AUTH_HELPER_SUBJECT_CERT: - case AUTH_HELPER_IM_HASH_URL: - case AUTH_HELPER_SUBJECT_HASH_URL: - default: - return NULL; - } -} - -/** - * Implementation of auth_cfg_t.add. - */ -static void add(private_auth_cfg_t *this, auth_rule_t type, ...) -{ - entry_t *entry = malloc_thing(entry_t); - va_list args; - - va_start(args, type); - entry->type = type; - switch (type) - { - case AUTH_RULE_AUTH_CLASS: - case AUTH_RULE_EAP_TYPE: - case AUTH_RULE_EAP_VENDOR: - case AUTH_RULE_CRL_VALIDATION: - case AUTH_RULE_OCSP_VALIDATION: - /* integer type */ - entry->value = (void*)(uintptr_t)va_arg(args, u_int); - break; - case AUTH_RULE_IDENTITY: - case AUTH_RULE_EAP_IDENTITY: - case AUTH_RULE_AC_GROUP: - case AUTH_RULE_CA_CERT: - case AUTH_RULE_IM_CERT: - case AUTH_RULE_SUBJECT_CERT: - case AUTH_HELPER_IM_CERT: - case AUTH_HELPER_SUBJECT_CERT: - case AUTH_HELPER_IM_HASH_URL: - case AUTH_HELPER_SUBJECT_HASH_URL: - /* pointer type */ - entry->value = va_arg(args, void*); - break; - } - va_end(args); - this->entries->insert_last(this->entries, entry); -} - -/** - * Implementation of auth_cfg_t.complies. - */ -static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints, - bool log_error) -{ - enumerator_t *e1, *e2; - bool success = TRUE; - auth_rule_t t1, t2; - void *value; - - e1 = constraints->create_enumerator(constraints); - while (e1->enumerate(e1, &t1, &value)) - { - switch (t1) - { - case AUTH_RULE_CA_CERT: - case AUTH_RULE_IM_CERT: - { - certificate_t *c1, *c2; - - c1 = (certificate_t*)value; - - success = FALSE; - e2 = create_enumerator(this); - while (e2->enumerate(e2, &t2, &c2)) - { - if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) && - c1->equals(c1, c2)) - { - success = TRUE; - } - } - e2->destroy(e2); - if (!success && log_error) - { - DBG1(DBG_CFG, "constraint check failed: peer not " - "authenticated by CA '%Y'.", c1->get_subject(c1)); - } - break; - } - case AUTH_RULE_SUBJECT_CERT: - { - certificate_t *c1, *c2; - - c1 = (certificate_t*)value; - c2 = get(this, AUTH_RULE_SUBJECT_CERT); - if (!c2 || !c1->equals(c1, c2)) - { - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint check failed: peer not " - "authenticated with peer cert '%Y'.", - c1->get_subject(c1)); - } - } - break; - } - case AUTH_RULE_CRL_VALIDATION: - case AUTH_RULE_OCSP_VALIDATION: - { - cert_validation_t validated, required; - - required = (uintptr_t)value; - validated = (uintptr_t)get(this, t1); - switch (required) - { - case VALIDATION_FAILED: - /* no constraint */ - break; - case VALIDATION_SKIPPED: - if (validated == VALIDATION_SKIPPED) - { - break; - } - /* FALL */ - case VALIDATION_GOOD: - if (validated == VALIDATION_GOOD) - { - break; - } - /* FALL */ - default: - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint check failed: %N is %N, " - "but requires at least %N", auth_rule_names, - t1, cert_validation_names, validated, - cert_validation_names, required); - } - break; - } - break; - } - case AUTH_RULE_IDENTITY: - case AUTH_RULE_EAP_IDENTITY: - { - identification_t *id1, *id2; - - id1 = (identification_t*)value; - id2 = get(this, t1); - if (!id2 || !id2->matches(id2, id1)) - { - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'" - " required ", t1 == AUTH_RULE_IDENTITY ? "" : - "EAP ", id1); - } - } - break; - } - case AUTH_RULE_AUTH_CLASS: - { - if ((uintptr_t)value != AUTH_CLASS_ANY && - (uintptr_t)value != (uintptr_t)get(this, t1)) - { - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint requires %N authentication, " - "but %N was used", auth_class_names, (uintptr_t)value, - auth_class_names, (uintptr_t)get(this, t1)); - } - } - break; - } - case AUTH_RULE_EAP_TYPE: - { - if ((uintptr_t)value != (uintptr_t)get(this, t1)) - { - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint requires %N, " - "but %N was used", eap_type_names, (uintptr_t)value, - eap_type_names, (uintptr_t)get(this, t1)); - } - } - break; - } - case AUTH_RULE_EAP_VENDOR: - { - if ((uintptr_t)value != (uintptr_t)get(this, t1)) - { - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint requires EAP vendor %d, " - "but %d was used", (uintptr_t)value, - (uintptr_t)get(this, t1)); - } - } - break; - } - case AUTH_RULE_AC_GROUP: - { - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint check %N not implemented!", - auth_rule_names, t1); - } - break; - } - case AUTH_HELPER_IM_CERT: - case AUTH_HELPER_SUBJECT_CERT: - case AUTH_HELPER_IM_HASH_URL: - case AUTH_HELPER_SUBJECT_HASH_URL: - /* skip helpers */ - continue; - } - if (!success) - { - break; - } - } - e1->destroy(e1); - return success; -} - -/** - * Implementation of auth_cfg_t.merge. - */ -static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy) -{ - if (!other) - { /* nothing to merge */ - return; - } - if (copy) - { - enumerator_t *enumerator; - auth_rule_t type; - void *value; - - enumerator = create_enumerator(other); - while (enumerator->enumerate(enumerator, &type, &value)) - { - switch (type) - { - case AUTH_RULE_CA_CERT: - case AUTH_RULE_IM_CERT: - case AUTH_RULE_SUBJECT_CERT: - case AUTH_HELPER_IM_CERT: - case AUTH_HELPER_SUBJECT_CERT: - { - certificate_t *cert = (certificate_t*)value; - - add(this, type, cert->get_ref(cert)); - break; - } - case AUTH_RULE_CRL_VALIDATION: - case AUTH_RULE_OCSP_VALIDATION: - case AUTH_RULE_AUTH_CLASS: - case AUTH_RULE_EAP_TYPE: - case AUTH_RULE_EAP_VENDOR: - { - add(this, type, (uintptr_t)value); - break; - } - case AUTH_RULE_IDENTITY: - case AUTH_RULE_EAP_IDENTITY: - case AUTH_RULE_AC_GROUP: - { - identification_t *id = (identification_t*)value; - - add(this, type, id->clone(id)); - break; - } - case AUTH_HELPER_IM_HASH_URL: - case AUTH_HELPER_SUBJECT_HASH_URL: - { - add(this, type, strdup((char*)value)); - break; - } - } - } - enumerator->destroy(enumerator); - } - else - { - entry_t *entry; - - while (other->entries->remove_first(other->entries, - (void**)&entry) == SUCCESS) - { - this->entries->insert_last(this->entries, entry); - } - } -} - -/** - * Implementation of auth_cfg_t.equals. - */ -static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other) -{ - enumerator_t *e1, *e2; - entry_t *i1, *i2; - bool equal = TRUE, found; - - if (this->entries->get_count(this->entries) != - other->entries->get_count(other->entries)) - { - return FALSE; - } - e1 = this->entries->create_enumerator(this->entries); - while (e1->enumerate(e1, &i1)) - { - found = FALSE; - e2 = other->entries->create_enumerator(other->entries); - while (e2->enumerate(e2, &i2)) - { - if (i1->type == i2->type) - { - switch (i1->type) - { - case AUTH_RULE_AUTH_CLASS: - case AUTH_RULE_EAP_TYPE: - case AUTH_RULE_EAP_VENDOR: - case AUTH_RULE_CRL_VALIDATION: - case AUTH_RULE_OCSP_VALIDATION: - { - if (i1->value == i2->value) - { - found = TRUE; - break; - } - continue; - } - case AUTH_RULE_CA_CERT: - case AUTH_RULE_IM_CERT: - case AUTH_RULE_SUBJECT_CERT: - case AUTH_HELPER_IM_CERT: - case AUTH_HELPER_SUBJECT_CERT: - { - certificate_t *c1, *c2; - - c1 = (certificate_t*)i1->value; - c2 = (certificate_t*)i2->value; - - if (c1->equals(c1, c2)) - { - found = TRUE; - break; - } - continue; - } - case AUTH_RULE_IDENTITY: - case AUTH_RULE_EAP_IDENTITY: - case AUTH_RULE_AC_GROUP: - { - identification_t *id1, *id2; - - id1 = (identification_t*)i1->value; - id2 = (identification_t*)i2->value; - - if (id1->equals(id1, id2)) - { - found = TRUE; - break; - } - continue; - } - case AUTH_HELPER_IM_HASH_URL: - case AUTH_HELPER_SUBJECT_HASH_URL: - { - if (streq(i1->value, i2->value)) - { - found = TRUE; - break; - } - continue; - } - } - break; - } - } - e2->destroy(e2); - if (!found) - { - equal = FALSE; - break; - } - } - e1->destroy(e1); - return equal; -} - -/** - * Implementation of auth_cfg_t.purge - */ -static void purge(private_auth_cfg_t *this, bool keep_ca) -{ - entry_t *entry; - linked_list_t *cas; - - cas = linked_list_create(); - while (this->entries->remove_last(this->entries, (void**)&entry) == SUCCESS) - { - if (keep_ca && entry->type == AUTH_RULE_CA_CERT) - { - cas->insert_first(cas, entry); - } - else - { - destroy_entry_value(entry); - free(entry); - } - } - while (cas->remove_last(cas, (void**)&entry) == SUCCESS) - { - this->entries->insert_first(this->entries, entry); - } - cas->destroy(cas); -} - -/** - * Implementation of auth_cfg_t.clone - */ -static auth_cfg_t* clone_(private_auth_cfg_t *this) -{ - enumerator_t *enumerator; - auth_cfg_t *clone; - entry_t *entry; - - clone = auth_cfg_create(); - enumerator = this->entries->create_enumerator(this->entries); - while (enumerator->enumerate(enumerator, &entry)) - { - switch (entry->type) - { - case AUTH_RULE_IDENTITY: - case AUTH_RULE_EAP_IDENTITY: - case AUTH_RULE_AC_GROUP: - { - identification_t *id = (identification_t*)entry->value; - clone->add(clone, entry->type, id->clone(id)); - break; - } - case AUTH_RULE_CA_CERT: - case AUTH_RULE_IM_CERT: - case AUTH_RULE_SUBJECT_CERT: - case AUTH_HELPER_IM_CERT: - case AUTH_HELPER_SUBJECT_CERT: - { - certificate_t *cert = (certificate_t*)entry->value; - clone->add(clone, entry->type, cert->get_ref(cert)); - break; - } - case AUTH_HELPER_IM_HASH_URL: - case AUTH_HELPER_SUBJECT_HASH_URL: - { - clone->add(clone, entry->type, strdup(entry->value)); - break; - } - case AUTH_RULE_AUTH_CLASS: - case AUTH_RULE_EAP_TYPE: - case AUTH_RULE_EAP_VENDOR: - case AUTH_RULE_CRL_VALIDATION: - case AUTH_RULE_OCSP_VALIDATION: - clone->add(clone, entry->type, (uintptr_t)entry->value); - break; - } - } - enumerator->destroy(enumerator); - return clone; -} - -/** - * Implementation of auth_cfg_t.destroy - */ -static void destroy(private_auth_cfg_t *this) -{ - purge(this, FALSE); - this->entries->destroy(this->entries); - free(this); -} - -/* - * see header file - */ -auth_cfg_t *auth_cfg_create() -{ - private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t); - - this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add; - this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get; - this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator; - this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace; - this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies; - this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge; - this->public.purge = (void(*)(auth_cfg_t*,bool))purge; - this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals; - this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_; - this->public.destroy = (void(*)(auth_cfg_t*))destroy; - - this->entries = linked_list_create(); - - return &this->public; -} - diff --git a/src/charon/config/auth_cfg.h b/src/charon/config/auth_cfg.h deleted file mode 100644 index 5e6215a4a..000000000 --- a/src/charon/config/auth_cfg.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2007-2009 Martin Willi - * Copyright (C) 2008 Tobias Brunner - * 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. - */ - -/** - * @defgroup auth_cfg auth_cfg - * @{ @ingroup config - */ - -#ifndef AUTH_CFG_H_ -#define AUTH_CFG_H_ - -#include <utils/enumerator.h> - -typedef struct auth_cfg_t auth_cfg_t; -typedef enum auth_rule_t auth_rule_t; - -/** - * Authentication config to use during authentication process. - * - * Each authentication config contains a set of rules. These rule-sets are used - * in two ways: - * - For configs specifying local authentication behavior, the rules define - * which authentication method in which way. - * - For configs specifying remote peer authentication, the rules define - * constraints the peer has to fullfill. - * - * Additionally to the rules, there is a set of helper items. These are used - * to transport credentials during the authentication process. - */ -enum auth_rule_t { - - /** identity to use for IKEv2 authentication exchange, identification_t* */ - AUTH_RULE_IDENTITY, - /** authentication class, auth_class_t */ - AUTH_RULE_AUTH_CLASS, - /** EAP identity to use within EAP-Identity exchange, identification_t* */ - AUTH_RULE_EAP_IDENTITY, - /** EAP type to propose for peer authentication, eap_type_t */ - AUTH_RULE_EAP_TYPE, - /** EAP vendor for vendor specific type, u_int32_t */ - AUTH_RULE_EAP_VENDOR, - /** certificate authority, certificate_t* */ - AUTH_RULE_CA_CERT, - /** intermediate certificate in trustchain, certificate_t* */ - AUTH_RULE_IM_CERT, - /** subject certificate, certificate_t* */ - AUTH_RULE_SUBJECT_CERT, - /** result of a CRL validation, cert_validation_t */ - AUTH_RULE_CRL_VALIDATION, - /** result of a OCSP validation, cert_validation_t */ - AUTH_RULE_OCSP_VALIDATION, - /** subject is in attribute certificate group, identification_t* */ - AUTH_RULE_AC_GROUP, - - /** intermediate certificate, certificate_t* */ - AUTH_HELPER_IM_CERT, - /** subject certificate, certificate_t* */ - AUTH_HELPER_SUBJECT_CERT, - /** Hash and URL of a intermediate certificate, char* */ - AUTH_HELPER_IM_HASH_URL, - /** Hash and URL of a end-entity certificate, char* */ - AUTH_HELPER_SUBJECT_HASH_URL, -}; - -/** - * enum name for auth_rule_t. - */ -extern enum_name_t *auth_rule_names; - -/** - * Authentication/Authorization round. - * - * RFC4739 defines multiple authentication rounds. This class defines such - * a round from a configuration perspective, either for the local or the remote - * peer. Local config are called "rulesets", as they define how we authenticate. - * Remote peer configs are called "constraits", they define what is needed to - * complete the authentication round successfully. - * - * @verbatim - - [Repeat for each configuration] - +--------------------------------------------------+ - | | - | | - | +----------+ IKE_AUTH +--------- + | - | | config | -----------> | | | - | | ruleset | | | | - | +----------+ [ <----------- ] | | | - | [ optional EAP ] | Peer | | - | +----------+ [ -----------> ] | | | - | | config | | | | - | | constr. | <----------- | | | - | +----------+ IKE_AUTH +--------- + | - | | - | | - +--------------------------------------------------+ - - @endverbatim - * - * Values for each items are either pointers (casted to void*) or short - * integers (use uintptr_t cast). - */ -struct auth_cfg_t { - - /** - * Add an rule to the set. - * - * @param rule rule type - * @param ... associated value to rule - */ - void (*add)(auth_cfg_t *this, auth_rule_t rule, ...); - - /** - * Get an rule value. - * - * @param rule rule type - * @return bool if item has been found - */ - void* (*get)(auth_cfg_t *this, auth_rule_t rule); - - /** - * Create an enumerator over added rules. - * - * @return enumerator over (auth_rule_t, union{void*,uintpr_t}) - */ - enumerator_t* (*create_enumerator)(auth_cfg_t *this); - - /** - * Replace an rule at enumerator position. - * - * @param pos enumerator position position - * @param rule rule type - * @param ... associated value to rule - */ - void (*replace)(auth_cfg_t *this, enumerator_t *pos, - auth_rule_t rule, ...); - - /** - * Check if a used config fulfills a set of configured constraints. - * - * @param constraints required authorization rules - * @param log_error wheter to log compliance errors - * @return TRUE if this complies with constraints - */ - bool (*complies)(auth_cfg_t *this, auth_cfg_t *constraints, bool log_error); - - /** - * Merge items from other into this. - * - * @param other items to read for merge - * @param copy TRUE to copy items, FALSE to move them - */ - void (*merge)(auth_cfg_t *this, auth_cfg_t *other, bool copy); - - /** - * Purge all rules in a config. - * - * @param keep_ca wheter to keep AUTH_RULE_CA_CERT entries - */ - void (*purge)(auth_cfg_t *this, bool keep_ca); - - /** - * Check two configs for equality. - * - * @param other other config to compaire against this - * @return TRUE if auth infos identical - */ - bool (*equals)(auth_cfg_t *this, auth_cfg_t *other); - - /** - * Clone a authentication config, including all rules. - * - * @return cloned configuration - */ - auth_cfg_t* (*clone)(auth_cfg_t *this); - - /** - * Destroy a config with all associated rules/values. - */ - void (*destroy)(auth_cfg_t *this); -}; - -/** - * Create a authentication config. - */ -auth_cfg_t *auth_cfg_create(); - -#endif /** AUTH_CFG_H_ @}*/ diff --git a/src/charon/config/backend.h b/src/charon/config/backend.h deleted file mode 100644 index 458abc37f..000000000 --- a/src/charon/config/backend.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2007-2008 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. - */ - -/** - * @defgroup backend backend - * @{ @ingroup config - */ - -#ifndef BACKEND_H_ -#define BACKEND_H_ - -typedef struct backend_t backend_t; - -#include <library.h> -#include <config/ike_cfg.h> -#include <config/peer_cfg.h> -#include <utils/linked_list.h> - -/** - * The interface for a configuration backend. - * - * A configuration backend is loaded into the backend_manager. It does the actual - * configuration lookup for the method it implements. See backend_manager_t for - * more information. - */ -struct backend_t { - - /** - * Create an enumerator over all IKE configs matching two hosts. - * - * Hosts may be NULL to get all. - * - * There is no requirement for the backend to filter the configurations - * using the supplied hosts; but it may do so if it increases lookup times - * (e.g. include hosts in SQL query). - * - * @param me address of local host - * @param other address of remote host - * @return enumerator over ike_cfg_t's - */ - enumerator_t* (*create_ike_cfg_enumerator)(backend_t *this, - host_t *me, host_t *other); - /** - * Create an enumerator over all peer configs matching two identities. - * - * IDs may be NULL to get all. - * - * As configurations are looked up in the first authentication round (when - * multiple authentication), the backend implementation should compare - * the identities to the first auth_cfgs only. - * There is no requirement for the backend to filter the configurations - * using the supplied identities; but it may do so if it increases lookup - * times (e.g. include hosts in SQL query). - * - * @param me identity of ourself - * @param other identity of remote host - * @return enumerator over peer_cfg_t - */ - enumerator_t* (*create_peer_cfg_enumerator)(backend_t *this, - identification_t *me, - identification_t *other); - /** - * Get a peer_cfg identified by it's name, or a name of its children. - * - * @param name name of peer/child cfg - * @return matching peer_config, or NULL if none found - */ - peer_cfg_t *(*get_peer_cfg_by_name)(backend_t *this, char *name); -}; - -#endif /** BACKEND_H_ @}*/ diff --git a/src/charon/config/backend_manager.c b/src/charon/config/backend_manager.c deleted file mode 100644 index 90ef58563..000000000 --- a/src/charon/config/backend_manager.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright (C) 2007-2009 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 "backend_manager.h" - -#include <sys/types.h> - -#include <daemon.h> -#include <utils/linked_list.h> -#include <threading/rwlock.h> - - -typedef struct private_backend_manager_t private_backend_manager_t; - -/** - * Private data of an backend_manager_t object. - */ -struct private_backend_manager_t { - - /** - * Public part of backend_manager_t object. - */ - backend_manager_t public; - - /** - * list of registered backends - */ - linked_list_t *backends; - - /** - * rwlock for backends - */ - rwlock_t *lock; -}; - -/** - * match of an ike_cfg - */ -typedef enum ike_cfg_match_t { - MATCH_NONE = 0x00, - MATCH_ANY = 0x01, - MATCH_ME = 0x04, - MATCH_OTHER = 0x08, -} ike_cfg_match_t; - -/** - * data to pass nested IKE enumerator - */ -typedef struct { - private_backend_manager_t *this; - host_t *me; - host_t *other; -} ike_data_t; - -/** - * inner enumerator constructor for IKE cfgs - */ -static enumerator_t *ike_enum_create(backend_t *backend, ike_data_t *data) -{ - return backend->create_ike_cfg_enumerator(backend, data->me, data->other); -} - -/** - * get a match of a candidate ike_cfg for two hosts - */ -static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other) -{ - host_t *me_cand, *other_cand; - ike_cfg_match_t match = MATCH_NONE; - - if (me) - { - me_cand = host_create_from_dns(cand->get_my_addr(cand), - me->get_family(me), 0); - if (!me_cand) - { - return MATCH_NONE; - } - if (me_cand->ip_equals(me_cand, me)) - { - match += MATCH_ME; - } - else if (me_cand->is_anyaddr(me_cand)) - { - match += MATCH_ANY; - } - me_cand->destroy(me_cand); - } - else - { - match += MATCH_ANY; - } - - if (other) - { - other_cand = host_create_from_dns(cand->get_other_addr(cand), - other->get_family(other), 0); - if (!other_cand) - { - return MATCH_NONE; - } - if (other_cand->ip_equals(other_cand, other)) - { - match += MATCH_OTHER; - } - else if (other_cand->is_anyaddr(other_cand)) - { - match += MATCH_ANY; - } - other_cand->destroy(other_cand); - } - else - { - match += MATCH_ANY; - } - return match; -} - -/** - * implements backend_manager_t.get_ike_cfg. - */ -static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this, - host_t *me, host_t *other) -{ - ike_cfg_t *current, *found = NULL; - enumerator_t *enumerator; - ike_cfg_match_t match, best = MATCH_ANY; - ike_data_t *data; - - data = malloc_thing(ike_data_t); - data->this = this; - data->me = me; - data->other = other; - - DBG2(DBG_CFG, "looking for an ike config for %H...%H", me, other); - - this->lock->read_lock(this->lock); - enumerator = enumerator_create_nested( - this->backends->create_enumerator(this->backends), - (void*)ike_enum_create, data, (void*)free); - while (enumerator->enumerate(enumerator, (void**)¤t)) - { - match = get_ike_match(current, me, other); - - if (match) - { - DBG2(DBG_CFG, " candidate: %s...%s, prio %d", - current->get_my_addr(current), - current->get_other_addr(current), match); - if (match > best) - { - DESTROY_IF(found); - found = current; - found->get_ref(found); - best = match; - } - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - if (found) - { - DBG2(DBG_CFG, "found matching ike config: %s...%s with prio %d", - found->get_my_addr(found), found->get_other_addr(found), best); - } - return found; -} - -/** - * Get the best ID match in one of the configs auth_cfg - */ -static id_match_t get_peer_match(identification_t *id, - peer_cfg_t *cfg, bool local) -{ - enumerator_t *enumerator; - auth_cfg_t *auth; - identification_t *candidate; - id_match_t match = ID_MATCH_NONE; - - if (!id) - { - return ID_MATCH_ANY; - } - - /* compare first auth config only */ - enumerator = cfg->create_auth_cfg_enumerator(cfg, local); - if (enumerator->enumerate(enumerator, &auth)) - { - candidate = auth->get(auth, AUTH_RULE_IDENTITY); - if (candidate) - { - match = id->matches(id, candidate); - /* match vice-versa, as the proposed IDr might be ANY */ - if (!match) - { - match = candidate->matches(candidate, id); - } - } - else - { - match = ID_MATCH_ANY; - } - } - enumerator->destroy(enumerator); - return match; -} - -/** - * data to pass nested peer enumerator - */ -typedef struct { - rwlock_t *lock; - identification_t *me; - identification_t *other; -} peer_data_t; - -/** - * list element to help sorting - */ -typedef struct { - id_match_t match_peer; - ike_cfg_match_t match_ike; - peer_cfg_t *cfg; -} match_entry_t; - -/** - * inner enumerator constructor for peer cfgs - */ -static enumerator_t *peer_enum_create(backend_t *backend, peer_data_t *data) -{ - return backend->create_peer_cfg_enumerator(backend, data->me, data->other); -} - -/** - * unlock/cleanup peer enumerator - */ -static void peer_enum_destroy(peer_data_t *data) -{ - data->lock->unlock(data->lock); - free(data); -} - -/** - * convert enumerator value from match_entry to config - */ -static bool peer_enum_filter(linked_list_t *configs, - match_entry_t **in, peer_cfg_t **out) -{ - *out = (*in)->cfg; - return TRUE; -} - -/** - * Clean up temporary config list - */ -static void peer_enum_filter_destroy(linked_list_t *configs) -{ - match_entry_t *entry; - - while (configs->remove_last(configs, (void**)&entry) == SUCCESS) - { - entry->cfg->destroy(entry->cfg); - free(entry); - } - configs->destroy(configs); -} - -/** - * Insert entry into match-sorted list, using helper - */ -static void insert_sorted(match_entry_t *entry, linked_list_t *list, - linked_list_t *helper) -{ - match_entry_t *current; - - while (list->remove_first(list, (void**)¤t) == SUCCESS) - { - helper->insert_last(helper, current); - } - while (helper->remove_first(helper, (void**)¤t) == SUCCESS) - { - if (entry && ( - (entry->match_ike > current->match_ike && - entry->match_peer >= current->match_peer) || - (entry->match_ike >= current->match_ike && - entry->match_peer > current->match_peer))) - { - list->insert_last(list, entry); - entry = NULL; - } - list->insert_last(list, current); - } - if (entry) - { - list->insert_last(list, entry); - } -} - -/** - * Implements backend_manager_t.create_peer_cfg_enumerator. - */ -static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this, - host_t *me, host_t *other, identification_t *my_id, - identification_t *other_id) -{ - enumerator_t *enumerator; - peer_data_t *data; - peer_cfg_t *cfg; - linked_list_t *configs, *helper; - - data = malloc_thing(peer_data_t); - data->lock = this->lock; - data->me = my_id; - data->other = other_id; - - /* create a sorted list with all matches */ - this->lock->read_lock(this->lock); - enumerator = enumerator_create_nested( - this->backends->create_enumerator(this->backends), - (void*)peer_enum_create, data, (void*)peer_enum_destroy); - - if (!me && !other && !my_id && !other_id) - { /* shortcut if we are doing a "listall" */ - return enumerator; - } - - DBG1(DBG_CFG, "looking for peer configs matching %H[%Y]...%H[%Y]", - me, my_id, other, other_id); - - configs = linked_list_create(); - /* only once allocated helper list for sorting */ - helper = linked_list_create(); - while (enumerator->enumerate(enumerator, &cfg)) - { - id_match_t match_peer_me, match_peer_other; - ike_cfg_match_t match_ike; - match_entry_t *entry; - - match_peer_me = get_peer_match(my_id, cfg, TRUE); - match_peer_other = get_peer_match(other_id, cfg, FALSE); - match_ike = get_ike_match(cfg->get_ike_cfg(cfg), me, other); - - if (match_peer_me && match_peer_other && match_ike) - { - DBG2(DBG_CFG, " candidate \"%s\", match: %d/%d/%d (me/other/ike)", - cfg->get_name(cfg), match_peer_me, match_peer_other, match_ike); - - entry = malloc_thing(match_entry_t); - entry->match_peer = match_peer_me + match_peer_other; - entry->match_ike = match_ike; - entry->cfg = cfg->get_ref(cfg); - insert_sorted(entry, configs, helper); - } - } - enumerator->destroy(enumerator); - helper->destroy(helper); - - return enumerator_create_filter(configs->create_enumerator(configs), - (void*)peer_enum_filter, configs, - (void*)peer_enum_filter_destroy); -} - -/** - * implements backend_manager_t.get_peer_cfg_by_name. - */ -static peer_cfg_t *get_peer_cfg_by_name(private_backend_manager_t *this, char *name) -{ - backend_t *backend; - peer_cfg_t *config = NULL; - enumerator_t *enumerator; - - this->lock->read_lock(this->lock); - enumerator = this->backends->create_enumerator(this->backends); - while (config == NULL && enumerator->enumerate(enumerator, (void**)&backend)) - { - config = backend->get_peer_cfg_by_name(backend, name); - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return config; -} - -/** - * Implementation of backend_manager_t.remove_backend. - */ -static void remove_backend(private_backend_manager_t *this, backend_t *backend) -{ - this->lock->write_lock(this->lock); - this->backends->remove(this->backends, backend, NULL); - this->lock->unlock(this->lock); -} - -/** - * Implementation of backend_manager_t.add_backend. - */ -static void add_backend(private_backend_manager_t *this, backend_t *backend) -{ - this->lock->write_lock(this->lock); - this->backends->insert_last(this->backends, backend); - this->lock->unlock(this->lock); -} - -/** - * Implementation of backend_manager_t.destroy. - */ -static void destroy(private_backend_manager_t *this) -{ - this->backends->destroy(this->backends); - this->lock->destroy(this->lock); - free(this); -} - -/* - * Described in header-file - */ -backend_manager_t *backend_manager_create() -{ - private_backend_manager_t *this = malloc_thing(private_backend_manager_t); - - this->public.get_ike_cfg = (ike_cfg_t* (*)(backend_manager_t*, host_t*, host_t*))get_ike_cfg; - this->public.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_manager_t*,char*))get_peer_cfg_by_name; - this->public.create_peer_cfg_enumerator = (enumerator_t* (*)(backend_manager_t*,host_t*,host_t*,identification_t*,identification_t*))create_peer_cfg_enumerator; - this->public.add_backend = (void(*)(backend_manager_t*, backend_t *backend))add_backend; - this->public.remove_backend = (void(*)(backend_manager_t*, backend_t *backend))remove_backend; - this->public.destroy = (void (*)(backend_manager_t*))destroy; - - this->backends = linked_list_create(); - this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); - - return &this->public; -} - diff --git a/src/charon/config/backend_manager.h b/src/charon/config/backend_manager.h deleted file mode 100644 index 5b394f791..000000000 --- a/src/charon/config/backend_manager.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2007 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. - */ - -/** - * @defgroup backend_manager backend_manager - * @{ @ingroup config - */ - -#ifndef BACKEND_MANAGER_H_ -#define BACKEND_MANAGER_H_ - -typedef struct backend_manager_t backend_manager_t; - -#include <library.h> -#include <utils/host.h> -#include <utils/identification.h> -#include <config/ike_cfg.h> -#include <config/peer_cfg.h> -#include <config/backend.h> - - -/** - * A loader and multiplexer to use multiple backends. - * - * Charon allows the use of multiple configuration backends simultaneously. To - * access all this backends by a single call, this class wraps multiple - * backends behind a single object. - * @verbatim - - +---------+ +-----------+ +--------------+ | - | | | | +--------------+ | | - | daemon |----->| backend_- | +--------------+ |-+ <==|==> IPC - | core | | manager |---->| backends |-+ | - | |----->| | +--------------+ | - | | | | | - +---------+ +-----------+ | - - @endverbatim - */ -struct backend_manager_t { - - /** - * Get an ike_config identified by two hosts. - * - * @param my_host address of own host - * @param other_host address of remote host - * @return matching ike_config, or NULL if none found - */ - ike_cfg_t* (*get_ike_cfg)(backend_manager_t *this, - host_t *my_host, host_t *other_host); - - /** - * Get a peer_config identified by it's name. - * - * @param name name of the peer_config - * @return matching peer_config, or NULL if none found - */ - peer_cfg_t* (*get_peer_cfg_by_name)(backend_manager_t *this, char *name); - - /** - * Create an enumerator over all matching peer configs. - * - * Pass NULL as parameters to match any. The enumerator enumerates over - * peer_cfgs, ordered by priority (best match first). - * - * @param me local address - * @param other remote address - * @param my_id IDr in first authentication round - * @param other_id IDi in first authentication round - * @return enumerator over peer_cfg_t - */ - enumerator_t* (*create_peer_cfg_enumerator)(backend_manager_t *this, - host_t *me, host_t *other, identification_t *my_id, - identification_t *other_id); - /** - * Register a backend on the manager. - * - * @param backend backend to register - */ - void (*add_backend)(backend_manager_t *this, backend_t *backend); - - /** - * Unregister a backend. - * - * @param backend backend to unregister - */ - void (*remove_backend)(backend_manager_t *this, backend_t *backend); - - /** - * Destroys a backend_manager_t object. - */ - void (*destroy) (backend_manager_t *this); -}; - -/** - * Create an instance of the backend manager - * - * @return backend_manager instance - */ -backend_manager_t* backend_manager_create(void); - -#endif /** BACKEND_MANAGER_H_ @}*/ diff --git a/src/charon/config/child_cfg.c b/src/charon/config/child_cfg.c deleted file mode 100644 index 8410b3fe5..000000000 --- a/src/charon/config/child_cfg.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (C) 2008-2009 Tobias Brunner - * Copyright (C) 2005-2007 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 "child_cfg.h" - -#include <daemon.h> - -ENUM(action_names, ACTION_NONE, ACTION_RESTART, - "clear", - "hold", - "restart", -); - -ENUM_BEGIN(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_NONE, - "IPCOMP_NONE"); -ENUM_NEXT(ipcomp_transform_names, IPCOMP_OUI, IPCOMP_LZJH, IPCOMP_NONE, - "IPCOMP_OUI", - "IPCOMP_DEFLATE", - "IPCOMP_LZS", - "IPCOMP_LZJH"); -ENUM_END(ipcomp_transform_names, IPCOMP_LZJH); - -typedef struct private_child_cfg_t private_child_cfg_t; - -/** - * Private data of an child_cfg_t object - */ -struct private_child_cfg_t { - - /** - * Public part - */ - child_cfg_t public; - - /** - * Number of references hold by others to this child_cfg - */ - refcount_t refcount; - - /** - * Name of the child_cfg, used to query it - */ - char *name; - - /** - * list for all proposals - */ - linked_list_t *proposals; - - /** - * list for traffic selectors for my site - */ - linked_list_t *my_ts; - - /** - * list for traffic selectors for others site - */ - linked_list_t *other_ts; - - /** - * updown script - */ - char *updown; - - /** - * allow host access - */ - bool hostaccess; - - /** - * Mode to propose for a initiated CHILD: tunnel/transport - */ - ipsec_mode_t mode; - - /** - * action to take on DPD - */ - action_t dpd_action; - - /** - * action to take on CHILD_SA close - */ - action_t close_action; - - /** - * CHILD_SA lifetime config - */ - lifetime_cfg_t lifetime; - - /** - * enable IPComp - */ - bool use_ipcomp; - - /** - * Inactivity timeout - */ - u_int32_t inactivity; - - /** - * set up IPsec transport SA in MIPv6 proxy mode - */ - bool proxy_mode; - - /** - * enable installation and removal of kernel IPsec policies - */ - bool install_policy; -}; - -/** - * Implementation of child_cfg_t.get_name. - */ -static char *get_name(private_child_cfg_t *this) -{ - return this->name; -} - -/** - * Implementation of child_cfg_t.add_proposal. - */ -static void add_proposal(private_child_cfg_t *this, proposal_t *proposal) -{ - this->proposals->insert_last(this->proposals, proposal); -} - -/** - * Implementation of child_cfg_t.get_proposals. - */ -static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh) -{ - enumerator_t *enumerator; - proposal_t *current; - linked_list_t *proposals = linked_list_create(); - - enumerator = this->proposals->create_enumerator(this->proposals); - while (enumerator->enumerate(enumerator, ¤t)) - { - current = current->clone(current); - if (strip_dh) - { - current->strip_dh(current); - } - proposals->insert_last(proposals, current); - } - enumerator->destroy(enumerator); - - return proposals; -} - -/** - * Implementation of child_cfg_t.select_proposal. - */ -static proposal_t* select_proposal(private_child_cfg_t*this, - linked_list_t *proposals, bool strip_dh, - bool private) -{ - enumerator_t *stored_enum, *supplied_enum; - proposal_t *stored, *supplied, *selected = NULL; - - stored_enum = this->proposals->create_enumerator(this->proposals); - supplied_enum = proposals->create_enumerator(proposals); - - /* compare all stored proposals with all supplied. Stored ones are preferred. */ - while (stored_enum->enumerate(stored_enum, &stored)) - { - stored = stored->clone(stored); - while (supplied_enum->enumerate(supplied_enum, &supplied)) - { - if (strip_dh) - { - stored->strip_dh(stored); - } - selected = stored->select(stored, supplied, private); - if (selected) - { - DBG2(DBG_CFG, "received proposals: %#P", proposals); - DBG2(DBG_CFG, "configured proposals: %#P", this->proposals); - DBG2(DBG_CFG, "selected proposal: %P", selected); - break; - } - } - stored->destroy(stored); - if (selected) - { - break; - } - supplied_enum->destroy(supplied_enum); - supplied_enum = proposals->create_enumerator(proposals); - } - stored_enum->destroy(stored_enum); - supplied_enum->destroy(supplied_enum); - if (selected == NULL) - { - DBG1(DBG_CFG, "received proposals: %#P", proposals); - DBG1(DBG_CFG, "configured proposals: %#P", this->proposals); - } - return selected; -} - -/** - * Implementation of child_cfg_t.add_traffic_selector. - */ -static void add_traffic_selector(private_child_cfg_t *this, bool local, - traffic_selector_t *ts) -{ - if (local) - { - this->my_ts->insert_last(this->my_ts, ts); - } - else - { - this->other_ts->insert_last(this->other_ts, ts); - } -} - -/** - * Implementation of child_cfg_t.get_traffic_selectors. - */ -static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool local, - linked_list_t *supplied, - host_t *host) -{ - enumerator_t *e1, *e2; - traffic_selector_t *ts1, *ts2, *selected; - linked_list_t *result = linked_list_create(); - - if (local) - { - e1 = this->my_ts->create_enumerator(this->my_ts); - } - else - { - e1 = this->other_ts->create_enumerator(this->other_ts); - } - - /* no list supplied, just fetch the stored traffic selectors */ - if (supplied == NULL) - { - DBG2(DBG_CFG, "proposing traffic selectors for %s:", - local ? "us" : "other"); - while (e1->enumerate(e1, &ts1)) - { - /* we make a copy of the TS, this allows us to update dynamic TS' */ - selected = ts1->clone(ts1); - if (host) - { - selected->set_address(selected, host); - } - DBG2(DBG_CFG, " %R (derived from %R)", selected, ts1); - result->insert_last(result, selected); - } - e1->destroy(e1); - } - else - { - DBG2(DBG_CFG, "selecting traffic selectors for %s:", - local ? "us" : "other"); - e2 = supplied->create_enumerator(supplied); - /* iterate over all stored selectors */ - while (e1->enumerate(e1, &ts1)) - { - /* we make a copy of the TS, as we have to update dynamic TS' */ - ts1 = ts1->clone(ts1); - if (host) - { - ts1->set_address(ts1, host); - } - - /* iterate over all supplied traffic selectors */ - while (e2->enumerate(e2, &ts2)) - { - selected = ts1->get_subset(ts1, ts2); - if (selected) - { - DBG2(DBG_CFG, " config: %R, received: %R => match: %R", - ts1, ts2, selected); - result->insert_last(result, selected); - } - else - { - DBG2(DBG_CFG, " config: %R, received: %R => no match", - ts1, ts2); - } - } - e2->destroy(e2); - e2 = supplied->create_enumerator(supplied); - ts1->destroy(ts1); - } - e1->destroy(e1); - e2->destroy(e2); - } - - /* remove any redundant traffic selectors in the list */ - e1 = result->create_enumerator(result); - e2 = result->create_enumerator(result); - while (e1->enumerate(e1, &ts1)) - { - while (e2->enumerate(e2, &ts2)) - { - if (ts1 != ts2) - { - if (ts2->is_contained_in(ts2, ts1)) - { - result->remove_at(result, e2); - ts2->destroy(ts2); - e1->destroy(e1); - e1 = result->create_enumerator(result); - break; - } - if (ts1->is_contained_in(ts1, ts2)) - { - result->remove_at(result, e1); - ts1->destroy(ts1); - e2->destroy(e2); - e2 = result->create_enumerator(result); - break; - } - } - } - } - e1->destroy(e1); - e2->destroy(e2); - - return result; -} - -/** - * Implementation of child_cfg_t.get_updown. - */ -static char* get_updown(private_child_cfg_t *this) -{ - return this->updown; -} - -/** - * Implementation of child_cfg_t.get_hostaccess. - */ -static bool get_hostaccess(private_child_cfg_t *this) -{ - return this->hostaccess; -} - -/** - * Applies jitter to the rekey value. Returns the new rekey value. - * Note: The distribution of random values is not perfect, but it - * should get the job done. - */ -static u_int64_t apply_jitter(u_int64_t rekey, u_int64_t jitter) -{ - if (jitter == 0) - { - return rekey; - } - jitter = (jitter == UINT64_MAX) ? jitter : jitter + 1; - return rekey - jitter * (random() / (RAND_MAX + 1.0)); -} -#define APPLY_JITTER(l) l.rekey = apply_jitter(l.rekey, l.jitter) - -/** - * Implementation of child_cfg_t.get_lifetime. - */ -static lifetime_cfg_t *get_lifetime(private_child_cfg_t *this) -{ - lifetime_cfg_t *lft = malloc_thing(lifetime_cfg_t); - memcpy(lft, &this->lifetime, sizeof(lifetime_cfg_t)); - APPLY_JITTER(lft->time); - APPLY_JITTER(lft->bytes); - APPLY_JITTER(lft->packets); - return lft; -} - -/** - * Implementation of child_cfg_t.get_mode. - */ -static ipsec_mode_t get_mode(private_child_cfg_t *this) -{ - return this->mode; -} - -/** - * Implementation of child_cfg_t.get_dpd_action. - */ -static action_t get_dpd_action(private_child_cfg_t *this) -{ - return this->dpd_action; -} - -/** - * Implementation of child_cfg_t.get_close_action. - */ -static action_t get_close_action(private_child_cfg_t *this) -{ - return this->close_action; -} - -/** - * Implementation of child_cfg_t.get_dh_group. - */ -static diffie_hellman_group_t get_dh_group(private_child_cfg_t *this) -{ - enumerator_t *enumerator; - proposal_t *proposal; - u_int16_t dh_group = MODP_NONE; - - enumerator = this->proposals->create_enumerator(this->proposals); - while (enumerator->enumerate(enumerator, &proposal)) - { - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &dh_group, NULL)) - { - break; - } - } - enumerator->destroy(enumerator); - return dh_group; -} - -/** - * Implementation of child_cfg_t.use_ipcomp. - */ -static bool use_ipcomp(private_child_cfg_t *this) -{ - return this->use_ipcomp; -} - -/** - * Implementation of child_cfg_t.get_inactivity. - */ -static u_int32_t get_inactivity(private_child_cfg_t *this) -{ - return this->inactivity; -} - -/** - * Implementation of child_cfg_t.set_mipv6_options. - */ -static void set_mipv6_options(private_child_cfg_t *this, bool proxy_mode, - bool install_policy) -{ - this->proxy_mode = proxy_mode; - this->install_policy = install_policy; -} - -/** - * Implementation of child_cfg_t.use_proxy_mode. - */ -static bool use_proxy_mode(private_child_cfg_t *this) -{ - return this->proxy_mode; -} - -/** - * Implementation of child_cfg_t.install_policy. - */ -static bool install_policy(private_child_cfg_t *this) -{ - return this->install_policy; -} - -/** - * Implementation of child_cfg_t.get_ref. - */ -static child_cfg_t* get_ref(private_child_cfg_t *this) -{ - ref_get(&this->refcount); - return &this->public; -} - -/** - * Implements child_cfg_t.destroy. - */ -static void destroy(private_child_cfg_t *this) -{ - if (ref_put(&this->refcount)) - { - this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy)); - this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy)); - this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy)); - if (this->updown) - { - free(this->updown); - } - free(this->name); - free(this); - } -} - -/* - * Described in header-file - */ -child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime, - char *updown, bool hostaccess, - ipsec_mode_t mode, action_t dpd_action, - action_t close_action, bool ipcomp, - u_int32_t inactivity) -{ - private_child_cfg_t *this = malloc_thing(private_child_cfg_t); - - this->public.get_name = (char* (*) (child_cfg_t*))get_name; - this->public.add_traffic_selector = (void (*)(child_cfg_t*,bool,traffic_selector_t*))add_traffic_selector; - this->public.get_traffic_selectors = (linked_list_t*(*)(child_cfg_t*,bool,linked_list_t*,host_t*))get_traffic_selectors; - this->public.add_proposal = (void (*) (child_cfg_t*,proposal_t*))add_proposal; - this->public.get_proposals = (linked_list_t* (*) (child_cfg_t*,bool))get_proposals; - this->public.select_proposal = (proposal_t* (*) (child_cfg_t*,linked_list_t*,bool,bool))select_proposal; - this->public.get_updown = (char* (*) (child_cfg_t*))get_updown; - this->public.get_hostaccess = (bool (*) (child_cfg_t*))get_hostaccess; - this->public.get_mode = (ipsec_mode_t (*) (child_cfg_t *))get_mode; - this->public.get_dpd_action = (action_t (*) (child_cfg_t *))get_dpd_action; - this->public.get_close_action = (action_t (*) (child_cfg_t *))get_close_action; - this->public.get_lifetime = (lifetime_cfg_t* (*) (child_cfg_t *))get_lifetime; - this->public.get_dh_group = (diffie_hellman_group_t(*)(child_cfg_t*)) get_dh_group; - this->public.set_mipv6_options = (void (*) (child_cfg_t*,bool,bool))set_mipv6_options; - this->public.use_ipcomp = (bool (*) (child_cfg_t *))use_ipcomp; - this->public.get_inactivity = (u_int32_t (*) (child_cfg_t *))get_inactivity; - this->public.use_proxy_mode = (bool (*) (child_cfg_t *))use_proxy_mode; - this->public.install_policy = (bool (*) (child_cfg_t *))install_policy; - this->public.get_ref = (child_cfg_t* (*) (child_cfg_t*))get_ref; - this->public.destroy = (void (*) (child_cfg_t*))destroy; - - this->name = strdup(name); - this->updown = updown ? strdup(updown) : NULL; - this->hostaccess = hostaccess; - this->mode = mode; - this->dpd_action = dpd_action; - this->close_action = close_action; - this->use_ipcomp = ipcomp; - this->inactivity = inactivity; - this->proxy_mode = FALSE; - this->install_policy = TRUE; - this->refcount = 1; - this->proposals = linked_list_create(); - this->my_ts = linked_list_create(); - this->other_ts = linked_list_create(); - memcpy(&this->lifetime, lifetime, sizeof(lifetime_cfg_t)); - - return &this->public; -} - diff --git a/src/charon/config/child_cfg.h b/src/charon/config/child_cfg.h deleted file mode 100644 index c6186ea36..000000000 --- a/src/charon/config/child_cfg.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (C) 2008-2009 Tobias Brunner - * Copyright (C) 2005-2007 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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. - */ - -/** - * @defgroup child_cfg child_cfg - * @{ @ingroup config - */ - -#ifndef CHILD_CFG_H_ -#define CHILD_CFG_H_ - -typedef enum action_t action_t; -typedef enum ipcomp_transform_t ipcomp_transform_t; -typedef struct lifetime_cfg_t lifetime_cfg_t; -typedef struct child_cfg_t child_cfg_t; - -#include <library.h> -#include <selectors/traffic_selector.h> -#include <config/proposal.h> -#include <kernel/kernel_ipsec.h> - -/** - * Action to take when DPD detected/connection gets closed by peer. - */ -enum action_t { - /** No action */ - ACTION_NONE, - /** Route config to reestablish on demand */ - ACTION_ROUTE, - /** Restart config immediately */ - ACTION_RESTART, -}; - -/** - * enum names for action_t. - */ -extern enum_name_t *action_names; - -/** - * IPComp transform IDs, as in RFC 4306 - */ -enum ipcomp_transform_t { - IPCOMP_NONE = 241, - IPCOMP_OUI = 1, - IPCOMP_DEFLATE = 2, - IPCOMP_LZS = 3, - IPCOMP_LZJH = 4, -}; - -/** - * enum strings for ipcomp_transform_t. - */ -extern enum_name_t *ipcomp_transform_names; - -/** - * A lifetime_cfg_t defines the lifetime limits of a CHILD_SA. - * - * Set any of these values to 0 to ignore. - */ -struct lifetime_cfg_t { - struct { - /** Limit before the CHILD_SA gets invalid. */ - u_int64_t life; - /** Limit before the CHILD_SA gets rekeyed. */ - u_int64_t rekey; - /** The range of a random value subtracted from rekey. */ - u_int64_t jitter; - } time, bytes, packets; -}; - -/** - * A child_cfg_t defines the config template for a CHILD_SA. - * - * After creation, proposals and traffic selectors may be added to the config. - * A child_cfg object is referenced multiple times, and is not thread save. - * Reading from the object is save, adding things is not allowed while other - * threads may access the object. - * A reference counter handles the number of references hold to this config. - * - * @see peer_cfg_t to get an overview over the configurations. - */ -struct child_cfg_t { - - /** - * Get the name of the child_cfg. - * - * @return child_cfg's name - */ - char *(*get_name) (child_cfg_t *this); - - /** - * Add a proposal to the list. - * - * The proposals are stored by priority, first added - * is the most prefered. - * After add, proposal is owned by child_cfg. - * - * @param proposal proposal to add - */ - void (*add_proposal) (child_cfg_t *this, proposal_t *proposal); - - /** - * Get the list of proposals for the CHILD_SA. - * - * Resulting list and all of its proposals must be freed after use. - * - * @param strip_dh TRUE strip out diffie hellman groups - * @return list of proposals - */ - linked_list_t* (*get_proposals)(child_cfg_t *this, bool strip_dh); - - /** - * Select a proposal from a supplied list. - * - * Returned propsal is newly created and must be destroyed after usage. - * - * @param proposals list from from wich proposals are selected - * @param strip_dh TRUE strip out diffie hellman groups - * @param private accept algorithms from a private range - * @return selected proposal, or NULL if nothing matches - */ - proposal_t* (*select_proposal)(child_cfg_t*this, linked_list_t *proposals, - bool strip_dh, bool private); - - /** - * Add a traffic selector to the config. - * - * Use the "local" parameter to add it for the local or the remote side. - * After add, traffic selector is owned by child_cfg. - * - * @param local TRUE for local side, FALSE for remote - * @param ts traffic_selector to add - */ - void (*add_traffic_selector)(child_cfg_t *this, bool local, - traffic_selector_t *ts); - - /** - * Get a list of traffic selectors to use for the CHILD_SA. - * - * The config contains two set of traffic selectors, one for the local - * side, one for the remote side. - * If a list with traffic selectors is supplied, these are used to narrow - * down the traffic selector list to the greatest common divisor. - * Some traffic selector may be "dymamic", meaning they are narrowed down - * to a specific address (host-to-host or virtual-IP setups). Use - * the "host" parameter to narrow such traffic selectors to that address. - * Resulted list and its traffic selectors must be destroyed after use. - * - * @param local TRUE for TS on local side, FALSE for remote - * @param supplied list with TS to select from, or NULL - * @param host address to use for narrowing "dynamic" TS', or NULL - * @return list containing the traffic selectors - */ - linked_list_t *(*get_traffic_selectors)(child_cfg_t *this, bool local, - linked_list_t *supplied, - host_t *host); - /** - * Get the updown script to run for the CHILD_SA. - * - * @return path to updown script - */ - char* (*get_updown)(child_cfg_t *this); - - /** - * Should we allow access to the local host (gateway)? - * - * @return value of hostaccess flag - */ - bool (*get_hostaccess) (child_cfg_t *this); - - /** - * Get the lifetime configuration of a CHILD_SA. - * - * The rekey limits automatically contain a jitter to avoid simultaneous - * rekeying. These values will change with each call to this function. - * - * @return lifetime_cfg_t (has to be freed) - */ - lifetime_cfg_t* (*get_lifetime) (child_cfg_t *this); - - /** - * Get the mode to use for the CHILD_SA. - * - * The mode is either tunnel, transport or BEET. The peer must agree - * on the method, fallback is tunnel mode. - * - * @return ipsec mode - */ - ipsec_mode_t (*get_mode) (child_cfg_t *this); - - /** - * Action to take on DPD. - * - * @return DPD action - */ - action_t (*get_dpd_action) (child_cfg_t *this); - - /** - * Action to take if CHILD_SA gets closed. - * - * @return close action - */ - action_t (*get_close_action) (child_cfg_t *this); - - /** - * Get the DH group to use for CHILD_SA setup. - * - * @return dh group to use - */ - diffie_hellman_group_t (*get_dh_group)(child_cfg_t *this); - - /** - * Check whether IPComp should be used, if the other peer supports it. - * - * @return TRUE, if IPComp should be used - * FALSE, otherwise - */ - bool (*use_ipcomp)(child_cfg_t *this); - - /** - * Get the inactivity timeout value. - * - * @return inactivity timeout in s - */ - u_int32_t (*get_inactivity)(child_cfg_t *this); - - /** - * Sets two options needed for Mobile IPv6 interoperability - * - * @param proxy_mode use IPsec transport proxy mode (default FALSE) - * @param install_policy install IPsec kernel policies (default TRUE) - */ - void (*set_mipv6_options)(child_cfg_t *this, bool proxy_mode, - bool install_policy); - - /** - * Check whether IPsec transport SA should be set up in proxy mode - * - * @return TRUE, if proxy mode should be used - * FALSE, otherwise - */ - bool (*use_proxy_mode)(child_cfg_t *this); - - /** - * Check whether IPsec policies should be installed in the kernel - * - * @return TRUE, if IPsec kernel policies should be installed - * FALSE, otherwise - */ - bool (*install_policy)(child_cfg_t *this); - - /** - * Increase the reference count. - * - * @return reference to this - */ - child_cfg_t* (*get_ref) (child_cfg_t *this); - - /** - * Destroys the child_cfg object. - * - * Decrements the internal reference counter and - * destroys the child_cfg when it reaches zero. - */ - void (*destroy) (child_cfg_t *this); -}; - -/** - * Create a configuration template for CHILD_SA setup. - * - * The "name" string gets cloned. - * - * The lifetime_cfg_t object gets cloned. - * To prevent two peers to start rekeying at the same time, a jitter may be - * specified. Rekeying of an SA starts at (x.rekey - random(0, x.jitter)). - * - * After a call to create, a reference is obtained (refcount = 1). - * - * @param name name of the child_cfg - * @param lifetime lifetime_cfg_t for this child_cfg - * @param updown updown script to execute on up/down event - * @param hostaccess TRUE to allow access to the local host - * @param mode mode to propose for CHILD_SA, transport, tunnel or BEET - * @param dpd_action DPD action - * @param close_action close action - * @param ipcomp use IPComp, if peer supports it - * @param inactivity inactivity timeout in s before closing a CHILD_SA - * @return child_cfg_t object - */ -child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime, - char *updown, bool hostaccess, - ipsec_mode_t mode, action_t dpd_action, - action_t close_action, bool ipcomp, - u_int32_t inactivity); - -#endif /** CHILD_CFG_H_ @}*/ diff --git a/src/charon/config/ike_cfg.c b/src/charon/config/ike_cfg.c deleted file mode 100644 index 2e748f511..000000000 --- a/src/charon/config/ike_cfg.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2005-2007 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 "ike_cfg.h" - -#include <string.h> - -#include <daemon.h> - - -typedef struct private_ike_cfg_t private_ike_cfg_t; - -/** - * Private data of an ike_cfg_t object - */ -struct private_ike_cfg_t { - - /** - * Public part - */ - ike_cfg_t public; - - /** - * Number of references hold by others to this ike_cfg - */ - refcount_t refcount; - - /** - * Address of local host - */ - char *me; - - /** - * Address of remote host - */ - char *other; - - /** - * should we send a certificate request? - */ - bool certreq; - - /** - * enforce UDP encapsulation - */ - bool force_encap; - - /** - * List of proposals to use - */ - linked_list_t *proposals; -}; - -/** - * Implementation of ike_cfg_t.certreq. - */ -static bool send_certreq(private_ike_cfg_t *this) -{ - return this->certreq; -} - -/** - * Implementation of ike_cfg_t.force_encap. - */ -static bool force_encap_meth(private_ike_cfg_t *this) -{ - return this->force_encap; -} - -/** - * Implementation of ike_cfg_t.get_my_addr. - */ -static char *get_my_addr(private_ike_cfg_t *this) -{ - return this->me; -} - -/** - * Implementation of ike_cfg_t.get_other_addr. - */ -static char *get_other_addr(private_ike_cfg_t *this) -{ - return this->other; -} - -/** - * Implementation of ike_cfg_t.add_proposal. - */ -static void add_proposal(private_ike_cfg_t *this, proposal_t *proposal) -{ - this->proposals->insert_last(this->proposals, proposal); -} - -/** - * Implementation of ike_cfg_t.get_proposals. - */ -static linked_list_t* get_proposals(private_ike_cfg_t *this) -{ - iterator_t *iterator; - proposal_t *current; - linked_list_t *proposals = linked_list_create(); - - iterator = this->proposals->create_iterator(this->proposals, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - current = current->clone(current); - proposals->insert_last(proposals, (void*)current); - } - iterator->destroy(iterator); - - return proposals; -} - -/** - * Implementation of ike_cfg_t.select_proposal. - */ -static proposal_t *select_proposal(private_ike_cfg_t *this, - linked_list_t *proposals, bool private) -{ - iterator_t *stored_iter, *supplied_iter; - proposal_t *stored, *supplied, *selected; - - stored_iter = this->proposals->create_iterator(this->proposals, TRUE); - supplied_iter = proposals->create_iterator(proposals, TRUE); - - - /* compare all stored proposals with all supplied. Stored ones are preferred.*/ - while (stored_iter->iterate(stored_iter, (void**)&stored)) - { - supplied_iter->reset(supplied_iter); - - while (supplied_iter->iterate(supplied_iter, (void**)&supplied)) - { - selected = stored->select(stored, supplied, private); - if (selected) - { - /* they match, return */ - stored_iter->destroy(stored_iter); - supplied_iter->destroy(supplied_iter); - DBG2(DBG_CFG, "received proposals: %#P", proposals); - DBG2(DBG_CFG, "configured proposals: %#P", this->proposals); - DBG2(DBG_CFG, "selected proposal: %P", selected); - return selected; - } - } - } - /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */ - stored_iter->destroy(stored_iter); - supplied_iter->destroy(supplied_iter); - DBG1(DBG_CFG, "received proposals: %#P", proposals); - DBG1(DBG_CFG, "configured proposals: %#P", this->proposals); - - return NULL; -} - -/** - * Implementation of ike_cfg_t.get_dh_group. - */ -static diffie_hellman_group_t get_dh_group(private_ike_cfg_t *this) -{ - enumerator_t *enumerator; - proposal_t *proposal; - u_int16_t dh_group = MODP_NONE; - - enumerator = this->proposals->create_enumerator(this->proposals); - while (enumerator->enumerate(enumerator, &proposal)) - { - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &dh_group, NULL)) - { - break; - } - } - enumerator->destroy(enumerator); - return dh_group; -} - -/** - * Implementation of ike_cfg_t.equals. - */ -static bool equals(private_ike_cfg_t *this, private_ike_cfg_t *other) -{ - enumerator_t *e1, *e2; - proposal_t *p1, *p2; - bool eq = TRUE; - - if (this == other) - { - return TRUE; - } - if (this->public.equals != other->public.equals) - { - return FALSE; - } - if (this->proposals->get_count(this->proposals) != - other->proposals->get_count(other->proposals)) - { - return FALSE; - } - e1 = this->proposals->create_enumerator(this->proposals); - e2 = this->proposals->create_enumerator(this->proposals); - while (e1->enumerate(e1, &p1) && e2->enumerate(e2, &p2)) - { - if (!p1->equals(p1, p2)) - { - eq = FALSE; - break; - } - } - e1->destroy(e1); - e2->destroy(e2); - - return (eq && - this->certreq == other->certreq && - this->force_encap == other->force_encap && - streq(this->me, other->me) && - streq(this->other, other->other)); -} - -/** - * Implementation of ike_cfg_t.get_ref. - */ -static ike_cfg_t* get_ref(private_ike_cfg_t *this) -{ - ref_get(&this->refcount); - return &this->public; -} - -/** - * Implementation of ike_cfg_t.destroy. - */ -static void destroy(private_ike_cfg_t *this) -{ - if (ref_put(&this->refcount)) - { - this->proposals->destroy_offset(this->proposals, - offsetof(proposal_t, destroy)); - free(this->me); - free(this->other); - free(this); - } -} - -/** - * Described in header. - */ -ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap, - char *me, char *other) -{ - private_ike_cfg_t *this = malloc_thing(private_ike_cfg_t); - - /* public functions */ - this->public.send_certreq = (bool(*)(ike_cfg_t*))send_certreq; - this->public.force_encap = (bool (*) (ike_cfg_t *))force_encap_meth; - this->public.get_my_addr = (char*(*)(ike_cfg_t*))get_my_addr; - this->public.get_other_addr = (char*(*)(ike_cfg_t*))get_other_addr; - this->public.add_proposal = (void(*)(ike_cfg_t*, proposal_t*)) add_proposal; - this->public.get_proposals = (linked_list_t*(*)(ike_cfg_t*))get_proposals; - this->public.select_proposal = (proposal_t*(*)(ike_cfg_t*,linked_list_t*,bool))select_proposal; - this->public.get_dh_group = (diffie_hellman_group_t(*)(ike_cfg_t*)) get_dh_group; - this->public.equals = (bool(*)(ike_cfg_t*,ike_cfg_t*)) equals; - this->public.get_ref = (ike_cfg_t*(*)(ike_cfg_t*))get_ref; - this->public.destroy = (void(*)(ike_cfg_t*))destroy; - - /* private variables */ - this->refcount = 1; - this->certreq = certreq; - this->force_encap = force_encap; - this->me = strdup(me); - this->other = strdup(other); - this->proposals = linked_list_create(); - - return &this->public; -} diff --git a/src/charon/config/ike_cfg.h b/src/charon/config/ike_cfg.h deleted file mode 100644 index eaac321b9..000000000 --- a/src/charon/config/ike_cfg.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2005-2007 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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. - */ - -/** - * @defgroup ike_cfg ike_cfg - * @{ @ingroup config - */ - -#ifndef IKE_CFG_H_ -#define IKE_CFG_H_ - -typedef struct ike_cfg_t ike_cfg_t; - -#include <library.h> -#include <utils/host.h> -#include <utils/linked_list.h> -#include <utils/identification.h> -#include <config/proposal.h> -#include <crypto/diffie_hellman.h> - -/** - * An ike_cfg_t defines the rules to set up an IKE_SA. - * - * @see peer_cfg_t to get an overview over the configurations. - */ -struct ike_cfg_t { - - /** - * Get own address. - * - * @return string of address/DNS name - */ - char* (*get_my_addr) (ike_cfg_t *this); - - /** - * Get peers address. - * - * @return string of address/DNS name - */ - char* (*get_other_addr) (ike_cfg_t *this); - - /** - * Adds a proposal to the list. - * - * The first added proposal has the highest priority, the last - * added the lowest. - * - * @param proposal proposal to add - */ - void (*add_proposal) (ike_cfg_t *this, proposal_t *proposal); - - /** - * Returns a list of all supported proposals. - * - * Returned list and its proposals must be destroyed after use. - * - * @return list containing all the proposals - */ - linked_list_t* (*get_proposals) (ike_cfg_t *this); - - /** - * Select a proposed from suggested proposals. - * - * Returned proposal must be destroyed after use. - * - * @param proposals list of proposals to select from - * @param private accept algorithms from a private range - * @return selected proposal, or NULL if none matches. - */ - proposal_t *(*select_proposal) (ike_cfg_t *this, linked_list_t *proposals, - bool private); - - /** - * Should we send a certificate request in IKE_SA_INIT? - * - * @return certificate request sending policy - */ - bool (*send_certreq) (ike_cfg_t *this); - - /** - * Enforce UDP encapsulation by faking NATD notifies? - * - * @return TRUE to enfoce UDP encapsulation - */ - bool (*force_encap) (ike_cfg_t *this); - - /** - * Get the DH group to use for IKE_SA setup. - * - * @return dh group to use for initialization - */ - diffie_hellman_group_t (*get_dh_group)(ike_cfg_t *this); - - /** - * Check if two IKE configs are equal. - * - * @param other other to check for equality - * @return TRUE if other equal to this - */ - bool (*equals)(ike_cfg_t *this, ike_cfg_t *other); - - /** - * Increase reference count. - * - * @return reference to this - */ - ike_cfg_t* (*get_ref) (ike_cfg_t *this); - - /** - * Destroys a ike_cfg_t object. - * - * Decrements the internal reference counter and - * destroys the ike_cfg when it reaches zero. - */ - void (*destroy) (ike_cfg_t *this); -}; - -/** - * Creates a ike_cfg_t object. - * - * Supplied hosts become owned by ike_cfg, the name gets cloned. - * - * @param certreq TRUE to send a certificate request - * @param force_encap enforce UDP encapsulation by faking NATD notify - * @param me address/DNS name of local peer - * @param other address/DNS name of remote peer - * @return ike_cfg_t object. - */ -ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap, - char *me, char *other); - -#endif /** IKE_CFG_H_ @}*/ diff --git a/src/charon/config/peer_cfg.c b/src/charon/config/peer_cfg.c deleted file mode 100644 index 9df14c9ae..000000000 --- a/src/charon/config/peer_cfg.c +++ /dev/null @@ -1,699 +0,0 @@ -/* - * Copyright (C) 2007-2008 Tobias Brunner - * Copyright (C) 2005-2009 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 <string.h> - -#include "peer_cfg.h" - -#include <daemon.h> - -#include <threading/mutex.h> -#include <utils/linked_list.h> -#include <utils/identification.h> - -ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND, - "CERT_ALWAYS_SEND", - "CERT_SEND_IF_ASKED", - "CERT_NEVER_SEND", -); - -ENUM(unique_policy_names, UNIQUE_NO, UNIQUE_KEEP, - "UNIQUE_NO", - "UNIQUE_REPLACE", - "UNIQUE_KEEP", -); - -typedef struct private_peer_cfg_t private_peer_cfg_t; - -/** - * Private data of an peer_cfg_t object - */ -struct private_peer_cfg_t { - - /** - * Public part - */ - peer_cfg_t public; - - /** - * Number of references hold by others to this peer_cfg - */ - refcount_t refcount; - - /** - * Name of the peer_cfg, used to query it - */ - char *name; - - /** - * IKE version to use for initiation - */ - u_int ike_version; - - /** - * IKE config associated to this peer config - */ - ike_cfg_t *ike_cfg; - - /** - * list of child configs associated to this peer config - */ - linked_list_t *child_cfgs; - - /** - * mutex to lock access to list of child_cfgs - */ - mutex_t *mutex; - - /** - * should we send a certificate - */ - cert_policy_t cert_policy; - - /** - * uniqueness of an IKE_SA - */ - unique_policy_t unique; - - /** - * number of tries after giving up if peer does not respond - */ - u_int32_t keyingtries; - - /** - * enable support for MOBIKE - */ - bool use_mobike; - - /** - * Time before starting rekeying - */ - u_int32_t rekey_time; - - /** - * Time before starting reauthentication - */ - u_int32_t reauth_time; - - /** - * Time, which specifies the range of a random value substracted from above. - */ - u_int32_t jitter_time; - - /** - * Delay before deleting a rekeying/reauthenticating SA - */ - u_int32_t over_time; - - /** - * DPD check intervall - */ - u_int32_t dpd; - - /** - * virtual IP to use locally - */ - host_t *virtual_ip; - - /** - * pool to acquire configuration attributes from - */ - char *pool; - - /** - * local authentication configs (rulesets) - */ - linked_list_t *local_auth; - - /** - * remote authentication configs (constraints) - */ - linked_list_t *remote_auth; - -#ifdef ME - /** - * Is this a mediation connection? - */ - bool mediation; - - /** - * Name of the mediation connection to mediate through - */ - peer_cfg_t *mediated_by; - - /** - * ID of our peer at the mediation server (= leftid of the peer's conn with - * the mediation server) - */ - identification_t *peer_id; -#endif /* ME */ -}; - -/** - * Implementation of peer_cfg_t.get_name - */ -static char *get_name(private_peer_cfg_t *this) -{ - return this->name; -} - -/** - * Implementation of peer_cfg_t.get_ike_version - */ -static u_int get_ike_version(private_peer_cfg_t *this) -{ - return this->ike_version; -} - -/** - * Implementation of peer_cfg_t.get_ike_cfg - */ -static ike_cfg_t* get_ike_cfg(private_peer_cfg_t *this) -{ - return this->ike_cfg; -} - -/** - * Implementation of peer_cfg_t.add_child_cfg. - */ -static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg) -{ - this->mutex->lock(this->mutex); - this->child_cfgs->insert_last(this->child_cfgs, child_cfg); - this->mutex->unlock(this->mutex); -} - -/** - * child_cfg enumerator - */ -typedef struct { - enumerator_t public; - enumerator_t *wrapped; - mutex_t *mutex; -} child_cfg_enumerator_t; - -/** - * Implementation of peer_cfg_t.remove_child_cfg. - */ -static void remove_child_cfg(private_peer_cfg_t *this, - child_cfg_enumerator_t *enumerator) -{ - this->child_cfgs->remove_at(this->child_cfgs, enumerator->wrapped); -} - -/** - * Implementation of child_cfg_enumerator_t.destroy - */ -static void child_cfg_enumerator_destroy(child_cfg_enumerator_t *this) -{ - this->mutex->unlock(this->mutex); - this->wrapped->destroy(this->wrapped); - free(this); -} - -/** - * Implementation of child_cfg_enumerator_t.enumerate - */ -static bool child_cfg_enumerate(child_cfg_enumerator_t *this, child_cfg_t **chd) -{ - return this->wrapped->enumerate(this->wrapped, chd); -} - -/** - * Implementation of peer_cfg_t.create_child_cfg_enumerator. - */ -static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this) -{ - child_cfg_enumerator_t *enumerator = malloc_thing(child_cfg_enumerator_t); - - enumerator->public.enumerate = (void*)child_cfg_enumerate; - enumerator->public.destroy = (void*)child_cfg_enumerator_destroy; - enumerator->mutex = this->mutex; - enumerator->wrapped = this->child_cfgs->create_enumerator(this->child_cfgs); - - this->mutex->lock(this->mutex); - return &enumerator->public; -} - -/** - * Check how good a list of TS matches a given child config - */ -static int get_ts_match(child_cfg_t *cfg, bool local, - linked_list_t *sup_list, host_t *host) -{ - linked_list_t *cfg_list; - enumerator_t *sup_enum, *cfg_enum; - traffic_selector_t *sup_ts, *cfg_ts; - int match = 0, round; - - /* fetch configured TS list, narrowing dynamic TS */ - cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, host); - - /* use a round counter to rate leading TS with higher priority */ - round = sup_list->get_count(sup_list); - - sup_enum = sup_list->create_enumerator(sup_list); - while (sup_enum->enumerate(sup_enum, &sup_ts)) - { - cfg_enum = cfg_list->create_enumerator(cfg_list); - while (cfg_enum->enumerate(cfg_enum, &cfg_ts)) - { - if (cfg_ts->equals(cfg_ts, sup_ts)) - { /* equality is honored better than matches */ - match += round * 5; - } - else if (cfg_ts->is_contained_in(cfg_ts, sup_ts) || - sup_ts->is_contained_in(sup_ts, cfg_ts)) - { - match += round * 1; - } - } - cfg_enum->destroy(cfg_enum); - round--; - } - sup_enum->destroy(sup_enum); - - cfg_list->destroy_offset(cfg_list, offsetof(traffic_selector_t, destroy)); - - return match; -} - -/** - * Implementation of peer_cfg_t.select_child_cfg - */ -static child_cfg_t* select_child_cfg(private_peer_cfg_t *this, - linked_list_t *my_ts, - linked_list_t *other_ts, - host_t *my_host, host_t *other_host) -{ - child_cfg_t *current, *found = NULL; - enumerator_t *enumerator; - int best = 0; - - DBG2(DBG_CFG, "looking for a child config for %#R=== %#R", my_ts, other_ts); - enumerator = create_child_cfg_enumerator(this); - while (enumerator->enumerate(enumerator, ¤t)) - { - int my_prio, other_prio; - - my_prio = get_ts_match(current, TRUE, my_ts, my_host); - other_prio = get_ts_match(current, FALSE, other_ts, other_host); - - if (my_prio && other_prio) - { - DBG2(DBG_CFG, " candidate \"%s\" with prio %d+%d", - current->get_name(current), my_prio, other_prio); - if (my_prio + other_prio > best) - { - best = my_prio + other_prio; - DESTROY_IF(found); - found = current->get_ref(current); - } - } - } - enumerator->destroy(enumerator); - if (found) - { - DBG2(DBG_CFG, "found matching child config \"%s\" with prio %d", - found->get_name(found), best); - } - return found; -} - -/** - * Implementation of peer_cfg_t.get_cert_policy. - */ -static cert_policy_t get_cert_policy(private_peer_cfg_t *this) -{ - return this->cert_policy; -} - -/** - * Implementation of peer_cfg_t.get_unique_policy. - */ -static unique_policy_t get_unique_policy(private_peer_cfg_t *this) -{ - return this->unique; -} - -/** - * Implementation of peer_cfg_t.get_keyingtries. - */ -static u_int32_t get_keyingtries(private_peer_cfg_t *this) -{ - return this->keyingtries; -} - -/** - * Implementation of peer_cfg_t.get_rekey_time. - */ -static u_int32_t get_rekey_time(private_peer_cfg_t *this) -{ - if (this->rekey_time == 0) - { - return 0; - } - if (this->jitter_time == 0) - { - return this->rekey_time; - } - return this->rekey_time - (random() % this->jitter_time); -} - -/** - * Implementation of peer_cfg_t.get_reauth_time. - */ -static u_int32_t get_reauth_time(private_peer_cfg_t *this) -{ - if (this->reauth_time == 0) - { - return 0; - } - if (this->jitter_time == 0) - { - return this->reauth_time; - } - return this->reauth_time - (random() % this->jitter_time); -} - -/** - * Implementation of peer_cfg_t.get_over_time. - */ -static u_int32_t get_over_time(private_peer_cfg_t *this) -{ - return this->over_time; -} - -/** - * Implementation of peer_cfg_t.use_mobike. - */ -static bool use_mobike(private_peer_cfg_t *this) -{ - return this->use_mobike; -} - -/** - * Implements peer_cfg_t.get_dpd - */ -static u_int32_t get_dpd(private_peer_cfg_t *this) -{ - return this->dpd; -} - -/** - * Implementation of peer_cfg_t.get_virtual_ip. - */ -static host_t* get_virtual_ip(private_peer_cfg_t *this) -{ - return this->virtual_ip; -} - -/** - * Implementation of peer_cfg_t.get_pool. - */ -static char* get_pool(private_peer_cfg_t *this) -{ - return this->pool; -} - -/** - * Implementation of peer_cfg_t.add_auth_cfg - */ -static void add_auth_cfg(private_peer_cfg_t *this, - auth_cfg_t *cfg, bool local) -{ - if (local) - { - this->local_auth->insert_last(this->local_auth, cfg); - } - else - { - this->remote_auth->insert_last(this->remote_auth, cfg); - } -} - -/** - * Implementation of peer_cfg_t.create_auth_cfg_enumerator - */ -static enumerator_t* create_auth_cfg_enumerator(private_peer_cfg_t *this, - bool local) -{ - if (local) - { - return this->local_auth->create_enumerator(this->local_auth); - } - return this->remote_auth->create_enumerator(this->remote_auth); -} - -#ifdef ME -/** - * Implementation of peer_cfg_t.is_mediation. - */ -static bool is_mediation(private_peer_cfg_t *this) -{ - return this->mediation; -} - -/** - * Implementation of peer_cfg_t.get_mediated_by. - */ -static peer_cfg_t* get_mediated_by(private_peer_cfg_t *this) -{ - return this->mediated_by; -} - -/** - * Implementation of peer_cfg_t.get_peer_id. - */ -static identification_t* get_peer_id(private_peer_cfg_t *this) -{ - return this->peer_id; -} -#endif /* ME */ - -/** - * check auth configs for equality - */ -static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other) -{ - enumerator_t *e1, *e2; - auth_cfg_t *cfg1, *cfg2; - bool equal = TRUE; - - if (this->local_auth->get_count(this->local_auth) != - other->local_auth->get_count(other->local_auth)) - { - return FALSE; - } - if (this->remote_auth->get_count(this->remote_auth) != - other->remote_auth->get_count(other->remote_auth)) - { - return FALSE; - } - - e1 = this->local_auth->create_enumerator(this->local_auth); - e2 = other->local_auth->create_enumerator(other->local_auth); - while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2)) - { - if (!cfg1->equals(cfg1, cfg2)) - { - equal = FALSE; - break; - } - } - e1->destroy(e1); - e2->destroy(e2); - - if (!equal) - { - return FALSE; - } - - e1 = this->remote_auth->create_enumerator(this->remote_auth); - e2 = other->remote_auth->create_enumerator(other->remote_auth); - while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2)) - { - if (!cfg1->equals(cfg1, cfg2)) - { - equal = FALSE; - break; - } - } - e1->destroy(e1); - e2->destroy(e2); - - return equal; -} - -/** - * Implementation of peer_cfg_t.equals. - */ -static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other) -{ - if (this == other) - { - return TRUE; - } - if (this->public.equals != other->public.equals) - { - return FALSE; - } - - return ( - this->ike_version == other->ike_version && - this->cert_policy == other->cert_policy && - this->unique == other->unique && - this->keyingtries == other->keyingtries && - this->use_mobike == other->use_mobike && - this->rekey_time == other->rekey_time && - this->reauth_time == other->reauth_time && - this->jitter_time == other->jitter_time && - this->over_time == other->over_time && - this->dpd == other->dpd && - (this->virtual_ip == other->virtual_ip || - (this->virtual_ip && other->virtual_ip && - this->virtual_ip->equals(this->virtual_ip, other->virtual_ip))) && - (this->pool == other->pool || - (this->pool && other->pool && streq(this->pool, other->pool))) && - auth_cfg_equal(this, other) -#ifdef ME - && this->mediation == other->mediation && - this->mediated_by == other->mediated_by && - (this->peer_id == other->peer_id || - (this->peer_id && other->peer_id && - this->peer_id->equals(this->peer_id, other->peer_id))) -#endif /* ME */ - ); -} - -/** - * Implements peer_cfg_t.get_ref. - */ -static peer_cfg_t* get_ref(private_peer_cfg_t *this) -{ - ref_get(&this->refcount); - return &this->public; -} - -/** - * Implements peer_cfg_t.destroy. - */ -static void destroy(private_peer_cfg_t *this) -{ - if (ref_put(&this->refcount)) - { - this->ike_cfg->destroy(this->ike_cfg); - this->child_cfgs->destroy_offset(this->child_cfgs, - offsetof(child_cfg_t, destroy)); - DESTROY_IF(this->virtual_ip); - this->local_auth->destroy_offset(this->local_auth, - offsetof(auth_cfg_t, destroy)); - this->remote_auth->destroy_offset(this->remote_auth, - offsetof(auth_cfg_t, destroy)); -#ifdef ME - DESTROY_IF(this->mediated_by); - DESTROY_IF(this->peer_id); -#endif /* ME */ - this->mutex->destroy(this->mutex); - free(this->name); - free(this->pool); - free(this); - } -} - -/* - * Described in header-file - */ -peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg, - cert_policy_t cert_policy, unique_policy_t unique, - u_int32_t keyingtries, u_int32_t rekey_time, - u_int32_t reauth_time, u_int32_t jitter_time, - u_int32_t over_time, bool mobike, u_int32_t dpd, - host_t *virtual_ip, char *pool, - bool mediation, peer_cfg_t *mediated_by, - identification_t *peer_id) -{ - private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t); - - /* public functions */ - this->public.get_name = (char* (*) (peer_cfg_t *))get_name; - this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version; - this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg; - this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg; - this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg; - this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator; - this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg; - this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy; - this->public.get_unique_policy = (unique_policy_t (*) (peer_cfg_t *))get_unique_policy; - this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries; - this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time; - this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time; - this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time; - this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike; - this->public.get_dpd = (u_int32_t (*) (peer_cfg_t *))get_dpd; - this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *))get_virtual_ip; - this->public.get_pool = (char*(*)(peer_cfg_t*))get_pool; - this->public.add_auth_cfg = (void(*)(peer_cfg_t*, auth_cfg_t *cfg, bool local))add_auth_cfg; - this->public.create_auth_cfg_enumerator = (enumerator_t*(*)(peer_cfg_t*, bool local))create_auth_cfg_enumerator; - this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals; - this->public.get_ref = (peer_cfg_t*(*)(peer_cfg_t *))get_ref; - this->public.destroy = (void(*)(peer_cfg_t *))destroy; -#ifdef ME - this->public.is_mediation = (bool (*) (peer_cfg_t *))is_mediation; - this->public.get_mediated_by = (peer_cfg_t* (*) (peer_cfg_t *))get_mediated_by; - this->public.get_peer_id = (identification_t* (*) (peer_cfg_t *))get_peer_id; -#endif /* ME */ - - /* apply init values */ - this->name = strdup(name); - this->ike_version = ike_version; - this->ike_cfg = ike_cfg; - this->child_cfgs = linked_list_create(); - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); - this->cert_policy = cert_policy; - this->unique = unique; - this->keyingtries = keyingtries; - this->rekey_time = rekey_time; - this->reauth_time = reauth_time; - if (rekey_time && jitter_time > rekey_time) - { - jitter_time = rekey_time; - } - if (reauth_time && jitter_time > reauth_time) - { - jitter_time = reauth_time; - } - this->jitter_time = jitter_time; - this->over_time = over_time; - this->use_mobike = mobike; - this->dpd = dpd; - this->virtual_ip = virtual_ip; - this->pool = pool ? strdup(pool) : NULL; - this->local_auth = linked_list_create(); - this->remote_auth = linked_list_create(); - this->refcount = 1; -#ifdef ME - this->mediation = mediation; - this->mediated_by = mediated_by; - this->peer_id = peer_id; -#else /* ME */ - DESTROY_IF(mediated_by); - DESTROY_IF(peer_id); -#endif /* ME */ - - return &this->public; -} diff --git a/src/charon/config/peer_cfg.h b/src/charon/config/peer_cfg.h deleted file mode 100644 index 6855276f8..000000000 --- a/src/charon/config/peer_cfg.h +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2007-2008 Tobias Brunner - * Copyright (C) 2005-2009 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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. - */ - -/** - * @defgroup peer_cfg peer_cfg - * @{ @ingroup config - */ - -#ifndef PEER_CFG_H_ -#define PEER_CFG_H_ - -typedef enum cert_policy_t cert_policy_t; -typedef enum unique_policy_t unique_policy_t; -typedef struct peer_cfg_t peer_cfg_t; - -#include <library.h> -#include <utils/identification.h> -#include <utils/enumerator.h> -#include <selectors/traffic_selector.h> -#include <config/proposal.h> -#include <config/ike_cfg.h> -#include <config/child_cfg.h> -#include <sa/authenticators/authenticator.h> -#include <sa/authenticators/eap/eap_method.h> -#include <config/auth_cfg.h> - -/** - * Certificate sending policy. This is also used for certificate - * requests when using this definition for the other peer. If - * it is CERT_NEVER_SEND, a certreq is omitted, otherwise its - * included. - * - * @warning These definitions must be the same as in pluto/starter, - * as they are sent over the stroke socket. - */ -enum cert_policy_t { - /** always send certificates, even when not requested */ - CERT_ALWAYS_SEND = 0, - /** send certificate upon cert request */ - CERT_SEND_IF_ASKED = 1, - /** never send a certificate, even when requested */ - CERT_NEVER_SEND = 2, -}; - -/** - * enum strings for cert_policy_t - */ -extern enum_name_t *cert_policy_names; - -/** - * Uniqueness of an IKE_SA, used to drop multiple connections with one peer. - */ -enum unique_policy_t { - /** do not check for client uniqueness */ - UNIQUE_NO, - /** replace unique IKE_SAs if new ones get established */ - UNIQUE_REPLACE, - /** keep existing IKE_SAs, close the new ones on connection attept */ - UNIQUE_KEEP, -}; - -/** - * enum strings for unique_policy_t - */ -extern enum_name_t *unique_policy_names; - -/** - * Configuration of a peer, specified by IDs. - * - * The peer config defines a connection between two given IDs. It contains - * exactly one ike_cfg_t, which is use for initiation. Additionally, it contains - * multiple child_cfg_t defining which CHILD_SAs are allowed for this peer. - * @verbatim - +-------------------+ +---------------+ - +---------------+ | peer_cfg | +---------------+ | - | ike_cfg | +-------------------+ | child_cfg | | - +---------------+ | - ids | +---------------+ | - | - hosts | 1 1 | - cas | 1 n | - proposals | | - | - proposals |<-----| - auth info |----->| - traffic sel | | - | - ... | | - dpd config | | - ... |-+ - +---------------+ | - ... | +---------------+ - +-------------------+ - | 1 0 | - | | - v n n V - +-------------------+ +-------------------+ - +-------------------+ | +-------------------+ | - | auth_cfg | | | auth_cfg | | - +-------------------+ | +-------------------+ | - | - local rules |-+ | - remote constr. |-+ - +-------------------+ +-------------------+ - @endverbatim - * - * Each peer_cfg has two lists of authentication config attached. Local - * authentication configs define how to authenticate ourself against the remote - * peer. Each config is enforced using the multiple authentication extension - * (RFC4739). - * The remote authentication configs are handled as constraints. The peer has - * to fullfill each of these rules (using multiple authentication, in any order) - * to gain access to the configuration. - */ -struct peer_cfg_t { - - /** - * Get the name of the peer_cfg. - * - * Returned object is not getting cloned. - * - * @return peer_cfg's name - */ - char* (*get_name) (peer_cfg_t *this); - - /** - * Get the IKE version to use for initiating. - * - * @return IKE major version - */ - u_int (*get_ike_version)(peer_cfg_t *this); - - /** - * Get the IKE config to use for initiaton. - * - * @return the IKE config to use - */ - ike_cfg_t* (*get_ike_cfg) (peer_cfg_t *this); - - /** - * Attach a CHILD config. - * - * @param child_cfg CHILD config to add - */ - void (*add_child_cfg) (peer_cfg_t *this, child_cfg_t *child_cfg); - - /** - * Detach a CHILD config, pointed to by an enumerator. - * - * @param enumerator enumerator indicating element position - */ - void (*remove_child_cfg)(peer_cfg_t *this, enumerator_t *enumerator); - - /** - * Create an enumerator for all attached CHILD configs. - * - * @return an enumerator over all CHILD configs. - */ - enumerator_t* (*create_child_cfg_enumerator) (peer_cfg_t *this); - - /** - * Select a CHILD config from traffic selectors. - * - * @param my_ts TS for local side - * @param other_ts TS for remote side - * @param my_host host to narrow down dynamic TS for local side - * @param other_host host to narrow down dynamic TS for remote side - * @return selected CHILD config, or NULL if no match found - */ - child_cfg_t* (*select_child_cfg) (peer_cfg_t *this, linked_list_t *my_ts, - linked_list_t *other_ts, host_t *my_host, - host_t *other_host); - - /** - * Add an authentication config to the peer configuration. - * - * @param config config to add - * @param local TRUE for local rules, FALSE for remote constraints - */ - void (*add_auth_cfg)(peer_cfg_t *this, auth_cfg_t *cfg, bool local); - - /** - * Create an enumerator over registered authentication configs. - * - * @param local TRUE for local rules, FALSE for remote constraints - * @return enumerator over auth_cfg_t* - */ - enumerator_t* (*create_auth_cfg_enumerator)(peer_cfg_t *this, bool local); - - /** - * Should be sent a certificate for this connection? - * - * @return certificate sending policy - */ - cert_policy_t (*get_cert_policy) (peer_cfg_t *this); - - /** - * How to handle uniqueness of IKE_SAs? - * - * @return unique policy - */ - unique_policy_t (*get_unique_policy) (peer_cfg_t *this); - - /** - * Get the max number of retries after timeout. - * - * @return max number retries - */ - u_int32_t (*get_keyingtries) (peer_cfg_t *this); - - /** - * Get a time to start rekeying (is randomized with jitter). - * - * @return time in s when to start rekeying, 0 disables rekeying - */ - u_int32_t (*get_rekey_time)(peer_cfg_t *this); - - /** - * Get a time to start reauthentication (is randomized with jitter). - * - * @return time in s when to start reauthentication, 0 disables it - */ - u_int32_t (*get_reauth_time)(peer_cfg_t *this); - - /** - * Get the timeout of a rekeying/reauthenticating SA. - * - * @return timeout in s - */ - u_int32_t (*get_over_time)(peer_cfg_t *this); - - /** - * Use MOBIKE (RFC4555) if peer supports it? - * - * @return TRUE to enable MOBIKE support - */ - bool (*use_mobike) (peer_cfg_t *this); - - /** - * Get the DPD check interval. - * - * @return dpd_delay in seconds - */ - u_int32_t (*get_dpd) (peer_cfg_t *this); - - /** - * Get a virtual IP for the local peer. - * - * If no virtual IP should be used, NULL is returned. %any means to request - * a virtual IP using configuration payloads. A specific address is also - * used for a request and may be changed by the server. - * - * @param suggestion NULL, %any or specific - * @return virtual IP, %any or NULL - */ - host_t* (*get_virtual_ip) (peer_cfg_t *this); - - /** - * Get the name of the pool to acquire configuration attributes from. - * - * @return pool name, NULL if none defined - */ - char* (*get_pool)(peer_cfg_t *this); - -#ifdef ME - /** - * Is this a mediation connection? - * - * @return TRUE, if this is a mediation connection - */ - bool (*is_mediation) (peer_cfg_t *this); - - /** - * Get peer_cfg of the connection this one is mediated through. - * - * @return the peer_cfg of the mediation connection - */ - peer_cfg_t* (*get_mediated_by) (peer_cfg_t *this); - - /** - * Get the id of the other peer at the mediation server. - * - * This is the leftid of the peer's connection with the mediation server. - * - * If it is not configured, it is assumed to be the same as the right id - * of this connection. - * - * @return the id of the other peer - */ - identification_t* (*get_peer_id) (peer_cfg_t *this); -#endif /* ME */ - - /** - * Check if two peer configurations are equal. - * - * This method does not compare associated ike/child_cfg. - * - * @param other candidate to check for equality against this - * @return TRUE if peer_cfg and ike_cfg are equal - */ - bool (*equals)(peer_cfg_t *this, peer_cfg_t *other); - - /** - * Increase reference count. - * - * @return reference to this - */ - peer_cfg_t* (*get_ref) (peer_cfg_t *this); - - /** - * Destroys the peer_cfg object. - * - * Decrements the internal reference counter and - * destroys the peer_cfg when it reaches zero. - */ - void (*destroy) (peer_cfg_t *this); -}; - -/** - * Create a configuration object for IKE_AUTH and later. - * - * name-string gets cloned, ID's not. - * Virtual IPs are used if they are != NULL. A %any host means the virtual - * IP should be obtained from the other peer. - * Lifetimes are in seconds. To prevent to peers to start rekeying at the - * same time, a jitter may be specified. Rekeying of an SA starts at - * (rekeylifetime - random(0, jitter)). - * - * @param name name of the peer_cfg - * @param ike_version which IKE version we sould use for this peer - * @param ike_cfg IKE config to use when acting as initiator - * @param cert_policy should we send a certificate payload? - * @param unique uniqueness of an IKE_SA - * @param keyingtries how many keying tries should be done before giving up - * @param rekey_time timeout before starting rekeying - * @param reauth_time timeout before starting reauthentication - * @param jitter_time timerange to randomly substract from rekey/reauth time - * @param over_time maximum overtime before closing a rekeying/reauth SA - * @param mobike use MOBIKE (RFC4555) if peer supports it - * @param dpd DPD check interval, 0 to disable - * @param virtual_ip virtual IP for local host, or NULL - * @param pool pool name to get configuration attributes from, or NULL - * @param mediation TRUE if this is a mediation connection - * @param mediated_by peer_cfg_t of the mediation connection to mediate through - * @param peer_id ID that identifies our peer at the mediation server - * @return peer_cfg_t object - */ -peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg, - cert_policy_t cert_policy, unique_policy_t unique, - u_int32_t keyingtries, u_int32_t rekey_time, - u_int32_t reauth_time, u_int32_t jitter_time, - u_int32_t over_time, bool mobike, u_int32_t dpd, - host_t *virtual_ip, char *pool, - bool mediation, peer_cfg_t *mediated_by, - identification_t *peer_id); - -#endif /** PEER_CFG_H_ @}*/ diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c deleted file mode 100644 index 6b3500b6e..000000000 --- a/src/charon/config/proposal.c +++ /dev/null @@ -1,945 +0,0 @@ -/* - * Copyright (C) 2008-2009 Tobias Brunner - * 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 <string.h> - -#include "proposal.h" - -#include <daemon.h> -#include <utils/linked_list.h> -#include <utils/identification.h> -#include <utils/lexparser.h> -#include <crypto/transform.h> -#include <crypto/prfs/prf.h> -#include <crypto/crypters/crypter.h> -#include <crypto/signers/signer.h> -#include <crypto/proposal/proposal_keywords.h> - -ENUM(protocol_id_names, PROTO_NONE, PROTO_ESP, - "PROTO_NONE", - "IKE", - "AH", - "ESP", -); - -ENUM(extended_sequence_numbers_names, NO_EXT_SEQ_NUMBERS, EXT_SEQ_NUMBERS, - "NO_EXT_SEQ", - "EXT_SEQ", -); - -typedef struct private_proposal_t private_proposal_t; -typedef struct algorithm_t algorithm_t; - -/** - * Private data of an proposal_t object - */ -struct private_proposal_t { - - /** - * Public part - */ - proposal_t public; - - /** - * protocol (ESP or AH) - */ - protocol_id_t protocol; - - /** - * priority ordered list of encryption algorithms - */ - linked_list_t *encryption_algos; - - /** - * priority ordered list of integrity algorithms - */ - linked_list_t *integrity_algos; - - /** - * priority ordered list of pseudo random functions - */ - linked_list_t *prf_algos; - - /** - * priority ordered list of dh groups - */ - linked_list_t *dh_groups; - - /** - * priority ordered list of extended sequence number flags - */ - linked_list_t *esns; - - /** - * senders SPI - */ - u_int64_t spi; -}; - -/** - * Struct used to store different kinds of algorithms. - */ -struct algorithm_t { - /** - * Value from an encryption_algorithm_t/integrity_algorithm_t/... - */ - u_int16_t algorithm; - - /** - * the associated key size in bits, or zero if not needed - */ - u_int16_t key_size; -}; - -/** - * Add algorithm/keysize to a algorithm list - */ -static void add_algo(linked_list_t *list, u_int16_t algo, u_int16_t key_size) -{ - algorithm_t *algo_key; - - algo_key = malloc_thing(algorithm_t); - algo_key->algorithm = algo; - algo_key->key_size = key_size; - list->insert_last(list, (void*)algo_key); -} - -/** - * Implements proposal_t.add_algorithm - */ -static void add_algorithm(private_proposal_t *this, transform_type_t type, - u_int16_t algo, u_int16_t key_size) -{ - switch (type) - { - case ENCRYPTION_ALGORITHM: - add_algo(this->encryption_algos, algo, key_size); - break; - case INTEGRITY_ALGORITHM: - add_algo(this->integrity_algos, algo, key_size); - break; - case PSEUDO_RANDOM_FUNCTION: - add_algo(this->prf_algos, algo, key_size); - break; - case DIFFIE_HELLMAN_GROUP: - add_algo(this->dh_groups, algo, 0); - break; - case EXTENDED_SEQUENCE_NUMBERS: - add_algo(this->esns, algo, 0); - break; - default: - break; - } -} - -/** - * filter function for peer configs - */ -static bool alg_filter(void *null, algorithm_t **in, u_int16_t *alg, - void **unused, u_int16_t *key_size) -{ - algorithm_t *algo = *in; - *alg = algo->algorithm; - if (key_size) - { - *key_size = algo->key_size; - } - return TRUE; -} - -/** - * Implements proposal_t.create_enumerator. - */ -static enumerator_t *create_enumerator(private_proposal_t *this, - transform_type_t type) -{ - linked_list_t *list; - - switch (type) - { - case ENCRYPTION_ALGORITHM: - list = this->encryption_algos; - break; - case INTEGRITY_ALGORITHM: - list = this->integrity_algos; - break; - case PSEUDO_RANDOM_FUNCTION: - list = this->prf_algos; - break; - case DIFFIE_HELLMAN_GROUP: - list = this->dh_groups; - break; - case EXTENDED_SEQUENCE_NUMBERS: - list = this->esns; - break; - default: - return NULL; - } - return enumerator_create_filter(list->create_enumerator(list), - (void*)alg_filter, NULL, NULL); -} - -/** - * Implements proposal_t.get_algorithm. - */ -static bool get_algorithm(private_proposal_t *this, transform_type_t type, - u_int16_t *alg, u_int16_t *key_size) -{ - enumerator_t *enumerator; - bool found = FALSE; - - enumerator = create_enumerator(this, type); - if (enumerator->enumerate(enumerator, alg, key_size)) - { - found = TRUE; - } - enumerator->destroy(enumerator); - return found; -} - -/** - * Implements proposal_t.has_dh_group - */ -static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group) -{ - bool result = FALSE; - - if (this->dh_groups->get_count(this->dh_groups)) - { - algorithm_t *current; - enumerator_t *enumerator; - - enumerator = this->dh_groups->create_enumerator(this->dh_groups); - while (enumerator->enumerate(enumerator, (void**)¤t)) - { - if (current->algorithm == group) - { - result = TRUE; - break; - } - } - enumerator->destroy(enumerator); - } - else if (group == MODP_NONE) - { - result = TRUE; - } - return result; -} - -/** - * Implementation of proposal_t.strip_dh. - */ -static void strip_dh(private_proposal_t *this) -{ - algorithm_t *alg; - - while (this->dh_groups->remove_last(this->dh_groups, (void**)&alg) == SUCCESS) - { - free(alg); - } -} - -/** - * Returns true if the given alg is an authenticated encryption algorithm - */ -static bool is_authenticated_encryption(u_int16_t alg) -{ - switch(alg) - { - case ENCR_AES_CCM_ICV8: - case ENCR_AES_CCM_ICV12: - case ENCR_AES_CCM_ICV16: - case ENCR_AES_GCM_ICV8: - case ENCR_AES_GCM_ICV12: - case ENCR_AES_GCM_ICV16: - case ENCR_CAMELLIA_CCM_ICV8: - case ENCR_CAMELLIA_CCM_ICV12: - case ENCR_CAMELLIA_CCM_ICV16: - return TRUE; - } - return FALSE; -} - -/** - * Find a matching alg/keysize in two linked lists - */ -static bool select_algo(linked_list_t *first, linked_list_t *second, bool priv, - bool *add, u_int16_t *alg, size_t *key_size) -{ - enumerator_t *e1, *e2; - algorithm_t *alg1, *alg2; - - /* if in both are zero algorithms specified, we HAVE a match */ - if (first->get_count(first) == 0 && second->get_count(second) == 0) - { - *add = FALSE; - return TRUE; - } - - e1 = first->create_enumerator(first); - e2 = second->create_enumerator(second); - /* compare algs, order of algs in "first" is preferred */ - while (e1->enumerate(e1, &alg1)) - { - e2->destroy(e2); - e2 = second->create_enumerator(second); - while (e2->enumerate(e2, &alg2)) - { - if (alg1->algorithm == alg2->algorithm && - alg1->key_size == alg2->key_size) - { - if (!priv && alg1->algorithm >= 1024) - { - /* accept private use algorithms only if requested */ - DBG1(DBG_CFG, "an algorithm from private space would match, " - "but peer implementation is unknown, skipped"); - continue; - } - /* ok, we have an algorithm */ - *alg = alg1->algorithm; - *key_size = alg1->key_size; - *add = TRUE; - e1->destroy(e1); - e2->destroy(e2); - return TRUE; - } - } - } - /* no match in all comparisons */ - e1->destroy(e1); - e2->destroy(e2); - return FALSE; -} - -/** - * Implements proposal_t.select. - */ -static proposal_t *select_proposal(private_proposal_t *this, - private_proposal_t *other, bool private) -{ - proposal_t *selected; - u_int16_t algo; - size_t key_size; - bool add; - - DBG2(DBG_CFG, "selecting proposal:"); - - /* check protocol */ - if (this->protocol != other->protocol) - { - DBG2(DBG_CFG, " protocol mismatch, skipping"); - return NULL; - } - - selected = proposal_create(this->protocol); - - /* select encryption algorithm */ - if (select_algo(this->encryption_algos, other->encryption_algos, private, - &add, &algo, &key_size)) - { - if (add) - { - selected->add_algorithm(selected, ENCRYPTION_ALGORITHM, - algo, key_size); - } - } - else - { - selected->destroy(selected); - DBG2(DBG_CFG, " no acceptable %N found", - transform_type_names, ENCRYPTION_ALGORITHM); - return NULL; - } - /* select integrity algorithm */ - if (!is_authenticated_encryption(algo)) - { - if (select_algo(this->integrity_algos, other->integrity_algos, private, - &add, &algo, &key_size)) - { - if (add) - { - selected->add_algorithm(selected, INTEGRITY_ALGORITHM, - algo, key_size); - } - } - else - { - selected->destroy(selected); - DBG2(DBG_CFG, " no acceptable %N found", - transform_type_names, INTEGRITY_ALGORITHM); - return NULL; - } - } - /* select prf algorithm */ - if (select_algo(this->prf_algos, other->prf_algos, private, - &add, &algo, &key_size)) - { - if (add) - { - selected->add_algorithm(selected, PSEUDO_RANDOM_FUNCTION, - algo, key_size); - } - } - else - { - selected->destroy(selected); - DBG2(DBG_CFG, " no acceptable %N found", - transform_type_names, PSEUDO_RANDOM_FUNCTION); - return NULL; - } - /* select a DH-group */ - if (select_algo(this->dh_groups, other->dh_groups, private, - &add, &algo, &key_size)) - { - if (add) - { - selected->add_algorithm(selected, DIFFIE_HELLMAN_GROUP, algo, 0); - } - } - else - { - selected->destroy(selected); - DBG2(DBG_CFG, " no acceptable %N found", - transform_type_names, DIFFIE_HELLMAN_GROUP); - return NULL; - } - /* select if we use ESNs (has no private use space) */ - if (select_algo(this->esns, other->esns, TRUE, &add, &algo, &key_size)) - { - if (add) - { - selected->add_algorithm(selected, EXTENDED_SEQUENCE_NUMBERS, algo, 0); - } - } - else - { - selected->destroy(selected); - DBG2(DBG_CFG, " no acceptable %N found", - transform_type_names, EXTENDED_SEQUENCE_NUMBERS); - return NULL; - } - DBG2(DBG_CFG, " proposal matches"); - - /* apply SPI from "other" */ - selected->set_spi(selected, other->spi); - - /* everything matched, return new proposal */ - return selected; -} - -/** - * Implements proposal_t.get_protocols. - */ -static protocol_id_t get_protocol(private_proposal_t *this) -{ - return this->protocol; -} - -/** - * Implements proposal_t.set_spi. - */ -static void set_spi(private_proposal_t *this, u_int64_t spi) -{ - this->spi = spi; -} - -/** - * Implements proposal_t.get_spi. - */ -static u_int64_t get_spi(private_proposal_t *this) -{ - return this->spi; -} - -/** - * Clone a algorithm list - */ -static void clone_algo_list(linked_list_t *list, linked_list_t *clone_list) -{ - algorithm_t *algo, *clone_algo; - enumerator_t *enumerator; - - enumerator = list->create_enumerator(list); - while (enumerator->enumerate(enumerator, &algo)) - { - clone_algo = malloc_thing(algorithm_t); - memcpy(clone_algo, algo, sizeof(algorithm_t)); - clone_list->insert_last(clone_list, (void*)clone_algo); - } - enumerator->destroy(enumerator); -} - -/** - * check if an algorithm list equals - */ -static bool algo_list_equals(linked_list_t *l1, linked_list_t *l2) -{ - enumerator_t *e1, *e2; - algorithm_t *alg1, *alg2; - bool equals = TRUE; - - if (l1->get_count(l1) != l2->get_count(l2)) - { - return FALSE; - } - - e1 = l1->create_enumerator(l1); - e2 = l2->create_enumerator(l2); - while (e1->enumerate(e1, &alg1) && e2->enumerate(e2, &alg2)) - { - if (alg1->algorithm != alg2->algorithm || - alg1->key_size != alg2->key_size) - { - equals = FALSE; - break; - } - } - e1->destroy(e1); - e2->destroy(e2); - return equals; -} - -/** - * Implementation of proposal_t.equals. - */ -static bool equals(private_proposal_t *this, private_proposal_t *other) -{ - if (this == other) - { - return TRUE; - } - if (this->public.equals != other->public.equals) - { - return FALSE; - } - return ( - algo_list_equals(this->encryption_algos, other->encryption_algos) && - algo_list_equals(this->integrity_algos, other->integrity_algos) && - algo_list_equals(this->prf_algos, other->prf_algos) && - algo_list_equals(this->dh_groups, other->dh_groups) && - algo_list_equals(this->esns, other->esns)); -} - -/** - * Implements proposal_t.clone - */ -static proposal_t *clone_(private_proposal_t *this) -{ - private_proposal_t *clone = (private_proposal_t*)proposal_create(this->protocol); - - clone_algo_list(this->encryption_algos, clone->encryption_algos); - clone_algo_list(this->integrity_algos, clone->integrity_algos); - clone_algo_list(this->prf_algos, clone->prf_algos); - clone_algo_list(this->dh_groups, clone->dh_groups); - clone_algo_list(this->esns, clone->esns); - - clone->spi = this->spi; - - return &clone->public; -} - -/** - * Checks the proposal read from a string. - */ -static void check_proposal(private_proposal_t *this) -{ - enumerator_t *e; - algorithm_t *alg; - bool all_aead = TRUE; - - e = this->encryption_algos->create_enumerator(this->encryption_algos); - while (e->enumerate(e, &alg)) - { - if (!is_authenticated_encryption(alg->algorithm)) - { - all_aead = FALSE; - break; - } - } - e->destroy(e); - - if (all_aead) - { - /* if all encryption algorithms in the proposal are authenticated encryption - * algorithms we MUST NOT propose any integrity algorithms */ - while (this->integrity_algos->remove_last(this->integrity_algos, - (void**)&alg) == SUCCESS) - { - free(alg); - } - } -} - -/** - * add a algorithm identified by a string to the proposal. - */ -static status_t add_string_algo(private_proposal_t *this, chunk_t alg) -{ - const proposal_token_t *token = proposal_get_token(alg.ptr, alg.len); - - if (token == NULL) - { - return FAILED; - } - - add_algorithm(this, token->type, token->algorithm, token->keysize); - - if (this->protocol == PROTO_IKE && token->type == INTEGRITY_ALGORITHM) - { - pseudo_random_function_t prf; - - switch (token->algorithm) - { - case AUTH_HMAC_SHA1_96: - prf = PRF_HMAC_SHA1; - break; - case AUTH_HMAC_SHA2_256_128: - prf = PRF_HMAC_SHA2_256; - break; - case AUTH_HMAC_SHA2_384_192: - prf = PRF_HMAC_SHA2_384; - break; - case AUTH_HMAC_SHA2_512_256: - prf = PRF_HMAC_SHA2_512; - break; - case AUTH_HMAC_MD5_96: - prf = PRF_HMAC_MD5; - break; - case AUTH_AES_XCBC_96: - prf = PRF_AES128_XCBC; - break; - default: - prf = PRF_UNDEFINED; - } - if (prf != PRF_UNDEFINED) - { - add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0); - } - } - return SUCCESS; -} - -/** - * print all algorithms of a kind to buffer - */ -static int print_alg(private_proposal_t *this, char **dst, size_t *len, - u_int kind, void *names, bool *first) -{ - enumerator_t *enumerator; - size_t written = 0; - u_int16_t alg, size; - - enumerator = create_enumerator(this, kind); - while (enumerator->enumerate(enumerator, &alg, &size)) - { - if (*first) - { - written += print_in_hook(*dst, *len, "%N", names, alg); - *first = FALSE; - } - else - { - written += print_in_hook(*dst, *len, "/%N", names, alg); - } - if (size) - { - written += print_in_hook(*dst, *len, "_%u", size); - } - } - enumerator->destroy(enumerator); - return written; -} - -/** - * Described in header. - */ -int proposal_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, - const void *const *args) -{ - private_proposal_t *this = *((private_proposal_t**)(args[0])); - linked_list_t *list = *((linked_list_t**)(args[0])); - enumerator_t *enumerator; - size_t written = 0; - bool first = TRUE; - - if (this == NULL) - { - return print_in_hook(dst, len, "(null)"); - } - - if (spec->hash) - { - enumerator = list->create_enumerator(list); - while (enumerator->enumerate(enumerator, &this)) - { /* call recursivly */ - if (first) - { - written += print_in_hook(dst, len, "%P", this); - first = FALSE; - } - else - { - written += print_in_hook(dst, len, ", %P", this); - } - } - enumerator->destroy(enumerator); - return written; - } - - written = print_in_hook(dst, len, "%N:", protocol_id_names, this->protocol); - written += print_alg(this, &dst, &len, ENCRYPTION_ALGORITHM, - encryption_algorithm_names, &first); - written += print_alg(this, &dst, &len, INTEGRITY_ALGORITHM, - integrity_algorithm_names, &first); - written += print_alg(this, &dst, &len, PSEUDO_RANDOM_FUNCTION, - pseudo_random_function_names, &first); - written += print_alg(this, &dst, &len, DIFFIE_HELLMAN_GROUP, - diffie_hellman_group_names, &first); - written += print_alg(this, &dst, &len, EXTENDED_SEQUENCE_NUMBERS, - extended_sequence_numbers_names, &first); - return written; -} - -/** - * Implements proposal_t.destroy. - */ -static void destroy(private_proposal_t *this) -{ - this->encryption_algos->destroy_function(this->encryption_algos, free); - this->integrity_algos->destroy_function(this->integrity_algos, free); - this->prf_algos->destroy_function(this->prf_algos, free); - this->dh_groups->destroy_function(this->dh_groups, free); - this->esns->destroy_function(this->esns, free); - free(this); -} - -/* - * Describtion in header-file - */ -proposal_t *proposal_create(protocol_id_t protocol) -{ - private_proposal_t *this = malloc_thing(private_proposal_t); - - this->public.add_algorithm = (void (*)(proposal_t*,transform_type_t,u_int16_t,u_int16_t))add_algorithm; - this->public.create_enumerator = (enumerator_t* (*)(proposal_t*,transform_type_t))create_enumerator; - this->public.get_algorithm = (bool (*)(proposal_t*,transform_type_t,u_int16_t*,u_int16_t*))get_algorithm; - this->public.has_dh_group = (bool (*)(proposal_t*,diffie_hellman_group_t))has_dh_group; - this->public.strip_dh = (void(*)(proposal_t*))strip_dh; - this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*,bool))select_proposal; - this->public.get_protocol = (protocol_id_t(*)(proposal_t*))get_protocol; - this->public.set_spi = (void(*)(proposal_t*,u_int64_t))set_spi; - this->public.get_spi = (u_int64_t(*)(proposal_t*))get_spi; - this->public.equals = (bool(*)(proposal_t*, proposal_t *other))equals; - this->public.clone = (proposal_t*(*)(proposal_t*))clone_; - this->public.destroy = (void(*)(proposal_t*))destroy; - - this->spi = 0; - this->protocol = protocol; - - this->encryption_algos = linked_list_create(); - this->integrity_algos = linked_list_create(); - this->prf_algos = linked_list_create(); - this->dh_groups = linked_list_create(); - this->esns = linked_list_create(); - - return &this->public; -} - -/** - * Add supported IKE algorithms to proposal - */ -static void proposal_add_supported_ike(private_proposal_t *this) -{ - enumerator_t *enumerator; - encryption_algorithm_t encryption; - integrity_algorithm_t integrity; - pseudo_random_function_t prf; - diffie_hellman_group_t group; - - enumerator = lib->crypto->create_crypter_enumerator(lib->crypto); - while (enumerator->enumerate(enumerator, &encryption)) - { - switch (encryption) - { - case ENCR_AES_CBC: - /* we assume that we support all AES sizes */ - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128); - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192); - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256); - break; - case ENCR_3DES: - case ENCR_AES_CTR: - case ENCR_AES_CCM_ICV8: - case ENCR_AES_CCM_ICV12: - case ENCR_AES_CCM_ICV16: - case ENCR_AES_GCM_ICV8: - case ENCR_AES_GCM_ICV12: - case ENCR_AES_GCM_ICV16: - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 0); - break; - case ENCR_DES: - /* no, thanks */ - break; - default: - break; - } - } - enumerator->destroy(enumerator); - - enumerator = lib->crypto->create_signer_enumerator(lib->crypto); - while (enumerator->enumerate(enumerator, &integrity)) - { - switch (integrity) - { - case AUTH_HMAC_SHA1_96: - case AUTH_HMAC_SHA2_256_128: - case AUTH_HMAC_SHA2_384_192: - case AUTH_HMAC_SHA2_512_256: - case AUTH_HMAC_MD5_96: - case AUTH_AES_XCBC_96: - add_algorithm(this, INTEGRITY_ALGORITHM, integrity, 0); - break; - default: - break; - } - } - enumerator->destroy(enumerator); - - enumerator = lib->crypto->create_prf_enumerator(lib->crypto); - while (enumerator->enumerate(enumerator, &prf)) - { - switch (prf) - { - case PRF_HMAC_SHA1: - case PRF_HMAC_SHA2_256: - case PRF_HMAC_SHA2_384: - case PRF_HMAC_SHA2_512: - case PRF_HMAC_MD5: - case PRF_AES128_XCBC: - add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0); - break; - default: - break; - } - } - enumerator->destroy(enumerator); - - enumerator = lib->crypto->create_dh_enumerator(lib->crypto); - while (enumerator->enumerate(enumerator, &group)) - { - switch (group) - { - case MODP_NULL: - /* only for testing purposes */ - break; - case MODP_768_BIT: - /* weak */ - break; - case MODP_1024_BIT: - case MODP_1536_BIT: - case MODP_2048_BIT: - case MODP_4096_BIT: - case MODP_8192_BIT: - case ECP_256_BIT: - case ECP_384_BIT: - case ECP_521_BIT: - case ECP_192_BIT: - case ECP_224_BIT: - add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0); - break; - default: - break; - } - } - enumerator->destroy(enumerator); -} - -/* - * Describtion in header-file - */ -proposal_t *proposal_create_default(protocol_id_t protocol) -{ - private_proposal_t *this = (private_proposal_t*)proposal_create(protocol); - - switch (protocol) - { - case PROTO_IKE: - proposal_add_supported_ike(this); - break; - case PROTO_ESP: - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128); - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192); - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256); - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_3DES, 0); - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256); - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0); - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0); - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0); - add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0); - break; - case PROTO_AH: - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0); - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0); - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0); - add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0); - break; - default: - break; - } - return &this->public; -} - -/* - * Describtion in header-file - */ -proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs) -{ - private_proposal_t *this = (private_proposal_t*)proposal_create(protocol); - chunk_t string = {(void*)algs, strlen(algs)}; - chunk_t alg; - status_t status = SUCCESS; - - eat_whitespace(&string); - if (string.len < 1) - { - destroy(this); - return NULL; - } - - /* get all tokens, separated by '-' */ - while (extract_token(&alg, '-', &string)) - { - status |= add_string_algo(this, alg); - } - if (string.len) - { - status |= add_string_algo(this, string); - } - if (status != SUCCESS) - { - destroy(this); - return NULL; - } - - check_proposal(this); - - if (protocol == PROTO_AH || protocol == PROTO_ESP) - { - add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0); - } - return &this->public; -} diff --git a/src/charon/config/proposal.h b/src/charon/config/proposal.h deleted file mode 100644 index 30f63b80d..000000000 --- a/src/charon/config/proposal.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * 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. - */ - -/** - * @defgroup proposal proposal - * @{ @ingroup config - */ - -#ifndef PROPOSAL_H_ -#define PROPOSAL_H_ - -typedef enum protocol_id_t protocol_id_t; -typedef enum extended_sequence_numbers_t extended_sequence_numbers_t; -typedef struct proposal_t proposal_t; - -#include <library.h> -#include <utils/identification.h> -#include <utils/linked_list.h> -#include <utils/host.h> -#include <crypto/transform.h> -#include <crypto/crypters/crypter.h> -#include <crypto/signers/signer.h> -#include <crypto/diffie_hellman.h> -#include <selectors/traffic_selector.h> - -/** - * Protocol ID of a proposal. - */ -enum protocol_id_t { - PROTO_NONE = 0, - PROTO_IKE = 1, - PROTO_AH = 2, - PROTO_ESP = 3, -}; - -/** - * enum names for protocol_id_t - */ -extern enum_name_t *protocol_id_names; - -/** - * Extended sequence numbers, as in IKEv2 RFC 3.3.2. - */ -enum extended_sequence_numbers_t { - NO_EXT_SEQ_NUMBERS = 0, - EXT_SEQ_NUMBERS = 1 -}; - -/** - * enum strings for extended_sequence_numbers_t. - */ -extern enum_name_t *extended_sequence_numbers_names; - -/** - * Stores a set of algorithms used for an SA. - * - * A proposal stores algorithms for a specific - * protocol. It can store algorithms for one protocol. - * Proposals with multiple protocols are not supported, - * as it's not specified in RFC4301 anymore. - */ -struct proposal_t { - - /** - * Add an algorithm to the proposal. - * - * The algorithms are stored by priority, first added - * is the most preferred. - * Key size is only needed for encryption algorithms - * with variable key size (such as AES). Must be set - * to zero if key size is not specified. - * The alg parameter accepts encryption_algorithm_t, - * integrity_algorithm_t, dh_group_number_t and - * extended_sequence_numbers_t. - * - * @param type kind of algorithm - * @param alg identifier for algorithm - * @param key_size key size to use - */ - void (*add_algorithm) (proposal_t *this, transform_type_t type, - u_int16_t alg, u_int16_t key_size); - - /** - * Get an enumerator over algorithms for a specifc algo type. - * - * @param type kind of algorithm - * @return enumerator over u_int16_t alg, u_int16_t key_size - */ - enumerator_t *(*create_enumerator) (proposal_t *this, transform_type_t type); - - /** - * Get the algorithm for a type to use. - * - * If there are multiple algorithms, only the first is returned. - * - * @param type kind of algorithm - * @param alg pointer which receives algorithm - * @param key_size pointer which receives the key size - * @return TRUE if algorithm of this kind available - */ - bool (*get_algorithm) (proposal_t *this, transform_type_t type, - u_int16_t *alg, u_int16_t *key_size); - - /** - * Check if the proposal has a specific DH group. - * - * @param group group to check for - * @return TRUE if algorithm included - */ - bool (*has_dh_group) (proposal_t *this, diffie_hellman_group_t group); - - /** - * Strip DH groups from proposal to use it without PFS. - */ - void (*strip_dh)(proposal_t *this); - - /** - * Compare two proposal, and select a matching subset. - * - * If the proposals are for the same protocols (AH/ESP), they are - * compared. If they have at least one algorithm of each type - * in common, a resulting proposal of this kind is created. - * - * @param other proposal to compair agains - * @param private accepts algorithms allocated in a private range - * @return selected proposal, NULL if proposals don't match - */ - proposal_t *(*select) (proposal_t *this, proposal_t *other, bool private); - - /** - * Get the protocol ID of the proposal. - * - * @return protocol of the proposal - */ - protocol_id_t (*get_protocol) (proposal_t *this); - - /** - * Get the SPI of the proposal. - * - * @return spi for proto - */ - u_int64_t (*get_spi) (proposal_t *this); - - /** - * Set the SPI of the proposal. - * - * @param spi spi to set for proto - */ - void (*set_spi) (proposal_t *this, u_int64_t spi); - - /** - * Check for the eqality of two proposals. - * - * @param other other proposal to check for equality - * @return TRUE if other equal to this - */ - bool (*equals)(proposal_t *this, proposal_t *other); - - /** - * Clone a proposal. - * - * @return clone of proposal - */ - proposal_t *(*clone) (proposal_t *this); - - /** - * Destroys the proposal object. - */ - void (*destroy) (proposal_t *this); -}; - -/** - * Create a child proposal for AH, ESP or IKE. - * - * @param protocol protocol, such as PROTO_ESP - * @return proposal_t object - */ -proposal_t *proposal_create(protocol_id_t protocol); - -/** - * Create a default proposal if nothing further specified. - * - * @param protocol protocol, such as PROTO_ESP - * @return proposal_t object - */ -proposal_t *proposal_create_default(protocol_id_t protocol); - -/** - * Create a proposal from a string identifying the algorithms. - * - * The string is in the same form as a in the ipsec.conf file. - * E.g.: aes128-sha2_256-modp2048 - * 3des-md5 - * An additional '!' at the end of the string forces this proposal, - * without it the peer may choose another algorithm we support. - * - * @param protocol protocol, such as PROTO_ESP - * @param algs algorithms as string - * @return proposal_t object - */ -proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs); - -/** - * printf hook function for proposal_t. - * - * Arguments are: - * proposal_t *proposal - * With the #-specifier, arguments are: - * linked_list_t *list containing proposal_t* - */ -int proposal_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, - const void *const *args); - -#endif /** PROPOSAL_H_ @}*/ |