summaryrefslogtreecommitdiff
path: root/src/charon/config
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/config')
-rw-r--r--src/charon/config/attributes/attribute_handler.h58
-rw-r--r--src/charon/config/attributes/attribute_manager.c267
-rw-r--r--src/charon/config/attributes/attribute_manager.h135
-rw-r--r--src/charon/config/attributes/attribute_provider.h67
-rw-r--r--src/charon/config/auth_cfg.c56
-rw-r--r--src/charon/config/auth_cfg.h24
-rw-r--r--src/charon/config/backend_manager.c67
-rw-r--r--src/charon/config/backend_manager.h14
-rw-r--r--src/charon/config/child_cfg.c143
-rw-r--r--src/charon/config/child_cfg.h146
-rw-r--r--src/charon/config/ike_cfg.c44
-rw-r--r--src/charon/config/ike_cfg.h48
-rw-r--r--src/charon/config/peer_cfg.c90
-rw-r--r--src/charon/config/peer_cfg.h90
-rw-r--r--src/charon/config/proposal.c131
-rw-r--r--src/charon/config/proposal.h63
-rw-r--r--src/charon/config/traffic_selector.c856
-rw-r--r--src/charon/config/traffic_selector.h304
18 files changed, 483 insertions, 2120 deletions
diff --git a/src/charon/config/attributes/attribute_handler.h b/src/charon/config/attributes/attribute_handler.h
deleted file mode 100644
index de1c4414d..000000000
--- a/src/charon/config/attributes/attribute_handler.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/**
- * @defgroup attribute_handler attribute_handler
- * @{ @ingroup attributes
- */
-
-#ifndef ATTRIBUTE_HANDLER_H_
-#define ATTRIBUTE_HANDLER_H_
-
-#include <sa/ike_sa.h>
-#include <encoding/payloads/configuration_attribute.h>
-
-typedef struct attribute_handler_t attribute_handler_t;
-
-/**
- * Interface to handle configuration payload attributes.
- */
-struct attribute_handler_t {
-
- /**
- * Handle a configuration attribute.
- *
- * After receiving a configuration attriubte, it is passed to each
- * attribute handler until it is handled.
- *
- * @param type type of configuration attribute to handle
- * @param data associated attribute data
- * @return TRUE if attribute handled
- */
- bool (*handle)(attribute_handler_t *this, ike_sa_t *ike_sa,
- configuration_attribute_type_t type, chunk_t data);
-
- /**
- * Release an attribute handled during handle().
- *
- * A handler that handle()d an attribute gets a call to release() when the
- * IKE_SA gets closed. Depending on the implementation, this is required
- * to remove the attribute.
- */
- void (*release)(attribute_handler_t *this, ike_sa_t *ike_sa,
- configuration_attribute_type_t type, chunk_t data);
-};
-
-#endif /* ATTRIBUTE_HANDLER_ @}*/
diff --git a/src/charon/config/attributes/attribute_manager.c b/src/charon/config/attributes/attribute_manager.c
deleted file mode 100644
index bf45fdb42..000000000
--- a/src/charon/config/attributes/attribute_manager.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "attribute_manager.h"
-
-#include <daemon.h>
-#include <utils/linked_list.h>
-#include <utils/mutex.h>
-
-typedef struct private_attribute_manager_t private_attribute_manager_t;
-
-/**
- * private data of attribute_manager
- */
-struct private_attribute_manager_t {
-
- /**
- * public functions
- */
- attribute_manager_t public;
-
- /**
- * list of registered providers
- */
- linked_list_t *providers;
-
- /**
- * list of registered handlers
- */
- linked_list_t *handlers;
-
- /**
- * rwlock provider list
- */
- rwlock_t *lock;
-};
-
-/**
- * Implementation of attribute_manager_t.acquire_address.
- */
-static host_t* acquire_address(private_attribute_manager_t *this,
- char *pool, identification_t *id,
- host_t *requested)
-{
- enumerator_t *enumerator;
- attribute_provider_t *current;
- host_t *host = NULL;
-
- this->lock->read_lock(this->lock);
- enumerator = this->providers->create_enumerator(this->providers);
- while (enumerator->enumerate(enumerator, &current))
- {
- host = current->acquire_address(current, pool, id, requested);
- if (host)
- {
- break;
- }
- }
- enumerator->destroy(enumerator);
- this->lock->unlock(this->lock);
-
- if (!host)
- {
- DBG1(DBG_CFG, "acquiring address from pool '%s' failed", pool);
- }
- return host;
-}
-
-/**
- * Implementation of attribute_manager_t.release_address.
- */
-static void release_address(private_attribute_manager_t *this,
- char *pool, host_t *address, identification_t *id)
-{
- enumerator_t *enumerator;
- attribute_provider_t *current;
- bool found = FALSE;
-
- this->lock->read_lock(this->lock);
- enumerator = this->providers->create_enumerator(this->providers);
- while (enumerator->enumerate(enumerator, &current))
- {
- if (current->release_address(current, pool, address, id))
- {
- found = TRUE;
- break;
- }
- }
- enumerator->destroy(enumerator);
- this->lock->unlock(this->lock);
-
- if (!found)
- {
- DBG1(DBG_CFG, "releasing address to pool '%s' failed", pool);
- }
-}
-
-/**
- * inner enumerator constructor for attributes
- */
-static enumerator_t *attrib_enum_create(attribute_provider_t *provider,
- identification_t *id)
-{
- return provider->create_attribute_enumerator(provider, id);
-}
-
-/**
- * Implementation of attribute_manager_t.create_attribute_enumerator
- */
-static enumerator_t* create_attribute_enumerator(
- private_attribute_manager_t *this, identification_t *id)
-{
- this->lock->read_lock(this->lock);
- return enumerator_create_cleaner(
- enumerator_create_nested(
- this->providers->create_enumerator(this->providers),
- (void*)attrib_enum_create, id, NULL),
- (void*)this->lock->unlock, this->lock);
-}
-
-/**
- * Implementation of attribute_manager_t.add_provider.
- */
-static void add_provider(private_attribute_manager_t *this,
- attribute_provider_t *provider)
-{
- this->lock->write_lock(this->lock);
- this->providers->insert_last(this->providers, provider);
- this->lock->unlock(this->lock);
-}
-
-/**
- * Implementation of attribute_manager_t.remove_provider.
- */
-static void remove_provider(private_attribute_manager_t *this,
- attribute_provider_t *provider)
-{
- this->lock->write_lock(this->lock);
- this->providers->remove(this->providers, provider, NULL);
- this->lock->unlock(this->lock);
-}
-
-/**
- * Implementation of attribute_manager_t.handle
- */
-static attribute_handler_t* handle(private_attribute_manager_t *this,
- ike_sa_t *ike_sa, configuration_attribute_type_t type,
- chunk_t data)
-{
- enumerator_t *enumerator;
- attribute_handler_t *current, *handled = NULL;
-
- this->lock->read_lock(this->lock);
- enumerator = this->handlers->create_enumerator(this->handlers);
- while (enumerator->enumerate(enumerator, &current))
- {
- if (current->handle(current, ike_sa, type, data))
- {
- handled = current;
- break;
- }
- }
- enumerator->destroy(enumerator);
- this->lock->unlock(this->lock);
-
- if (!handled)
- {
- DBG1(DBG_CFG, "handling %N attribute failed",
- configuration_attribute_type_names, type);
- }
- return handled;
-}
-
-/**
- * Implementation of attribute_manager_t.release
- */
-static void release(private_attribute_manager_t *this,
- attribute_handler_t *handler, ike_sa_t *ike_sa,
- configuration_attribute_type_t type, chunk_t data)
-{
- enumerator_t *enumerator;
- attribute_handler_t *current;
-
- this->lock->read_lock(this->lock);
- enumerator = this->handlers->create_enumerator(this->handlers);
- while (enumerator->enumerate(enumerator, &current))
- {
- if (current == handler)
- {
- current->release(current, ike_sa, type, data);
- break;
- }
- }
- enumerator->destroy(enumerator);
- this->lock->unlock(this->lock);
-}
-
-/**
- * Implementation of attribute_manager_t.add_handler
- */
-static void add_handler(private_attribute_manager_t *this,
- attribute_handler_t *handler)
-{
- this->lock->write_lock(this->lock);
- this->handlers->insert_last(this->handlers, handler);
- this->lock->unlock(this->lock);
-}
-
-/**
- * Implementation of attribute_manager_t.remove_handler
- */
-static void remove_handler(private_attribute_manager_t *this,
- attribute_handler_t *handler)
-{
- this->lock->write_lock(this->lock);
- this->handlers->remove(this->handlers, handler, NULL);
- this->lock->unlock(this->lock);
-}
-
-/**
- * Implementation of attribute_manager_t.destroy
- */
-static void destroy(private_attribute_manager_t *this)
-{
- this->providers->destroy(this->providers);
- this->handlers->destroy(this->handlers);
- this->lock->destroy(this->lock);
- free(this);
-}
-
-/*
- * see header file
- */
-attribute_manager_t *attribute_manager_create()
-{
- private_attribute_manager_t *this = malloc_thing(private_attribute_manager_t);
-
- this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,host_t*))acquire_address;
- this->public.release_address = (void(*)(attribute_manager_t*, char *, host_t*, identification_t*))release_address;
- this->public.create_attribute_enumerator = (enumerator_t*(*)(attribute_manager_t*, identification_t *id))create_attribute_enumerator;
- this->public.add_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))add_provider;
- this->public.remove_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))remove_provider;
- this->public.handle = (attribute_handler_t*(*)(attribute_manager_t*, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data))handle;
- this->public.release = (void(*)(attribute_manager_t*, attribute_handler_t *handler, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data))release;
- this->public.add_handler = (void(*)(attribute_manager_t*, attribute_handler_t *handler))add_handler;
- this->public.remove_handler = (void(*)(attribute_manager_t*, attribute_handler_t *handler))remove_handler;
- this->public.destroy = (void(*)(attribute_manager_t*))destroy;
-
- this->providers = linked_list_create();
- this->handlers = linked_list_create();
- this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
-
- return &this->public;
-}
-
diff --git a/src/charon/config/attributes/attribute_manager.h b/src/charon/config/attributes/attribute_manager.h
deleted file mode 100644
index ceea06581..000000000
--- a/src/charon/config/attributes/attribute_manager.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2008-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.
- */
-
-/**
- * @defgroup attribute_manager attribute_manager
- * @{ @ingroup attributes
- */
-
-#ifndef ATTRIBUTE_MANAGER_H_
-#define ATTRIBUTE_MANAGER_H_
-
-#include <config/attributes/attribute_provider.h>
-#include <config/attributes/attribute_handler.h>
-
-typedef struct attribute_manager_t attribute_manager_t;
-
-/**
- * The attribute manager hands out attributes or handles them.
- *
- * The attribute manager manages both, attribute providers and attribute
- * handlers. Attribute providers are responsible to hand out attributes if
- * a connecting peer requests them. Handlers handle such attributes if they
- * are received on the requesting peer.
- */
-struct attribute_manager_t {
-
- /**
- * Acquire a virtual IP address to assign to a peer.
- *
- * @param pool pool name to acquire address from
- * @param id peer identity to get address forua
- * @param requested IP in configuration request
- * @return allocated address, NULL to serve none
- */
- host_t* (*acquire_address)(attribute_manager_t *this,
- char *pool, identification_t *id,
- host_t *requested);
-
- /**
- * Release a previously acquired address.
- *
- * @param pool pool name from which the address was acquired
- * @param address address to release
- * @param id peer identity to get address for
- */
- void (*release_address)(attribute_manager_t *this,
- char *pool, host_t *address, identification_t *id);
-
- /**
- * Create an enumerator over attributes to hand out to a peer.
- *
- * @param id peer identity to hand out attributes to
- * @return enumerator (configuration_attribute_type_t, chunk_t)
- */
- enumerator_t* (*create_attribute_enumerator)(attribute_manager_t *this,
- identification_t *id);
-
- /**
- * Register an attribute provider to the manager.
- *
- * @param provider attribute provider to register
- */
- void (*add_provider)(attribute_manager_t *this,
- attribute_provider_t *provider);
- /**
- * Unregister an attribute provider from the manager.
- *
- * @param provider attribute provider to unregister
- */
- void (*remove_provider)(attribute_manager_t *this,
- attribute_provider_t *provider);
-
- /**
- * Handle a configuration attribute by passing them to the handlers.
- *
- * @param ike_sa IKE_SA where attribute was received
- * @param type type of configuration attribute
- * @param data associated attribute data
- * @return handler which handled this attribute, NULL if none
- */
- attribute_handler_t* (*handle)(attribute_manager_t *this, ike_sa_t *ike_sa,
- configuration_attribute_type_t type, chunk_t data);
-
- /**
- * Release an attribute previously handle()d by a handler.
- *
- * @param handler handler returned by handle() for this attribute
- * @param ike_sa IKE_SA owning the attribute
- * @param type type of attribute to release
- * @param data associated attribute data
- */
- void (*release)(attribute_manager_t *this, attribute_handler_t *handler,
- ike_sa_t *ike_sa, configuration_attribute_type_t type,
- chunk_t data);
-
- /**
- * Register an attribute handler to the manager.
- *
- * @param handler attribute handler to register
- */
- void (*add_handler)(attribute_manager_t *this,
- attribute_handler_t *handler);
-
- /**
- * Unregister an attribute handler from the manager.
- *
- * @param handler attribute handler to unregister
- */
- void (*remove_handler)(attribute_manager_t *this,
- attribute_handler_t *handler);
-
- /**
- * Destroy a attribute_manager instance.
- */
- void (*destroy)(attribute_manager_t *this);
-};
-
-/**
- * Create a attribute_manager instance.
- */
-attribute_manager_t *attribute_manager_create();
-
-#endif /** ATTRIBUTE_MANAGER_H_ @}*/
diff --git a/src/charon/config/attributes/attribute_provider.h b/src/charon/config/attributes/attribute_provider.h
deleted file mode 100644
index 0f1057af4..000000000
--- a/src/charon/config/attributes/attribute_provider.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 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 attribute_provider attribute_provider
- * @{ @ingroup attributes
- */
-
-#ifndef ATTRIBUTE_PROVIDER_H_
-#define ATTRIBUTE_PROVIDER_H_
-
-#include <library.h>
-#include <utils/host.h>
-#include <utils/identification.h>
-
-typedef struct attribute_provider_t attribute_provider_t;
-
-/**
- * Interface to provide attributes to peers through attribute manager.
- */
-struct attribute_provider_t {
-
- /**
- * Acquire a virtual IP address to assign to a peer.
- *
- * @param pool name of the pool to acquire address from
- * @param id peer ID
- * @param requested IP in configuration request
- * @return allocated address, NULL to serve none
- */
- host_t* (*acquire_address)(attribute_provider_t *this,
- char *pool, identification_t *id,
- host_t *requested);
- /**
- * Release a previously acquired address.
- *
- * @param pool name of the pool this address was acquired from
- * @param address address to release
- * @param id peer ID
- * @return TRUE if the address has been released by the provider
- */
- bool (*release_address)(attribute_provider_t *this,
- char *pool, host_t *address, identification_t *id);
-
- /**
- * Create an enumerator over attributes to hand out to a peer.
- *
- * @param id peer ID
- * @return enumerator (configuration_attribute_type_t, chunk_t)
- */
- enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this,
- identification_t *id);
-};
-
-#endif /** ATTRIBUTE_PROVIDER_H_ @}*/
diff --git a/src/charon/config/auth_cfg.c b/src/charon/config/auth_cfg.c
index e4501bc93..94362c756 100644
--- a/src/charon/config/auth_cfg.c
+++ b/src/charon/config/auth_cfg.c
@@ -45,12 +45,12 @@ 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
*/
@@ -84,7 +84,7 @@ typedef struct {
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;
@@ -110,7 +110,7 @@ static void entry_enumerator_destroy(entry_enumerator_t *this)
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;
@@ -168,9 +168,9 @@ static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
if (enumerator->current)
{
va_list args;
-
+
va_start(args, type);
-
+
destroy_entry_value(enumerator->current);
enumerator->current->type = type;
switch (type)
@@ -210,7 +210,7 @@ static void* get(private_auth_cfg_t *this, auth_rule_t type)
void *current_value, *best_value = NULL;
auth_rule_t current_type;
bool found = FALSE;
-
+
enumerator = create_enumerator(this);
while (enumerator->enumerate(enumerator, &current_type, &current_value))
{
@@ -270,7 +270,7 @@ 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)
@@ -311,7 +311,7 @@ static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
bool success = TRUE;
auth_rule_t t1, t2;
void *value;
-
+
e1 = constraints->create_enumerator(constraints);
while (e1->enumerate(e1, &t1, &value))
{
@@ -321,9 +321,9 @@ static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
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))
@@ -345,7 +345,7 @@ static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
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))
@@ -364,7 +364,7 @@ static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
case AUTH_RULE_OCSP_VALIDATION:
{
cert_validation_t validated, required;
-
+
required = (uintptr_t)value;
validated = (uintptr_t)get(this, t1);
switch (required)
@@ -401,7 +401,7 @@ static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
case AUTH_RULE_EAP_IDENTITY:
{
identification_t *id1, *id2;
-
+
id1 = (identification_t*)value;
id2 = get(this, t1);
if (!id2 || !id2->matches(id2, id1))
@@ -499,7 +499,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
enumerator_t *enumerator;
auth_rule_t type;
void *value;
-
+
enumerator = create_enumerator(other);
while (enumerator->enumerate(enumerator, &type, &value))
{
@@ -512,7 +512,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
case AUTH_HELPER_SUBJECT_CERT:
{
certificate_t *cert = (certificate_t*)value;
-
+
add(this, type, cert->get_ref(cert));
break;
}
@@ -530,7 +530,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
case AUTH_RULE_AC_GROUP:
{
identification_t *id = (identification_t*)value;
-
+
add(this, type, id->clone(id));
break;
}
@@ -547,7 +547,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
else
{
entry_t *entry;
-
+
while (other->entries->remove_first(other->entries,
(void**)&entry) == SUCCESS)
{
@@ -564,7 +564,7 @@ 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))
{
@@ -601,10 +601,10 @@ static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
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;
@@ -617,10 +617,10 @@ static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
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;
@@ -660,7 +660,7 @@ 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)
{
@@ -689,7 +689,7 @@ 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))
@@ -749,7 +749,7 @@ static void destroy(private_auth_cfg_t *this)
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;
@@ -760,9 +760,9 @@ auth_cfg_t *auth_cfg_create()
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
index c6bc1959b..5e6215a4a 100644
--- a/src/charon/config/auth_cfg.h
+++ b/src/charon/config/auth_cfg.h
@@ -41,7 +41,7 @@ typedef enum auth_rule_t auth_rule_t;
* 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 */
@@ -64,7 +64,7 @@ enum auth_rule_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* */
@@ -86,7 +86,7 @@ extern enum_name_t *auth_rule_names;
* 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
+ * Remote peer configs are called "constraits", they define what is needed to
* complete the authentication round successfully.
*
* @verbatim
@@ -122,7 +122,7 @@ struct auth_cfg_t {
* @param ... associated value to rule
*/
void (*add)(auth_cfg_t *this, auth_rule_t rule, ...);
-
+
/**
* Get an rule value.
*
@@ -130,14 +130,14 @@ struct auth_cfg_t {
* @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.
*
@@ -147,7 +147,7 @@ struct auth_cfg_t {
*/
void (*replace)(auth_cfg_t *this, enumerator_t *pos,
auth_rule_t rule, ...);
-
+
/**
* Check if a used config fulfills a set of configured constraints.
*
@@ -156,7 +156,7 @@ struct auth_cfg_t {
* @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.
*
@@ -164,14 +164,14 @@ struct auth_cfg_t {
* @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.
*
@@ -179,14 +179,14 @@ struct auth_cfg_t {
* @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.
*/
diff --git a/src/charon/config/backend_manager.c b/src/charon/config/backend_manager.c
index cfd611858..90ef58563 100644
--- a/src/charon/config/backend_manager.c
+++ b/src/charon/config/backend_manager.c
@@ -16,11 +16,10 @@
#include "backend_manager.h"
#include <sys/types.h>
-#include <pthread.h>
#include <daemon.h>
#include <utils/linked_list.h>
-#include <utils/mutex.h>
+#include <threading/rwlock.h>
typedef struct private_backend_manager_t private_backend_manager_t;
@@ -34,12 +33,12 @@ 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
*/
@@ -52,7 +51,7 @@ struct private_backend_manager_t {
typedef enum ike_cfg_match_t {
MATCH_NONE = 0x00,
MATCH_ANY = 0x01,
- MATCH_ME = 0x04,
+ MATCH_ME = 0x04,
MATCH_OTHER = 0x08,
} ike_cfg_match_t;
@@ -80,7 +79,7 @@ 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),
@@ -103,7 +102,7 @@ static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other)
{
match += MATCH_ANY;
}
-
+
if (other)
{
other_cand = host_create_from_dns(cand->get_other_addr(cand),
@@ -132,21 +131,21 @@ static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other)
/**
* implements backend_manager_t.get_ike_cfg.
*/
-static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
+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),
@@ -154,11 +153,11 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
while (enumerator->enumerate(enumerator, (void**)&current))
{
match = get_ike_match(current, me, other);
-
+
if (match)
{
- DBG2(DBG_CFG, " candidate: %s...%s, prio %d",
- current->get_my_addr(current),
+ DBG2(DBG_CFG, " candidate: %s...%s, prio %d",
+ current->get_my_addr(current),
current->get_other_addr(current), match);
if (match > best)
{
@@ -173,7 +172,7 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
this->lock->unlock(this->lock);
if (found)
{
- DBG2(DBG_CFG, "found matching ike config: %s...%s with prio %d",
+ 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;
@@ -189,12 +188,12 @@ static id_match_t get_peer_match(identification_t *id,
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))
@@ -269,7 +268,7 @@ static bool peer_enum_filter(linked_list_t *configs,
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);
@@ -285,7 +284,7 @@ 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**)&current) == SUCCESS)
{
helper->insert_last(helper, current);
@@ -311,7 +310,7 @@ static void insert_sorted(match_entry_t *entry, linked_list_t *list,
/**
* 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)
@@ -320,26 +319,26 @@ static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this,
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();
@@ -348,16 +347,16 @@ static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this,
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;
@@ -367,7 +366,7 @@ static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this,
}
enumerator->destroy(enumerator);
helper->destroy(helper);
-
+
return enumerator_create_filter(configs->create_enumerator(configs),
(void*)peer_enum_filter, configs,
(void*)peer_enum_filter_destroy);
@@ -375,13 +374,13 @@ static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this,
/**
* 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))
@@ -429,17 +428,17 @@ static void destroy(private_backend_manager_t *this)
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
index 0b7d7d0f8..5b394f791 100644
--- a/src/charon/config/backend_manager.h
+++ b/src/charon/config/backend_manager.h
@@ -46,11 +46,11 @@ typedef struct backend_manager_t backend_manager_t;
| |----->| | +--------------+ |
| | | | |
+---------+ +-----------+ |
-
+
@endverbatim
*/
struct backend_manager_t {
-
+
/**
* Get an ike_config identified by two hosts.
*
@@ -58,9 +58,9 @@ struct backend_manager_t {
* @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,
+ 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.
*
@@ -68,7 +68,7 @@ struct backend_manager_t {
* @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.
*
@@ -90,14 +90,14 @@ struct backend_manager_t {
* @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.
*/
diff --git a/src/charon/config/child_cfg.c b/src/charon/config/child_cfg.c
index 990ee3fd6..8410b3fe5 100644
--- a/src/charon/config/child_cfg.c
+++ b/src/charon/config/child_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2009 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -25,7 +25,7 @@ ENUM(action_names, ACTION_NONE, ACTION_RESTART,
"restart",
);
-ENUM_BEGIN(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_NONE,
+ENUM_BEGIN(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_NONE,
"IPCOMP_NONE");
ENUM_NEXT(ipcomp_transform_names, IPCOMP_OUI, IPCOMP_LZJH, IPCOMP_NONE,
"IPCOMP_OUI",
@@ -45,79 +45,73 @@ 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;
-
- /**
- * Time before an SA gets invalid
- */
- u_int32_t lifetime;
-
- /**
- * Time before an SA gets rekeyed
- */
- u_int32_t rekeytime;
-
+
/**
- * Time, which specifies the range of a random value
- * substracted from rekeytime.
+ * CHILD_SA lifetime config
*/
- u_int32_t jitter;
-
+ 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;
@@ -152,7 +146,7 @@ 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, &current))
{
@@ -164,7 +158,7 @@ static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh)
proposals->insert_last(proposals, current);
}
enumerator->destroy(enumerator);
-
+
return proposals;
}
@@ -172,14 +166,15 @@ static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh)
* Implementation of child_cfg_t.select_proposal.
*/
static proposal_t* select_proposal(private_child_cfg_t*this,
- linked_list_t *proposals, bool strip_dh)
+ 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))
{
@@ -190,7 +185,7 @@ static proposal_t* select_proposal(private_child_cfg_t*this,
{
stored->strip_dh(stored);
}
- selected = stored->select(stored, supplied);
+ selected = stored->select(stored, supplied, private);
if (selected)
{
DBG2(DBG_CFG, "received proposals: %#P", proposals);
@@ -205,7 +200,7 @@ static proposal_t* select_proposal(private_child_cfg_t*this,
break;
}
supplied_enum->destroy(supplied_enum);
- supplied_enum = proposals->create_enumerator(proposals);
+ supplied_enum = proposals->create_enumerator(proposals);
}
stored_enum->destroy(stored_enum);
supplied_enum->destroy(supplied_enum);
@@ -243,7 +238,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
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);
@@ -252,11 +247,11 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
{
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:",
+ DBG2(DBG_CFG, "proposing traffic selectors for %s:",
local ? "us" : "other");
while (e1->enumerate(e1, &ts1))
{
@@ -273,7 +268,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
}
else
{
- DBG2(DBG_CFG, "selecting traffic selectors for %s:",
+ DBG2(DBG_CFG, "selecting traffic selectors for %s:",
local ? "us" : "other");
e2 = supplied->create_enumerator(supplied);
/* iterate over all stored selectors */
@@ -285,7 +280,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
{
ts1->set_address(ts1, host);
}
-
+
/* iterate over all supplied traffic selectors */
while (e2->enumerate(e2, &ts2))
{
@@ -309,7 +304,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
e1->destroy(e1);
e2->destroy(e2);
}
-
+
/* remove any redundant traffic selectors in the list */
e1 = result->create_enumerator(result);
e2 = result->create_enumerator(result);
@@ -340,7 +335,7 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
}
e1->destroy(e1);
e2->destroy(e2);
-
+
return result;
}
@@ -361,19 +356,32 @@ static bool get_hostaccess(private_child_cfg_t *this)
}
/**
- * Implementation of child_cfg_t.get_lifetime.
+ * 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_int32_t get_lifetime(private_child_cfg_t *this, bool rekey)
+static u_int64_t apply_jitter(u_int64_t rekey, u_int64_t jitter)
{
- if (rekey)
+ if (jitter == 0)
{
- if (this->jitter == 0)
- {
- return this->rekeytime;
- }
- return this->rekeytime - (random() % this->jitter);
+ return rekey;
}
- return this->lifetime;
+ 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;
}
/**
@@ -408,7 +416,7 @@ 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))
{
@@ -430,6 +438,14 @@ static bool use_ipcomp(private_child_cfg_t *this)
}
/**
+ * 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,
@@ -486,10 +502,11 @@ static void destroy(private_child_cfg_t *this)
/*
* Described in header-file
*/
-child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
- u_int32_t rekeytime, u_int32_t jitter,
- char *updown, bool hostaccess, ipsec_mode_t mode,
- action_t dpd_action, action_t close_action, bool ipcomp)
+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);
@@ -498,37 +515,37 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
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))select_proposal;
+ 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 = (u_int32_t (*) (child_cfg_t *,bool))get_lifetime;
+ 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->lifetime = lifetime;
- this->rekeytime = rekeytime;
- this->jitter = jitter;
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->use_ipcomp = ipcomp;
+ this->inactivity = inactivity;
this->proxy_mode = FALSE;
- this->install_policy = TRUE;
+ 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
index 33c75701c..c6186ea36 100644
--- a/src/charon/config/child_cfg.h
+++ b/src/charon/config/child_cfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2009 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -25,11 +25,12 @@
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 <config/traffic_selector.h>
#include <kernel/kernel_ipsec.h>
/**
@@ -66,73 +67,90 @@ enum 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.
+ * 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.
- *
+ * 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 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
@@ -141,7 +159,7 @@ struct child_cfg_t {
* 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
@@ -152,74 +170,77 @@ struct child_cfg_t {
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 of a CHILD_SA.
+ * 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.
*
- * If "rekey" is set to TRUE, a lifetime is returned before the first
- * rekeying should be started. If it is FALSE, the actual lifetime is
- * returned when the CHILD_SA must be deleted.
- * The rekey time automatically contains a jitter to avoid simlutaneous
- * rekeying.
- *
- * @param rekey TRUE to get rekey time
- * @return lifetime in seconds
+ * @return lifetime_cfg_t (has to be freed)
*/
- u_int32_t (*get_lifetime) (child_cfg_t *this, bool rekey);
-
+ 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)
*/
@@ -228,27 +249,27 @@ struct child_cfg_t {
/**
* 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.
*
@@ -260,29 +281,30 @@ struct child_cfg_t {
/**
* Create a configuration template for CHILD_SA setup.
- *
+ *
* The "name" string gets cloned.
- * 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
- * (rekeytime - random(0, jitter)). You should specify
- * lifetime > rekeytime > jitter.
+ *
+ * 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 after CHILD_SA expires and gets deleted
- * @param rekeytime time when rekeying should be initiated
- * @param jitter range of randomization time to remove from rekeytime
+ * @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, u_int32_t lifetime,
- u_int32_t rekeytime, u_int32_t jitter,
- char *updown, bool hostaccess, ipsec_mode_t mode,
- action_t dpd_action, action_t close_action, bool ipcomp);
+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
index e80ab577e..2e748f511 100644
--- a/src/charon/config/ike_cfg.c
+++ b/src/charon/config/ike_cfg.c
@@ -32,7 +32,7 @@ struct private_ike_cfg_t {
* Public part
*/
ike_cfg_t public;
-
+
/**
* Number of references hold by others to this ike_cfg
*/
@@ -45,19 +45,19 @@ struct private_ike_cfg_t {
/**
* 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
*/
@@ -71,7 +71,7 @@ static bool send_certreq(private_ike_cfg_t *this)
{
return this->certreq;
}
-
+
/**
* Implementation of ike_cfg_t.force_encap.
*/
@@ -112,7 +112,7 @@ 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**)&current))
{
@@ -120,31 +120,31 @@ static linked_list_t* get_proposals(private_ike_cfg_t *this)
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)
+ 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);
+ selected = stored->select(stored, supplied, private);
if (selected)
{
/* they match, return */
@@ -162,7 +162,7 @@ static proposal_t *select_proposal(private_ike_cfg_t *this,
supplied_iter->destroy(supplied_iter);
DBG1(DBG_CFG, "received proposals: %#P", proposals);
DBG1(DBG_CFG, "configured proposals: %#P", this->proposals);
-
+
return NULL;
}
@@ -174,7 +174,7 @@ 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))
{
@@ -195,7 +195,7 @@ 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;
@@ -260,7 +260,7 @@ 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;
@@ -268,12 +268,12 @@ ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
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*))select_proposal;
+ 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;
@@ -281,6 +281,6 @@ ike_cfg_t *ike_cfg_create(bool certreq, bool 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
index 064906423..eaac321b9 100644
--- a/src/charon/config/ike_cfg.h
+++ b/src/charon/config/ike_cfg.h
@@ -37,71 +37,73 @@ typedef struct ike_cfg_t ike_cfg_t;
* @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);
-
+ 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.
*
@@ -109,17 +111,17 @@ struct ike_cfg_t {
* @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.
*/
@@ -137,7 +139,7 @@ struct ike_cfg_t {
* @param other address/DNS name of remote peer
* @return ike_cfg_t object.
*/
-ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
+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
index f096f269e..9df14c9ae 100644
--- a/src/charon/config/peer_cfg.c
+++ b/src/charon/config/peer_cfg.c
@@ -21,7 +21,7 @@
#include <daemon.h>
-#include <utils/mutex.h>
+#include <threading/mutex.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
@@ -48,113 +48,113 @@ 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
+
+#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)
@@ -239,12 +239,12 @@ static bool child_cfg_enumerate(child_cfg_enumerator_t *this, child_cfg_t **chd)
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;
}
@@ -259,13 +259,13 @@ static int get_ts_match(child_cfg_t *cfg, bool local,
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))
{
@@ -286,9 +286,9 @@ static int get_ts_match(child_cfg_t *cfg, bool local,
round--;
}
sup_enum->destroy(sup_enum);
-
+
cfg_list->destroy_offset(cfg_list, offsetof(traffic_selector_t, destroy));
-
+
return match;
}
@@ -303,16 +303,16 @@ static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
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, &current))
{
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",
@@ -421,7 +421,7 @@ static host_t* get_virtual_ip(private_peer_cfg_t *this)
{
return this->virtual_ip;
}
-
+
/**
* Implementation of peer_cfg_t.get_pool.
*/
@@ -493,7 +493,7 @@ 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))
{
@@ -504,7 +504,7 @@ static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
{
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))
@@ -517,12 +517,12 @@ static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
}
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))
@@ -535,7 +535,7 @@ static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
}
e1->destroy(e1);
e2->destroy(e2);
-
+
return equal;
}
@@ -552,7 +552,7 @@ static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
{
return FALSE;
}
-
+
return (
this->ike_version == other->ike_version &&
this->cert_policy == other->cert_policy &&
@@ -567,7 +567,7 @@ static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
(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 ||
(this->pool && other->pool && streq(this->pool, other->pool))) &&
auth_cfg_equal(this, other)
#ifdef ME
@@ -630,8 +630,8 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
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_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;
@@ -657,7 +657,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
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;
diff --git a/src/charon/config/peer_cfg.h b/src/charon/config/peer_cfg.h
index 3c095eff0..6855276f8 100644
--- a/src/charon/config/peer_cfg.h
+++ b/src/charon/config/peer_cfg.h
@@ -30,7 +30,7 @@ typedef struct peer_cfg_t peer_cfg_t;
#include <library.h>
#include <utils/identification.h>
#include <utils/enumerator.h>
-#include <config/traffic_selector.h>
+#include <selectors/traffic_selector.h>
#include <config/proposal.h>
#include <config/ike_cfg.h>
#include <config/child_cfg.h>
@@ -43,17 +43,17 @@ typedef struct peer_cfg_t peer_cfg_t;
* 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,
+ CERT_ALWAYS_SEND = 0,
/** send certificate upon cert request */
- CERT_SEND_IF_ASKED = 1,
+ CERT_SEND_IF_ASKED = 1,
/** never send a certificate, even when requested */
- CERT_NEVER_SEND = 2,
+ CERT_NEVER_SEND = 2,
};
/**
@@ -108,60 +108,60 @@ extern enum_name_t *unique_policy_names;
* 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).
+ * (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
@@ -171,7 +171,7 @@ struct peer_cfg_t {
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.
*
@@ -179,7 +179,7 @@ struct peer_cfg_t {
* @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.
*
@@ -201,49 +201,49 @@ struct peer_cfg_t {
* @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.
*
@@ -255,37 +255,37 @@ struct peer_cfg_t {
* @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.
- *
+ * of this connection.
+ *
* @return the id of the other peer
*/
identification_t* (*get_peer_id) (peer_cfg_t *this);
@@ -300,14 +300,14 @@ struct peer_cfg_t {
* @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.
*
@@ -319,14 +319,14 @@ struct peer_cfg_t {
/**
* 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)).
- *
+ * (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
diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c
index cf7e19605..6b3500b6e 100644
--- a/src/charon/config/proposal.c
+++ b/src/charon/config/proposal.c
@@ -52,52 +52,52 @@ 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 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
*/
@@ -110,7 +110,7 @@ struct algorithm_t {
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;
@@ -200,7 +200,7 @@ static bool get_algorithm(private_proposal_t *this, transform_type_t type,
{
enumerator_t *enumerator;
bool found = FALSE;
-
+
enumerator = create_enumerator(this, type);
if (enumerator->enumerate(enumerator, alg, key_size))
{
@@ -216,12 +216,12 @@ static bool get_algorithm(private_proposal_t *this, transform_type_t type,
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**)&current))
{
@@ -246,7 +246,7 @@ static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group)
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);
@@ -277,19 +277,19 @@ static bool is_authenticated_encryption(u_int16_t alg)
/**
* Find a matching alg/keysize in two linked lists
*/
-static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add,
- u_int16_t *alg, size_t *key_size)
+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 */
@@ -302,6 +302,13 @@ static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add,
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;
@@ -321,26 +328,27 @@ static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add,
/**
* Implements proposal_t.select.
*/
-static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t *other)
+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,
+ if (select_algo(this->encryption_algos, other->encryption_algos, private,
&add, &algo, &key_size))
{
if (add)
@@ -359,7 +367,7 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t
/* select integrity algorithm */
if (!is_authenticated_encryption(algo))
{
- if (select_algo(this->integrity_algos, other->integrity_algos,
+ if (select_algo(this->integrity_algos, other->integrity_algos, private,
&add, &algo, &key_size))
{
if (add)
@@ -377,7 +385,7 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t
}
}
/* select prf algorithm */
- if (select_algo(this->prf_algos, other->prf_algos,
+ if (select_algo(this->prf_algos, other->prf_algos, private,
&add, &algo, &key_size))
{
if (add)
@@ -394,7 +402,8 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t
return NULL;
}
/* select a DH-group */
- if (select_algo(this->dh_groups, other->dh_groups, &add, &algo, &key_size))
+ if (select_algo(this->dh_groups, other->dh_groups, private,
+ &add, &algo, &key_size))
{
if (add)
{
@@ -408,8 +417,8 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t
transform_type_names, DIFFIE_HELLMAN_GROUP);
return NULL;
}
- /* select if we use ESNs */
- if (select_algo(this->esns, other->esns, &add, &algo, &key_size))
+ /* select if we use ESNs (has no private use space) */
+ if (select_algo(this->esns, other->esns, TRUE, &add, &algo, &key_size))
{
if (add)
{
@@ -424,10 +433,10 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t
return NULL;
}
DBG2(DBG_CFG, " proposal matches");
-
+
/* apply SPI from "other" */
selected->set_spi(selected, other->spi);
-
+
/* everything matched, return new proposal */
return selected;
}
@@ -463,7 +472,7 @@ 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))
{
@@ -482,12 +491,12 @@ 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))
@@ -531,15 +540,15 @@ static bool equals(private_proposal_t *this, private_proposal_t *other)
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;
}
@@ -551,7 +560,7 @@ 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))
{
@@ -562,7 +571,7 @@ static void check_proposal(private_proposal_t *this)
}
}
e->destroy(e);
-
+
if (all_aead)
{
/* if all encryption algorithms in the proposal are authenticated encryption
@@ -613,7 +622,7 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
case AUTH_AES_XCBC_96:
prf = PRF_AES128_XCBC;
break;
- default:
+ default:
prf = PRF_UNDEFINED;
}
if (prf != PRF_UNDEFINED)
@@ -633,7 +642,7 @@ static int print_alg(private_proposal_t *this, char **dst, size_t *len,
enumerator_t *enumerator;
size_t written = 0;
u_int16_t alg, size;
-
+
enumerator = create_enumerator(this, kind);
while (enumerator->enumerate(enumerator, &alg, &size))
{
@@ -666,12 +675,12 @@ int proposal_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
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);
@@ -690,7 +699,7 @@ int proposal_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
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);
@@ -724,29 +733,29 @@ static void destroy(private_proposal_t *this)
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*))select_proposal;
+ 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;
}
@@ -760,7 +769,7 @@ static void proposal_add_supported_ike(private_proposal_t *this)
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))
{
@@ -787,10 +796,10 @@ static void proposal_add_supported_ike(private_proposal_t *this)
break;
default:
break;
- }
+ }
}
enumerator->destroy(enumerator);
-
+
enumerator = lib->crypto->create_signer_enumerator(lib->crypto);
while (enumerator->enumerate(enumerator, &integrity))
{
@@ -806,10 +815,10 @@ static void proposal_add_supported_ike(private_proposal_t *this)
break;
default:
break;
- }
+ }
}
enumerator->destroy(enumerator);
-
+
enumerator = lib->crypto->create_prf_enumerator(lib->crypto);
while (enumerator->enumerate(enumerator, &prf))
{
@@ -828,7 +837,7 @@ static void proposal_add_supported_ike(private_proposal_t *this)
}
}
enumerator->destroy(enumerator);
-
+
enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
while (enumerator->enumerate(enumerator, &group))
{
@@ -865,7 +874,7 @@ static void proposal_add_supported_ike(private_proposal_t *this)
proposal_t *proposal_create_default(protocol_id_t protocol)
{
private_proposal_t *this = (private_proposal_t*)proposal_create(protocol);
-
+
switch (protocol)
{
case PROTO_IKE:
@@ -903,14 +912,14 @@ proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs
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))
{
@@ -925,9 +934,9 @@ proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs
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);
diff --git a/src/charon/config/proposal.h b/src/charon/config/proposal.h
index bc7a8c5e7..30f63b80d 100644
--- a/src/charon/config/proposal.h
+++ b/src/charon/config/proposal.h
@@ -33,7 +33,7 @@ typedef struct proposal_t proposal_t;
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
#include <crypto/diffie_hellman.h>
-#include <config/traffic_selector.h>
+#include <selectors/traffic_selector.h>
/**
* Protocol ID of a proposal.
@@ -65,17 +65,17 @@ extern enum_name_t *extended_sequence_numbers_names;
/**
* Stores a set of algorithms used for an SA.
- *
- * A proposal stores algorithms for a specific
+ *
+ * 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
@@ -84,27 +84,27 @@ struct proposal_t {
* 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
@@ -112,53 +112,54 @@ struct proposal_t {
*/
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);
+ 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);
-
+ 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.
*
@@ -166,14 +167,14 @@ struct proposal_t {
* @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.
*/
@@ -201,7 +202,7 @@ proposal_t *proposal_create_default(protocol_id_t protocol);
*
* The string is in the same form as a in the ipsec.conf file.
* E.g.: aes128-sha2_256-modp2048
- * 3des-md5
+ * 3des-md5
* An additional '!' at the end of the string forces this proposal,
* without it the peer may choose another algorithm we support.
*
@@ -214,10 +215,10 @@ proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs
/**
* printf hook function for proposal_t.
*
- * Arguments are:
- * proposal_t *proposal
+ * Arguments are:
+ * proposal_t *proposal
* With the #-specifier, arguments are:
- * linked_list_t *list containing proposal_t*
+ * 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);
diff --git a/src/charon/config/traffic_selector.c b/src/charon/config/traffic_selector.c
deleted file mode 100644
index a8ea10008..000000000
--- a/src/charon/config/traffic_selector.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- * Copyright (C) 2007-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 <arpa/inet.h>
-#include <string.h>
-#include <netdb.h>
-#include <stdio.h>
-
-#include "traffic_selector.h"
-
-#include <daemon.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-ENUM(ts_type_name, TS_IPV4_ADDR_RANGE, TS_IPV6_ADDR_RANGE,
- "TS_IPV4_ADDR_RANGE",
- "TS_IPV6_ADDR_RANGE",
-);
-
-typedef struct private_traffic_selector_t private_traffic_selector_t;
-
-/**
- * Private data of an traffic_selector_t object
- */
-struct private_traffic_selector_t {
-
- /**
- * Public part
- */
- traffic_selector_t public;
-
- /**
- * Type of address
- */
- ts_type_t type;
-
- /**
- * IP protocol (UDP, TCP, ICMP, ...)
- */
- u_int8_t protocol;
-
- /**
- * narrow this traffic selector to hosts external ip
- * if set, from and to have no meaning until set_address() is called
- */
- bool dynamic;
-
- /**
- * begin of address range, network order
- */
- union {
- /** dummy char for common address manipulation */
- char from[0];
- /** IPv4 address */
- u_int32_t from4[1];
- /** IPv6 address */
- u_int32_t from6[4];
- };
-
- /**
- * end of address range, network order
- */
- union {
- /** dummy char for common address manipulation */
- char to[0];
- /** IPv4 address */
- u_int32_t to4[1];
- /** IPv6 address */
- u_int32_t to6[4];
- };
-
- /**
- * begin of port range
- */
- u_int16_t from_port;
-
- /**
- * end of port range
- */
- u_int16_t to_port;
-};
-
-/**
- * calculate to "to"-address for the "from" address and a subnet size
- */
-static void calc_range(private_traffic_selector_t *this, u_int8_t netbits)
-{
- int byte;
- size_t size = (this->type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
-
- /* go through the from address, starting at the tail. While we
- * have not processed the bits belonging to the host, set them to 1 on
- * the to address. If we reach the bits for the net, copy them from "from". */
- for (byte = size - 1; byte >=0; byte--)
- {
- u_char mask = 0x00;
- int shift;
-
- shift = (byte+1) * 8 - netbits;
- if (shift > 0)
- {
- mask = 1 << shift;
- if (mask != 0xFF)
- {
- mask--;
- }
- }
- this->to[byte] = this->from[byte] | mask;
- }
-}
-
-/**
- * calculate to subnet size from "to"- and "from"-address
- */
-static u_int8_t calc_netbits(private_traffic_selector_t *this)
-{
- int byte, bit;
- size_t size = (this->type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
-
- /* go trough all bits of the addresses, beginning in the front.
- * as long as they are equal, the subnet gets larger
- */
- for (byte = 0; byte < size; byte++)
- {
- for (bit = 7; bit >= 0; bit--)
- {
- if ((1<<bit & this->from[byte]) != (1<<bit & this->to[byte]))
- {
- return ((7 - bit) + (byte * 8));
- }
- }
- }
- /* single host, netmask is 32/128 */
- return (size * 8);
-}
-
-/**
- * internal generic constructor
- */
-static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port);
-
-/**
- * Described in header.
- */
-int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
- const void *const *args)
-{
- private_traffic_selector_t *this = *((private_traffic_selector_t**)(args[0]));
- linked_list_t *list = *((linked_list_t**)(args[0]));
- iterator_t *iterator;
- char addr_str[INET6_ADDRSTRLEN] = "";
- char *serv_proto = NULL;
- u_int8_t mask;
- bool has_proto;
- bool has_ports;
- size_t written = 0;
- u_int32_t from[4], to[4];
-
- if (this == NULL)
- {
- return print_in_hook(dst, len, "(null)");
- }
-
- if (spec->hash)
- {
- iterator = list->create_iterator(list, TRUE);
- while (iterator->iterate(iterator, (void**)&this))
- {
- /* call recursivly */
- written += print_in_hook(dst, len, "%R ", this);
- }
- iterator->destroy(iterator);
- return written;
- }
-
- memset(from, 0, sizeof(from));
- memset(to, 0xFF, sizeof(to));
- if (this->dynamic &&
- memeq(this->from, from, this->type == TS_IPV4_ADDR_RANGE ? 4 : 16) &&
- memeq(this->to, to, this->type == TS_IPV4_ADDR_RANGE ? 4 : 16))
- {
- written += print_in_hook(dst, len, "dynamic");
- }
- else
- {
- if (this->type == TS_IPV4_ADDR_RANGE)
- {
- inet_ntop(AF_INET, &this->from4, addr_str, sizeof(addr_str));
- }
- else
- {
- inet_ntop(AF_INET6, &this->from6, addr_str, sizeof(addr_str));
- }
- mask = calc_netbits(this);
- written += print_in_hook(dst, len, "%s/%d", addr_str, mask);
- }
-
- /* check if we have protocol and/or port selectors */
- has_proto = this->protocol != 0;
- has_ports = !(this->from_port == 0 && this->to_port == 0xFFFF);
-
- if (!has_proto && !has_ports)
- {
- return written;
- }
-
- written += print_in_hook(dst, len, "[");
-
- /* build protocol string */
- if (has_proto)
- {
- struct protoent *proto = getprotobynumber(this->protocol);
-
- if (proto)
- {
- written += print_in_hook(dst, len, "%s", proto->p_name);
- serv_proto = proto->p_name;
- }
- else
- {
- written += print_in_hook(dst, len, "%d", this->protocol);
- }
- }
-
- if (has_proto && has_ports)
- {
- written += print_in_hook(dst, len, "/");
- }
-
- /* build port string */
- if (has_ports)
- {
- if (this->from_port == this->to_port)
- {
- struct servent *serv = getservbyport(htons(this->from_port), serv_proto);
-
- if (serv)
- {
- written += print_in_hook(dst, len, "%s", serv->s_name);
- }
- else
- {
- written += print_in_hook(dst, len, "%d", this->from_port);
- }
- }
- else
- {
- written += print_in_hook(dst, len, "%d-%d", this->from_port, this->to_port);
- }
- }
-
- written += print_in_hook(dst, len, "]");
-
- return written;
-}
-
-/**
- * implements traffic_selector_t.get_subset
- */
-static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_traffic_selector_t *other)
-{
- if (this->type == other->type && (this->protocol == other->protocol ||
- this->protocol == 0 || other->protocol == 0))
- {
- u_int16_t from_port, to_port;
- u_char *from, *to;
- u_int8_t protocol;
- size_t size;
- private_traffic_selector_t *new_ts;
-
- /* calculate the maximum port range allowed for both */
- from_port = max(this->from_port, other->from_port);
- to_port = min(this->to_port, other->to_port);
- if (from_port > to_port)
- {
- return NULL;
- }
- /* select protocol, which is not zero */
- protocol = max(this->protocol, other->protocol);
-
- switch (this->type)
- {
- case TS_IPV4_ADDR_RANGE:
- size = sizeof(this->from4);
- break;
- case TS_IPV6_ADDR_RANGE:
- size = sizeof(this->from6);
- break;
- default:
- return NULL;
- }
-
- /* get higher from-address */
- if (memcmp(this->from, other->from, size) > 0)
- {
- from = this->from;
- }
- else
- {
- from = other->from;
- }
- /* get lower to-address */
- if (memcmp(this->to, other->to, size) > 0)
- {
- to = other->to;
- }
- else
- {
- to = this->to;
- }
- /* if "from" > "to", we don't have a match */
- if (memcmp(from, to, size) > 0)
- {
- return NULL;
- }
-
- /* we have a match in protocol, port, and address: return it... */
- new_ts = traffic_selector_create(protocol, this->type, from_port, to_port);
- new_ts->type = this->type;
- new_ts->dynamic = this->dynamic || other->dynamic;
- memcpy(new_ts->from, from, size);
- memcpy(new_ts->to, to, size);
-
- return &new_ts->public;
- }
- return NULL;
-}
-
-/**
- * implements traffic_selector_t.equals
- */
-static bool equals(private_traffic_selector_t *this, private_traffic_selector_t *other)
-{
- if (this->type != other->type)
- {
- return FALSE;
- }
- if (!(this->from_port == other->from_port &&
- this->to_port == other->to_port &&
- this->protocol == other->protocol))
- {
- return FALSE;
- }
- switch (this->type)
- {
- case TS_IPV4_ADDR_RANGE:
- if (memeq(this->from4, other->from4, sizeof(this->from4)))
- {
- return TRUE;
- }
- break;
- case TS_IPV6_ADDR_RANGE:
- if (memeq(this->from6, other->from6, sizeof(this->from6)))
- {
- return TRUE;
- }
- break;
- default:
- break;
- }
- return FALSE;
-}
-
-/**
- * Implements traffic_selector_t.get_from_address.
- */
-static chunk_t get_from_address(private_traffic_selector_t *this)
-{
- switch (this->type)
- {
- case TS_IPV4_ADDR_RANGE:
- return chunk_create(this->from, sizeof(this->from4));
- case TS_IPV6_ADDR_RANGE:
- return chunk_create(this->from, sizeof(this->from6));
- default:
- return chunk_empty;
- }
-}
-
-/**
- * Implements traffic_selector_t.get_to_address.
- */
-static chunk_t get_to_address(private_traffic_selector_t *this)
-{
- switch (this->type)
- {
- case TS_IPV4_ADDR_RANGE:
- return chunk_create(this->to, sizeof(this->to4));
- case TS_IPV6_ADDR_RANGE:
- return chunk_create(this->to, sizeof(this->to6));
- default:
- return chunk_empty;
- }
-}
-
-/**
- * Implements traffic_selector_t.get_from_port.
- */
-static u_int16_t get_from_port(private_traffic_selector_t *this)
-{
- return this->from_port;
-}
-
-/**
- * Implements traffic_selector_t.get_to_port.
- */
-static u_int16_t get_to_port(private_traffic_selector_t *this)
-{
- return this->to_port;
-}
-
-/**
- * Implements traffic_selector_t.get_type.
- */
-static ts_type_t get_type(private_traffic_selector_t *this)
-{
- return this->type;
-}
-
-/**
- * Implements traffic_selector_t.get_protocol.
- */
-static u_int8_t get_protocol(private_traffic_selector_t *this)
-{
- return this->protocol;
-}
-
-/**
- * Implements traffic_selector_t.is_host.
- */
-static bool is_host(private_traffic_selector_t *this, host_t *host)
-{
- if (host)
- {
- chunk_t addr;
- int family = host->get_family(host);
-
- if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) ||
- (family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE))
- {
- addr = host->get_address(host);
- if (memeq(addr.ptr, this->from, addr.len) &&
- memeq(addr.ptr, this->to, addr.len))
- {
- return TRUE;
- }
- }
- }
- else
- {
- size_t length = (this->type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
-
- if (this->dynamic)
- {
- return TRUE;
- }
-
- if (memeq(this->from, this->to, length))
- {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/**
- * Implementation of traffic_selector_t.is_dynamic
- */
-static bool is_dynamic(private_traffic_selector_t *this)
-{
- return this->dynamic;
-}
-
-/**
- * Implements traffic_selector_t.set_address.
- */
-static void set_address(private_traffic_selector_t *this, host_t *host)
-{
- if (this->dynamic)
- {
- this->type = host->get_family(host) == AF_INET ?
- TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE;
-
- if (host->is_anyaddr(host))
- {
- memset(this->from6, 0x00, sizeof(this->from6));
- memset(this->to6, 0xFF, sizeof(this->to6));
- }
- else
- {
- chunk_t from = host->get_address(host);
- memcpy(this->from, from.ptr, from.len);
- memcpy(this->to, from.ptr, from.len);
- }
- }
-}
-
-/**
- * Implements traffic_selector_t.is_contained_in.
- */
-static bool is_contained_in(private_traffic_selector_t *this,
- private_traffic_selector_t *other)
-{
- private_traffic_selector_t *subset;
- bool contained_in = FALSE;
-
- subset = (private_traffic_selector_t*)get_subset(this, other);
-
- if (subset)
- {
- if (equals(subset, this))
- {
- contained_in = TRUE;
- }
- free(subset);
- }
- return contained_in;
-}
-
-/**
- * Implements traffic_selector_t.includes.
- */
-static bool includes(private_traffic_selector_t *this, host_t *host)
-{
- chunk_t addr;
- int family = host->get_family(host);
-
- if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) ||
- (family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE))
- {
- addr = host->get_address(host);
-
- return memcmp(this->from, addr.ptr, addr.len) <= 0 &&
- memcmp(this->to, addr.ptr, addr.len) >= 0;
- }
-
- return FALSE;
-}
-
-/**
- * Implements traffic_selector_t.to_subnet.
- */
-static void to_subnet(private_traffic_selector_t *this, host_t **net, u_int8_t *mask)
-{
- /* there is no way to do this cleanly, as the address range may
- * be anything else but a subnet. We use from_addr as subnet
- * and try to calculate a usable subnet mask.
- */
- int family, byte;
- u_int16_t port = 0;
- chunk_t net_chunk;
-
- *mask = calc_netbits(this);
-
- switch (this->type)
- {
- case TS_IPV4_ADDR_RANGE:
- {
- family = AF_INET;
- net_chunk.len = sizeof(this->from4);
- break;
- }
- case TS_IPV6_ADDR_RANGE:
- {
- family = AF_INET6;
- net_chunk.len = sizeof(this->from6);
- break;
- }
- default:
- {
- /* unreachable */
- return;
- }
- }
-
- net_chunk.ptr = malloc(net_chunk.len);
- memcpy(net_chunk.ptr, this->from, net_chunk.len);
-
- for (byte = net_chunk.len - 1; byte >= (*mask / 8); --byte)
- {
- int shift = (byte + 1) * 8 - *mask;
- net_chunk.ptr[byte] = net_chunk.ptr[byte] & (0xFF << shift);
- }
-
- if (this->to_port == this->from_port)
- {
- port = this->to_port;
- }
-
- *net = host_create_from_chunk(family, net_chunk, port);
- chunk_free(&net_chunk);
-}
-
-/**
- * Implements traffic_selector_t.clone.
- */
-static traffic_selector_t *clone_(private_traffic_selector_t *this)
-{
- private_traffic_selector_t *clone;
-
- clone = traffic_selector_create(this->protocol, this->type,
- this->from_port, this->to_port);
-
- clone->dynamic = this->dynamic;
- switch (clone->type)
- {
- case TS_IPV4_ADDR_RANGE:
- {
- memcpy(clone->from4, this->from4, sizeof(this->from4));
- memcpy(clone->to4, this->to4, sizeof(this->to4));
- return &clone->public;
- }
- case TS_IPV6_ADDR_RANGE:
- {
- memcpy(clone->from6, this->from6, sizeof(this->from6));
- memcpy(clone->to6, this->to6, sizeof(this->to6));
- return &clone->public;
- }
- default:
- {
- /* unreachable */
- return &clone->public;
- }
- }
-}
-
-/**
- * Implements traffic_selector_t.destroy.
- */
-static void destroy(private_traffic_selector_t *this)
-{
- free(this);
-}
-
-/*
- * see header
- */
-traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol,
- ts_type_t type,
- chunk_t from, u_int16_t from_port,
- chunk_t to, u_int16_t to_port)
-{
- private_traffic_selector_t *this = traffic_selector_create(protocol, type,
- from_port, to_port);
-
- switch (type)
- {
- case TS_IPV4_ADDR_RANGE:
- {
- if (from.len != 4 || to.len != 4)
- {
- free(this);
- return NULL;
- }
- memcpy(this->from4, from.ptr, from.len);
- memcpy(this->to4, to.ptr, to.len);
- break;
- }
- case TS_IPV6_ADDR_RANGE:
- {
- if (from.len != 16 || to.len != 16)
- {
- free(this);
- return NULL;
- }
- memcpy(this->from6, from.ptr, from.len);
- memcpy(this->to6, to.ptr, to.len);
- break;
- }
- default:
- {
- free(this);
- return NULL;
- }
- }
- return (&this->public);
-}
-
-/*
- * see header
- */
-traffic_selector_t *traffic_selector_create_from_subnet(host_t *net,
- u_int8_t netbits, u_int8_t protocol, u_int16_t port)
-{
- private_traffic_selector_t *this = traffic_selector_create(protocol, 0, 0, 65535);
-
- switch (net->get_family(net))
- {
- case AF_INET:
- {
- chunk_t from;
-
- this->type = TS_IPV4_ADDR_RANGE;
- from = net->get_address(net);
- memcpy(this->from4, from.ptr, from.len);
- if (this->from4[0] == 0)
- {
- /* use /0 for 0.0.0.0 */
- this->to4[0] = ~0;
- }
- else
- {
- calc_range(this, netbits);
- }
- break;
- }
- case AF_INET6:
- {
- chunk_t from;
-
- this->type = TS_IPV6_ADDR_RANGE;
- from = net->get_address(net);
- memcpy(this->from6, from.ptr, from.len);
- if (this->from6[0] == 0 && this->from6[1] == 0 &&
- this->from6[2] == 0 && this->from6[3] == 0)
- {
- /* use /0 for ::0 */
- this->to6[0] = ~0;
- this->to6[1] = ~0;
- this->to6[2] = ~0;
- this->to6[3] = ~0;
- }
- else
- {
- calc_range(this, netbits);
- }
- break;
- }
- default:
- {
- net->destroy(net);
- free(this);
- return NULL;
- }
- }
- if (port)
- {
- this->from_port = port;
- this->to_port = port;
- }
- net->destroy(net);
- return (&this->public);
-}
-
-/*
- * see header
- */
-traffic_selector_t *traffic_selector_create_from_string(
- u_int8_t protocol, ts_type_t type,
- char *from_addr, u_int16_t from_port,
- char *to_addr, u_int16_t to_port)
-{
- private_traffic_selector_t *this = traffic_selector_create(protocol, type,
- from_port, to_port);
-
- this->type = type;
- switch (type)
- {
- case TS_IPV4_ADDR_RANGE:
- {
- if (inet_pton(AF_INET, from_addr, (struct in_addr*)this->from4) < 0)
- {
- free(this);
- return NULL;
- }
- if (inet_pton(AF_INET, to_addr, (struct in_addr*)this->to4) < 0)
- {
- free(this);
- return NULL;
- }
- break;
- }
- case TS_IPV6_ADDR_RANGE:
- {
- if (inet_pton(AF_INET6, from_addr, (struct in6_addr*)this->from6) < 0)
- {
- free(this);
- return NULL;
- }
- if (inet_pton(AF_INET6, to_addr, (struct in6_addr*)this->to6) < 0)
- {
- free(this);
- return NULL;
- }
- break;
- }
- }
- return (&this->public);
-}
-
-/*
- * see header
- */
-traffic_selector_t *traffic_selector_create_dynamic(u_int8_t protocol,
- u_int16_t from_port, u_int16_t to_port)
-{
- private_traffic_selector_t *this = traffic_selector_create(
- protocol, TS_IPV4_ADDR_RANGE, from_port, to_port);
-
- memset(this->from6, 0, sizeof(this->from6));
- memset(this->to6, 0xFF, sizeof(this->to6));
-
- this->dynamic = TRUE;
-
- return &this->public;
-}
-
-/*
- * see declaration
- */
-static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol,
- ts_type_t type, u_int16_t from_port, u_int16_t to_port)
-{
- private_traffic_selector_t *this = malloc_thing(private_traffic_selector_t);
-
- /* public functions */
- this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset;
- this->public.equals = (bool(*)(traffic_selector_t*,traffic_selector_t*))equals;
- this->public.get_from_address = (chunk_t(*)(traffic_selector_t*))get_from_address;
- this->public.get_to_address = (chunk_t(*)(traffic_selector_t*))get_to_address;
- this->public.get_from_port = (u_int16_t(*)(traffic_selector_t*))get_from_port;
- this->public.get_to_port = (u_int16_t(*)(traffic_selector_t*))get_to_port;
- this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type;
- this->public.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol;
- this->public.is_host = (bool(*)(traffic_selector_t*,host_t*))is_host;
- this->public.is_dynamic = (bool(*)(traffic_selector_t*))is_dynamic;
- this->public.is_contained_in = (bool(*)(traffic_selector_t*,traffic_selector_t*))is_contained_in;
- this->public.includes = (bool(*)(traffic_selector_t*,host_t*))includes;
- this->public.set_address = (void(*)(traffic_selector_t*,host_t*))set_address;
- this->public.to_subnet = (void(*)(traffic_selector_t*,host_t**,u_int8_t*))to_subnet;
- this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone_;
- this->public.destroy = (void(*)(traffic_selector_t*))destroy;
-
- this->from_port = from_port;
- this->to_port = to_port;
- this->protocol = protocol;
- this->type = type;
- this->dynamic = FALSE;
-
- return this;
-}
-
diff --git a/src/charon/config/traffic_selector.h b/src/charon/config/traffic_selector.h
deleted file mode 100644
index a57da43a8..000000000
--- a/src/charon/config/traffic_selector.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2007 Tobias Brunner
- * Copyright (C) 2005-2006 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 traffic_selector traffic_selector
- * @{ @ingroup config
- */
-
-#ifndef TRAFFIC_SELECTOR_H_
-#define TRAFFIC_SELECTOR_H_
-
-typedef enum ts_type_t ts_type_t;
-typedef struct traffic_selector_t traffic_selector_t;
-
-#include <library.h>
-#include <utils/host.h>
-
-/**
- * Traffic selector types.
- */
-enum ts_type_t {
-
- /**
- * A range of IPv4 addresses, represented by two four (4) octet
- * values. The first value is the beginning IPv4 address
- * (inclusive) and the second value is the ending IPv4 address
- * (inclusive). All addresses falling between the two specified
- * addresses are considered to be within the list.
- */
- TS_IPV4_ADDR_RANGE = 7,
-
- /**
- * A range of IPv6 addresses, represented by two sixteen (16)
- * octet values. The first value is the beginning IPv6 address
- * (inclusive) and the second value is the ending IPv6 address
- * (inclusive). All addresses falling between the two specified
- * addresses are considered to be within the list.
- */
- TS_IPV6_ADDR_RANGE = 8
-};
-
-/**
- * enum names for ts_type_t
- */
-extern enum_name_t *ts_type_name;
-
-/**
- * Object representing a traffic selector entry.
- *
- * A traffic selector defines an range of addresses
- * and a range of ports. IPv6 is not fully supported yet.
- */
-struct traffic_selector_t {
-
- /**
- * Compare two traffic selectors, and create a new one
- * which is the largest subset of both (subnet & port).
- *
- * Resulting traffic_selector is newly created and must be destroyed.
- *
- * @param other traffic selector to compare
- * @return
- * - created subset of them
- * - or NULL if no match between this and other
- */
- traffic_selector_t *(*get_subset) (traffic_selector_t *this,
- traffic_selector_t *other);
-
- /**
- * Clone a traffic selector.
- *
- * @return clone of it
- */
- traffic_selector_t *(*clone) (traffic_selector_t *this);
-
- /**
- * Get starting address of this ts as a chunk.
- *
- * Chunk is in network order and points to internal data.
- *
- * @return chunk containing the address
- */
- chunk_t (*get_from_address) (traffic_selector_t *this);
-
- /**
- * Get ending address of this ts as a chunk.
- *
- * Chunk is in network order and points to internal data.
- *
- * @return chunk containing the address
- */
- chunk_t (*get_to_address) (traffic_selector_t *this);
-
- /**
- * Get starting port of this ts.
- *
- * Port is in host order, since the parser converts it.
- * Size depends on protocol.
- *
- * @return port
- */
- u_int16_t (*get_from_port) (traffic_selector_t *this);
-
- /**
- * Get ending port of this ts.
- *
- * Port is in host order, since the parser converts it.
- * Size depends on protocol.
- *
- * @return port
- */
- u_int16_t (*get_to_port) (traffic_selector_t *this);
-
- /**
- * Get the type of the traffic selector.
- *
- * @return ts_type_t specifying the type
- */
- ts_type_t (*get_type) (traffic_selector_t *this);
-
- /**
- * Get the protocol id of this ts.
- *
- * @return protocol id
- */
- u_int8_t (*get_protocol) (traffic_selector_t *this);
-
- /**
- * Check if the traffic selector is for a single host.
- *
- * Traffic selector may describe the end of *-to-host tunnel. In this
- * case, the address range is a single address equal to the hosts
- * peer address.
- * If host is NULL, the traffic selector is checked if it is a single host,
- * but not a specific one.
- *
- * @param host host_t specifying the address range
- */
- bool (*is_host) (traffic_selector_t *this, host_t* host);
-
- /**
- * Check if a traffic selector has been created by create_dynamic().
- *
- * @return TRUE if TS is dynamic
- */
- bool (*is_dynamic)(traffic_selector_t *this);
-
- /**
- * Update the address of a traffic selector.
- *
- * Update the address range of a traffic selector, if it is
- * constructed with the traffic_selector_create_dynamic().
- *
- * @param host host_t specifying the address
- */
- void (*set_address) (traffic_selector_t *this, host_t* host);
-
- /**
- * Compare two traffic selectors for equality.
- *
- * @param other ts to compare with this
- * @return TRUE if equal, FALSE otherwise
- */
- bool (*equals) (traffic_selector_t *this, traffic_selector_t *other);
-
- /**
- * Check if a traffic selector is contained completly in another.
- *
- * contains() allows to check if multiple traffic selectors are redundant.
- *
- * @param other ts that contains this
- * @return TRUE if other contains this completly, FALSE otherwise
- */
- bool (*is_contained_in) (traffic_selector_t *this, traffic_selector_t *other);
-
- /**
- * Check if a specific host is included in the address range of
- * this traffic selector.
- *
- * @param host the host to check
- */
- bool (*includes) (traffic_selector_t *this, host_t *host);
-
- /**
- * Convert a traffic selector address range to a subnet
- * and its net mask.
- * If from and to ports of this traffic selector are equal,
- * the port of the returned host_t is set to that port.
- *
- * @param net converted subnet (has to be freed)
- * @param mask converted net mask
- */
- void (*to_subnet) (traffic_selector_t *this, host_t **net, u_int8_t *mask);
-
- /**
- * Destroys the ts object
- */
- void (*destroy) (traffic_selector_t *this);
-};
-
-/**
- * Create a new traffic selector using human readable params.
- *
- * @param protocol protocol for this ts, such as TCP or UDP
- * @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
- * @param from_addr start of address range as string
- * @param from_port port number in host order
- * @param to_addr end of address range as string
- * @param to_port port number in host order
- * @return
- * - traffic_selector_t object
- * - NULL if invalid address strings/protocol
- */
-traffic_selector_t *traffic_selector_create_from_string(
- u_int8_t protocol, ts_type_t type,
- char *from_addr, u_int16_t from_port,
- char *to_addr, u_int16_t to_port);
-
-/**
- * Create a new traffic selector using data read from the net.
- *
- * There exists a mix of network and host order in the params.
- * But the parser gives us this data in this format, so we
- * don't have to convert twice.
- *
- * @param protocol protocol for this ts, such as TCP or UDP
- * @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
- * @param from_address start of address range, network order
- * @param from_port port number, host order
- * @param to_address end of address range, network order
- * @param to_port port number, host order
- * @return traffic_selector_t object
- */
-traffic_selector_t *traffic_selector_create_from_bytes(
- u_int8_t protocol, ts_type_t type,
- chunk_t from_address, u_int16_t from_port,
- chunk_t to_address, u_int16_t to_port);
-
-/**
- * Create a new traffic selector defining a whole subnet.
- *
- * In most cases, definition of a traffic selector for full subnets
- * is sufficient. This constructor creates a traffic selector for
- * all protocols, all ports and the address range specified by the
- * subnet.
- * Additionally, a protocol and a port may be specified. Port ranges
- * are not supported via this constructor.
- *
- * @param net subnet to use
- * @param netbits size of the subnet, as used in e.g. 192.168.0.0/24 notation
- * @param protocol protocol for this ts, such as TCP or UDP
- * @param port port number, host order
- * @return
- * - traffic_selector_t object
- * - NULL if address family of net not supported
- */
-traffic_selector_t *traffic_selector_create_from_subnet(
- host_t *net, u_int8_t netbits,
- u_int8_t protocol, u_int16_t port);
-
-/**
- * Create a traffic selector for host-to-host cases.
- *
- * For host2host or virtual IP setups, the traffic selectors gets
- * created at runtime using the external/virtual IP. Using this constructor,
- * a call to set_address() sets this traffic selector to the supplied host.
- *
- *
- * @param protocol upper layer protocl to allow
- * @param from_port start of allowed port range
- * @param to_port end of range
- * @return
- * - traffic_selector_t object
- * - NULL if type not supported
- */
-traffic_selector_t *traffic_selector_create_dynamic(u_int8_t protocol,
- u_int16_t from_port, u_int16_t to_port);
-
-/**
- * printf hook function for traffic_selector_t.
- *
- * Arguments are:
- * traffic_selector_t *ts
- * With the #-specifier, arguments are:
- * linked_list_t *list containing traffic_selector_t*
- */
-int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
- const void *const *args);
-
-#endif /** TRAFFIC_SELECTOR_H_ @}*/