From 9937ca069ad4fb26aeaf1b5c72820afdcd93ae16 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Tue, 31 Jul 2012 10:39:16 +0200 Subject: Serve ipsec.conf rightdns servers through stroke attribute provider --- src/libcharon/plugins/stroke/stroke_attribute.c | 153 ++++++++++++++++++++++-- 1 file changed, 143 insertions(+), 10 deletions(-) (limited to 'src/libcharon/plugins/stroke/stroke_attribute.c') diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c index 1e4615e12..aa3b1d20c 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.c +++ b/src/libcharon/plugins/stroke/stroke_attribute.c @@ -38,12 +38,37 @@ struct private_stroke_attribute_t { */ linked_list_t *pools; + /** + * List of connection specific attributes, as attributes_t + */ + linked_list_t *attrs; + /** * rwlock to lock access to pools */ rwlock_t *lock; }; +/** + * Attributes assigned to a connection + */ +typedef struct { + /** name of the connection */ + char *name; + /** list of DNS attributes, as host_t */ + linked_list_t *dns; +} attributes_t; + +/** + * Destroy an attributes_t entry + */ +static void attributes_destroy(attributes_t *this) +{ + this->dns->destroy_offset(this->dns, offsetof(host_t, destroy)); + free(this->name); + free(this); +} + /** * find a pool by name */ @@ -66,8 +91,8 @@ static mem_pool_t *find_pool(private_stroke_attribute_t *this, char *name) } METHOD(attribute_provider_t, acquire_address, host_t*, - private_stroke_attribute_t *this, char *name, identification_t *id, - host_t *requested) + private_stroke_attribute_t *this, char *name, identification_t *id, + host_t *requested) { mem_pool_t *pool; host_t *addr = NULL; @@ -82,8 +107,8 @@ METHOD(attribute_provider_t, acquire_address, host_t*, } METHOD(attribute_provider_t, release_address, bool, - private_stroke_attribute_t *this, char *name, host_t *address, - identification_t *id) + private_stroke_attribute_t *this, char *name, host_t *address, + identification_t *id) { mem_pool_t *pool; bool found = FALSE; @@ -97,8 +122,64 @@ METHOD(attribute_provider_t, release_address, bool, return found; } +/** + * Filter function to convert host to DNS configuration attributes + */ +static bool attr_filter(void *lock, host_t **in, + configuration_attribute_type_t *type, + void *dummy, chunk_t *data) +{ + host_t *host = *in; + + switch (host->get_family(host)) + { + case AF_INET: + *type = INTERNAL_IP4_DNS; + break; + case AF_INET6: + *type = INTERNAL_IP6_DNS; + break; + default: + return FALSE; + } + *data = host->get_address(host); + return TRUE; +} + +METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, + private_stroke_attribute_t *this, char *pool, identification_t *id, + host_t *vip) +{ + ike_sa_t *ike_sa; + peer_cfg_t *peer_cfg; + enumerator_t *enumerator; + attributes_t *attr; + + ike_sa = charon->bus->get_sa(charon->bus); + if (ike_sa) + { + peer_cfg = ike_sa->get_peer_cfg(ike_sa); + this->lock->read_lock(this->lock); + enumerator = this->attrs->create_enumerator(this->attrs); + while (enumerator->enumerate(enumerator, &attr)) + { + if (streq(attr->name, peer_cfg->get_name(peer_cfg))) + { + enumerator->destroy(enumerator); + return enumerator_create_filter( + attr->dns->create_enumerator(attr->dns), + (void*)attr_filter, this->lock, + (void*)this->lock->unlock); + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + } + return enumerator_create_empty(); +} + METHOD(stroke_attribute_t, add_pool, void, - private_stroke_attribute_t *this, stroke_msg_t *msg) + private_stroke_attribute_t *this, stroke_msg_t *msg) { if (msg->add_conn.other.sourceip_mask) { @@ -127,12 +208,49 @@ METHOD(stroke_attribute_t, add_pool, void, this->pools->insert_last(this->pools, pool); this->lock->unlock(this->lock); } + + if (msg->add_conn.other.dns) + { + enumerator_t *enumerator; + attributes_t *attr = NULL; + host_t *host; + char *token; + + enumerator = enumerator_create_token(msg->add_conn.other.dns, ",", " "); + while (enumerator->enumerate(enumerator, &token)) + { + host = host_create_from_string(token, 0); + if (host) + { + if (!attr) + { + INIT(attr, + .name = strdup(msg->add_conn.name), + .dns = linked_list_create(), + ); + } + attr->dns->insert_last(attr->dns, host); + } + else + { + DBG1(DBG_CFG, "ignoring invalid DNS address '%s'", token); + } + } + enumerator->destroy(enumerator); + if (attr) + { + this->lock->write_lock(this->lock); + this->attrs->insert_last(this->attrs, attr); + this->lock->unlock(this->lock); + } + } } METHOD(stroke_attribute_t, del_pool, void, - private_stroke_attribute_t *this, stroke_msg_t *msg) + private_stroke_attribute_t *this, stroke_msg_t *msg) { enumerator_t *enumerator; + attributes_t *attr; mem_pool_t *pool; this->lock->write_lock(this->lock); @@ -147,6 +265,19 @@ METHOD(stroke_attribute_t, del_pool, void, } } enumerator->destroy(enumerator); + + enumerator = this->attrs->create_enumerator(this->attrs); + while (enumerator->enumerate(enumerator, &attr)) + { + if (streq(msg->del_conn.name, attr->name)) + { + this->attrs->remove_at(this->attrs, enumerator); + attributes_destroy(attr); + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); } @@ -166,7 +297,7 @@ static bool pool_filter(void *lock, mem_pool_t **poolp, const char **name, } METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*, - private_stroke_attribute_t *this) + private_stroke_attribute_t *this) { this->lock->read_lock(this->lock); return enumerator_create_filter(this->pools->create_enumerator(this->pools), @@ -175,7 +306,7 @@ METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*, } METHOD(stroke_attribute_t, create_lease_enumerator, enumerator_t*, - private_stroke_attribute_t *this, char *name) + private_stroke_attribute_t *this, char *name) { mem_pool_t *pool; this->lock->read_lock(this->lock); @@ -190,10 +321,11 @@ METHOD(stroke_attribute_t, create_lease_enumerator, enumerator_t*, } METHOD(stroke_attribute_t, destroy, void, - private_stroke_attribute_t *this) + private_stroke_attribute_t *this) { this->lock->destroy(this->lock); this->pools->destroy_offset(this->pools, offsetof(mem_pool_t, destroy)); + this->attrs->destroy_function(this->attrs, (void*)attributes_destroy); free(this); } @@ -209,7 +341,7 @@ stroke_attribute_t *stroke_attribute_create() .provider = { .acquire_address = _acquire_address, .release_address = _release_address, - .create_attribute_enumerator = enumerator_create_empty, + .create_attribute_enumerator = _create_attribute_enumerator, }, .add_pool = _add_pool, .del_pool = _del_pool, @@ -218,6 +350,7 @@ stroke_attribute_t *stroke_attribute_create() .destroy = _destroy, }, .pools = linked_list_create(), + .attrs = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), ); -- cgit v1.2.3 From 96c2b3cf89aa1825d70c51ddb3d800ed4720d6c0 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Mon, 27 Aug 2012 11:19:46 +0200 Subject: Support multiple addresses/pools in left/rightsourceip --- src/libcharon/plugins/stroke/stroke_attribute.c | 81 ++++++++++++++----------- 1 file changed, 44 insertions(+), 37 deletions(-) (limited to 'src/libcharon/plugins/stroke/stroke_attribute.c') diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c index aa3b1d20c..ebae6fcf1 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.c +++ b/src/libcharon/plugins/stroke/stroke_attribute.c @@ -17,7 +17,6 @@ #include "stroke_attribute.h" #include -#include #include #include @@ -96,6 +95,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*, { mem_pool_t *pool; host_t *addr = NULL; + this->lock->read_lock(this->lock); pool = find_pool(this, name); if (pool) @@ -112,6 +112,7 @@ METHOD(attribute_provider_t, release_address, bool, { mem_pool_t *pool; bool found = FALSE; + this->lock->read_lock(this->lock); pool = find_pool(this, name); if (pool) @@ -179,36 +180,48 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, } METHOD(stroke_attribute_t, add_pool, void, - private_stroke_attribute_t *this, stroke_msg_t *msg) + private_stroke_attribute_t *this, mem_pool_t *pool) { - if (msg->add_conn.other.sourceip_mask) - { - mem_pool_t *pool; - host_t *base = NULL; - u_int32_t bits = 0; + enumerator_t *enumerator; + mem_pool_t *current; + host_t *base; + int size; - /* if %config, add an empty pool, otherwise */ - if (msg->add_conn.other.sourceip) + base = pool->get_base(pool); + size = pool->get_size(pool); + + this->lock->write_lock(this->lock); + + enumerator = this->pools->create_enumerator(this->pools); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (base && current->get_base(current) && + base->ip_equals(base, current->get_base(current)) && + size == current->get_size(current)) { - DBG1(DBG_CFG, "adding virtual IP address pool '%s': %s/%d", - msg->add_conn.name, msg->add_conn.other.sourceip, - msg->add_conn.other.sourceip_mask); - base = host_create_from_string(msg->add_conn.other.sourceip, 0); - if (!base) - { - DBG1(DBG_CFG, "virtual IP address invalid, discarded"); - return; - } - bits = msg->add_conn.other.sourceip_mask; + pool->destroy(pool); + pool = NULL; + DBG1(DBG_CFG, "reusing virtual IP address pool %H/%d", base, size); + break; } - pool = mem_pool_create(msg->add_conn.name, base, bits); - DESTROY_IF(base); + } + enumerator->destroy(enumerator); - this->lock->write_lock(this->lock); + if (pool) + { + if (base) + { + DBG1(DBG_CFG, "adding virtual IP address pool %H/%d", base, size); + } this->pools->insert_last(this->pools, pool); - this->lock->unlock(this->lock); } + this->lock->unlock(this->lock); +} + +METHOD(stroke_attribute_t, add_dns, void, + private_stroke_attribute_t *this, stroke_msg_t *msg) +{ if (msg->add_conn.other.dns) { enumerator_t *enumerator; @@ -246,25 +259,13 @@ METHOD(stroke_attribute_t, add_pool, void, } } -METHOD(stroke_attribute_t, del_pool, void, +METHOD(stroke_attribute_t, del_dns, void, private_stroke_attribute_t *this, stroke_msg_t *msg) { enumerator_t *enumerator; attributes_t *attr; - mem_pool_t *pool; this->lock->write_lock(this->lock); - enumerator = this->pools->create_enumerator(this->pools); - while (enumerator->enumerate(enumerator, &pool)) - { - if (streq(msg->del_conn.name, pool->get_name(pool))) - { - this->pools->remove_at(this->pools, enumerator); - pool->destroy(pool); - break; - } - } - enumerator->destroy(enumerator); enumerator = this->attrs->create_enumerator(this->attrs); while (enumerator->enumerate(enumerator, &attr)) @@ -289,6 +290,11 @@ static bool pool_filter(void *lock, mem_pool_t **poolp, const char **name, void *d3, u_int *offline) { mem_pool_t *pool = *poolp; + + if (pool->get_size(pool) == 0) + { + return FALSE; + } *name = pool->get_name(pool); *size = pool->get_size(pool); *online = pool->get_online(pool); @@ -344,7 +350,8 @@ stroke_attribute_t *stroke_attribute_create() .create_attribute_enumerator = _create_attribute_enumerator, }, .add_pool = _add_pool, - .del_pool = _del_pool, + .add_dns = _add_dns, + .del_dns = _del_dns, .create_pool_enumerator = _create_pool_enumerator, .create_lease_enumerator = _create_lease_enumerator, .destroy = _destroy, -- cgit v1.2.3 From feb8550401c85218523c007f0d52a1c9bf006342 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Mon, 27 Aug 2012 14:09:47 +0200 Subject: Pass a list instead of a single virtual IP to attribute enumerators --- src/libcharon/plugins/stroke/stroke_attribute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libcharon/plugins/stroke/stroke_attribute.c') diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c index ebae6fcf1..cec6334ed 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.c +++ b/src/libcharon/plugins/stroke/stroke_attribute.c @@ -149,7 +149,7 @@ static bool attr_filter(void *lock, host_t **in, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, private_stroke_attribute_t *this, char *pool, identification_t *id, - host_t *vip) + linked_list_t *vips) { ike_sa_t *ike_sa; peer_cfg_t *peer_cfg; -- cgit v1.2.3 From d55fe264d1dd33a2751aa75a6f814e153f6354d4 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Mon, 27 Aug 2012 14:48:41 +0200 Subject: Pass all configured pool names to attribute provider enumerator --- src/libcharon/plugins/stroke/stroke_attribute.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libcharon/plugins/stroke/stroke_attribute.c') diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c index cec6334ed..3e012230a 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.c +++ b/src/libcharon/plugins/stroke/stroke_attribute.c @@ -148,8 +148,8 @@ static bool attr_filter(void *lock, host_t **in, } METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, - private_stroke_attribute_t *this, char *pool, identification_t *id, - linked_list_t *vips) + private_stroke_attribute_t *this, linked_list_t *pools, + identification_t *id, linked_list_t *vips) { ike_sa_t *ike_sa; peer_cfg_t *peer_cfg; -- cgit v1.2.3