diff options
author | Martin Willi <martin@revosec.ch> | 2012-07-31 11:09:19 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2012-08-21 09:38:01 +0200 |
commit | 63e460542c2cc9e1fb7707db34f483362f6a6c13 (patch) | |
tree | dad49c956a537c3ff374b6de42e385b5161322ac | |
parent | 9937ca069ad4fb26aeaf1b5c72820afdcd93ae16 (diff) | |
download | strongswan-63e460542c2cc9e1fb7707db34f483362f6a6c13.tar.bz2 strongswan-63e460542c2cc9e1fb7707db34f483362f6a6c13.tar.xz |
Add a stroke attribute_handler requesting DNS servers given with leftdns
-rw-r--r-- | src/libcharon/plugins/stroke/Makefile.am | 1 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_handler.c | 230 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_handler.h | 64 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_socket.c | 12 |
4 files changed, 307 insertions, 0 deletions
diff --git a/src/libcharon/plugins/stroke/Makefile.am b/src/libcharon/plugins/stroke/Makefile.am index e561224e9..cebcd984f 100644 --- a/src/libcharon/plugins/stroke/Makefile.am +++ b/src/libcharon/plugins/stroke/Makefile.am @@ -21,6 +21,7 @@ libstrongswan_stroke_la_SOURCES = \ stroke_cred.h stroke_cred.c \ stroke_ca.h stroke_ca.c \ stroke_attribute.h stroke_attribute.c \ + stroke_handler.h stroke_handler.c \ stroke_list.h stroke_list.c libstrongswan_stroke_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/stroke/stroke_handler.c b/src/libcharon/plugins/stroke/stroke_handler.c new file mode 100644 index 000000000..e15daf4a4 --- /dev/null +++ b/src/libcharon/plugins/stroke/stroke_handler.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "stroke_handler.h" + +#include <daemon.h> +#include <utils/linked_list.h> +#include <threading/rwlock.h> + +typedef struct private_stroke_handler_t private_stroke_handler_t; + +/** + * Private data of an stroke_handler_t object. + */ +struct private_stroke_handler_t { + + /** + * Public stroke_handler_t interface. + */ + stroke_handler_t public; + + /** + * 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); +} + +/** + * 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; + } + if (host->is_anyaddr(host)) + { + *data = chunk_empty; + } + else + { + *data = host->get_address(host); + } + return TRUE; +} + +METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, + private_stroke_handler_t *this, identification_t *server, 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_handler_t, add_attributes, void, + private_stroke_handler_t *this, stroke_msg_t *msg) +{ + if (msg->add_conn.me.dns) + { + enumerator_t *enumerator; + attributes_t *attr = NULL; + host_t *host; + char *token; + + enumerator = enumerator_create_token(msg->add_conn.me.dns, ",", " "); + while (enumerator->enumerate(enumerator, &token)) + { + if (streq(token, "%config") || streq(token, "%config4")) + { + host = host_create_any(AF_INET); + } + else if (streq(token, "%config6")) + { + host = host_create_any(AF_INET6); + } + else + { + 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_handler_t, del_attributes, void, + private_stroke_handler_t *this, stroke_msg_t *msg) +{ + enumerator_t *enumerator; + attributes_t *attr; + + this->lock->write_lock(this->lock); + 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); +} + +METHOD(stroke_handler_t, destroy, void, + private_stroke_handler_t *this) +{ + this->lock->destroy(this->lock); + this->attrs->destroy_function(this->attrs, (void*)attributes_destroy); + free(this); +} + +/** + * See header + */ +stroke_handler_t *stroke_handler_create() +{ + private_stroke_handler_t *this; + + INIT(this, + .public = { + .handler = { + .handle = (void*)return_false, + .release = (void*)return_false, + .create_attribute_enumerator = _create_attribute_enumerator, + }, + .add_attributes = _add_attributes, + .del_attributes = _del_attributes, + .destroy = _destroy, + }, + .attrs = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/stroke/stroke_handler.h b/src/libcharon/plugins/stroke/stroke_handler.h new file mode 100644 index 000000000..ab76f80b0 --- /dev/null +++ b/src/libcharon/plugins/stroke/stroke_handler.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup stroke_handler stroke_handler + * @{ @ingroup stroke + */ + +#ifndef STROKE_HANDLER_H_ +#define STROKE_HANDLER_H_ + +#include <stroke_msg.h> +#include <attributes/attribute_handler.h> + +typedef struct stroke_handler_t stroke_handler_t; + +/** + * Handler requesting DNS attributes as defined with leftdns option. + */ +struct stroke_handler_t { + + /** + * Implements the attribute_handler_t interface + */ + attribute_handler_t handler; + + /** + * Add connection specific configuration attributes. + * + * @param msg stroke message + */ + void (*add_attributes)(stroke_handler_t *this, stroke_msg_t *msg); + + /** + * Remove connection specific configuration attributes. + * + * @param msg stroke message + */ + void (*del_attributes)(stroke_handler_t *this, stroke_msg_t *msg); + + /** + * Destroy a stroke_handler_t. + */ + void (*destroy)(stroke_handler_t *this); +}; + +/** + * Create a stroke_handler instance. + */ +stroke_handler_t *stroke_handler_create(); + +#endif /** STROKE_HANDLER_H_ @}*/ diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 427a5e83f..df43e168d 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -37,6 +37,7 @@ #include "stroke_cred.h" #include "stroke_ca.h" #include "stroke_attribute.h" +#include "stroke_handler.h" #include "stroke_list.h" /** @@ -99,6 +100,11 @@ struct private_stroke_socket_t { stroke_attribute_t *attribute; /** + * attribute handler (requests only) + */ + stroke_handler_t *handler; + + /** * controller to control daemon */ stroke_control_t *control; @@ -238,6 +244,7 @@ static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg) this->config->add(this->config, msg); this->attribute->add_pool(this->attribute, msg); + this->handler->add_attributes(this->handler, msg); } /** @@ -250,6 +257,7 @@ static void stroke_del_conn(private_stroke_socket_t *this, stroke_msg_t *msg) this->config->del(this->config, msg); this->attribute->del_pool(this->attribute, msg); + this->handler->del_attributes(this->handler, msg); } /** @@ -789,10 +797,12 @@ METHOD(stroke_socket_t, destroy, void, lib->credmgr->remove_set(lib->credmgr, &this->cred->set); charon->backends->remove_backend(charon->backends, &this->config->backend); hydra->attributes->remove_provider(hydra->attributes, &this->attribute->provider); + hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler); this->cred->destroy(this->cred); this->ca->destroy(this->ca); this->config->destroy(this->config); this->attribute->destroy(this->attribute); + this->handler->destroy(this->handler); this->control->destroy(this->control); this->list->destroy(this->list); free(this); @@ -819,6 +829,7 @@ stroke_socket_t *stroke_socket_create() this->cred = stroke_cred_create(); this->attribute = stroke_attribute_create(); + this->handler = stroke_handler_create(); this->ca = stroke_ca_create(this->cred); this->config = stroke_config_create(this->ca, this->cred); this->control = stroke_control_create(); @@ -835,6 +846,7 @@ stroke_socket_t *stroke_socket_create() lib->credmgr->add_set(lib->credmgr, &this->cred->set); charon->backends->add_backend(charon->backends, &this->config->backend); hydra->attributes->add_provider(hydra->attributes, &this->attribute->provider); + hydra->attributes->add_handler(hydra->attributes, &this->handler->handler); lib->processor->queue_job(lib->processor, (job_t*)callback_job_create_with_prio((callback_job_cb_t)receive, this, |