diff options
author | Martin Willi <martin@strongswan.org> | 2009-04-24 14:13:52 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2009-04-24 14:13:52 +0000 |
commit | 7f56b494616fca022b157eff393a0bfa19cf5e2b (patch) | |
tree | e2fd93668cbfab29b25fcf8a5498bc0bda4f73c6 /src/charon/plugins/resolv_conf | |
parent | da17b0169ab4d6eee644b7a612ecbd58be7ae4a7 (diff) | |
download | strongswan-7f56b494616fca022b157eff393a0bfa19cf5e2b.tar.bz2 strongswan-7f56b494616fca022b157eff393a0bfa19cf5e2b.tar.xz |
attribute_manager supports attribute_handler's to handle configuration attributes via plugins
moved resolv.conf editing to a separate plugin (resolv_conf)
extended attribute_provider interface to hand out arbitrary attributes
moved strongswan.conf based dns/nbns configuration to a plugin (attr)
Diffstat (limited to 'src/charon/plugins/resolv_conf')
-rw-r--r-- | src/charon/plugins/resolv_conf/Makefile.am | 13 | ||||
-rw-r--r-- | src/charon/plugins/resolv_conf/resolv_conf_handler.c | 194 | ||||
-rw-r--r-- | src/charon/plugins/resolv_conf/resolv_conf_handler.h | 51 | ||||
-rw-r--r-- | src/charon/plugins/resolv_conf/resolv_conf_plugin.c | 66 | ||||
-rw-r--r-- | src/charon/plugins/resolv_conf/resolv_conf_plugin.h | 49 |
5 files changed, 373 insertions, 0 deletions
diff --git a/src/charon/plugins/resolv_conf/Makefile.am b/src/charon/plugins/resolv_conf/Makefile.am new file mode 100644 index 000000000..917964f93 --- /dev/null +++ b/src/charon/plugins/resolv_conf/Makefile.am @@ -0,0 +1,13 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon + +AM_CFLAGS = -rdynamic \ + -DRESOLV_CONF=\"${resolv_conf}\" + +plugin_LTLIBRARIES = libstrongswan-resolv-conf.la +libstrongswan_resolv_conf_la_SOURCES = \ + resolv_conf_plugin.h resolv_conf_plugin.c \ + resolv_conf_handler.h resolv_conf_handler.c +libstrongswan_resolv_conf_la_LDFLAGS = -module + + diff --git a/src/charon/plugins/resolv_conf/resolv_conf_handler.c b/src/charon/plugins/resolv_conf/resolv_conf_handler.c new file mode 100644 index 000000000..c76222f28 --- /dev/null +++ b/src/charon/plugins/resolv_conf/resolv_conf_handler.c @@ -0,0 +1,194 @@ +/* + * 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. + * + * $Id$ + */ + +#include "resolv_conf_handler.h" + +#include <unistd.h> + +#include <daemon.h> +#include <utils/mutex.h> + +typedef struct private_resolv_conf_handler_t private_resolv_conf_handler_t; + +/** + * Private data of an resolv_conf_handler_t object. + */ +struct private_resolv_conf_handler_t { + + /** + * Public resolv_conf_handler_t interface. + */ + resolv_conf_handler_t public; + + /** + * resolv.conf file to use + */ + char *file; + + /** + * Mutex to access file exclusively + */ + mutex_t *mutex; +}; + +/** + * Implementation of attribute_handler_t.handle + */ +static bool handle(private_resolv_conf_handler_t *this, ike_sa_t *ike_sa, + configuration_attribute_type_t type, chunk_t data) +{ + FILE *in, *out; + char buf[1024]; + host_t *addr; + int family; + size_t len; + bool handled = FALSE; + + switch (type) + { + case INTERNAL_IP4_DNS: + family = AF_INET; + break; + case INTERNAL_IP6_DNS: + family = AF_INET6; + break; + default: + return FALSE; + } + + this->mutex->lock(this->mutex); + + in = fopen(this->file, "r"); + /* allows us to stream from in to out */ + unlink(this->file); + out = fopen(this->file, "w"); + if (out) + { + addr = host_create_from_chunk(family, data, 0); + fprintf(out, "nameserver %H # by strongSwan, from %D\n", + addr, ike_sa->get_other_id(ike_sa)); + DBG1(DBG_IKE, "installing DNS server %H to %s", addr, this->file); + addr->destroy(addr); + handled = TRUE; + + /* copy rest of the file */ + if (in) + { + while ((len = fread(buf, 1, sizeof(buf), in))) + { + ignore_result(fwrite(buf, 1, len, out)); + } + fclose(in); + } + fclose(out); + } + + if (!handled) + { + DBG1(DBG_IKE, "adding DNS server failed", this->file); + } + this->mutex->unlock(this->mutex); + return handled; +} + +/** + * Implementation of attribute_handler_t.release + */ +static void release(private_resolv_conf_handler_t *this, ike_sa_t *ike_sa, + configuration_attribute_type_t type, chunk_t data) +{ + FILE *in, *out; + char line[1024], matcher[512], *pos; + host_t *addr; + int family; + + switch (type) + { + case INTERNAL_IP4_DNS: + family = AF_INET; + break; + case INTERNAL_IP6_DNS: + family = AF_INET6; + break; + default: + return; + } + + this->mutex->lock(this->mutex); + + in = fopen(this->file, "r"); + if (in) + { + /* allows us to stream from in to out */ + unlink(this->file); + out = fopen(this->file, "w"); + if (out) + { + addr = host_create_from_chunk(family, data, 0); + snprintf(matcher, sizeof(matcher), + "nameserver %H # by strongSwan, from %D\n", + addr, ike_sa->get_other_id(ike_sa)); + + /* copy all, but matching line */ + while ((pos = fgets(line, sizeof(line), in))) + { + if (strneq(line, matcher, strlen(matcher))) + { + DBG1(DBG_IKE, "removing DNS server %H from %s", + addr, this->file); + } + else + { + fputs(line, out); + } + } + addr->destroy(addr); + fclose(out); + } + fclose(in); + } + + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of resolv_conf_handler_t.destroy. + */ +static void destroy(private_resolv_conf_handler_t *this) +{ + this->mutex->destroy(this->mutex); + free(this); +} + +/** + * See header + */ +resolv_conf_handler_t *resolv_conf_handler_create() +{ + private_resolv_conf_handler_t *this = malloc_thing(private_resolv_conf_handler_t); + + this->public.handler.handle = (bool(*)(attribute_handler_t*, ike_sa_t*, configuration_attribute_type_t, chunk_t))handle; + this->public.handler.release = (void(*)(attribute_handler_t*, ike_sa_t*, configuration_attribute_type_t, chunk_t))release; + this->public.destroy = (void(*)(resolv_conf_handler_t*))destroy; + + this->mutex = mutex_create(MUTEX_DEFAULT); + this->file = lib->settings->get_str(lib->settings, + "charon.plugins.resolv-conf.file", RESOLV_CONF); + + return &this->public; +} + diff --git a/src/charon/plugins/resolv_conf/resolv_conf_handler.h b/src/charon/plugins/resolv_conf/resolv_conf_handler.h new file mode 100644 index 000000000..c5608b726 --- /dev/null +++ b/src/charon/plugins/resolv_conf/resolv_conf_handler.h @@ -0,0 +1,51 @@ +/* + * 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. + * + * $Id$ + */ + +/** + * @defgroup resolv_conf_handler resolv_conf_handler + * @{ @ingroup resolv_conf + */ + +#ifndef RESOLV_CONF_HANDLER_H_ +#define RESOLV_CONF_HANDLER_H_ + +#include <config/attributes/attribute_handler.h> + +typedef struct resolv_conf_handler_t resolv_conf_handler_t; + +/** + * Handle DNS configuration attributes by mangling a resolv.conf file. + */ +struct resolv_conf_handler_t { + + /** + * Implements the attribute_handler_t interface + */ + attribute_handler_t handler; + + /** + * Destroy a resolv_conf_handler_t. + */ + void (*destroy)(resolv_conf_handler_t *this); +}; + +/** + * Create a resolv_conf_handler instance. + */ +resolv_conf_handler_t *resolv_conf_handler_create(); + +#endif /* RESOLV_CONF_HANDLER_ @}*/ diff --git a/src/charon/plugins/resolv_conf/resolv_conf_plugin.c b/src/charon/plugins/resolv_conf/resolv_conf_plugin.c new file mode 100644 index 000000000..855f4dad4 --- /dev/null +++ b/src/charon/plugins/resolv_conf/resolv_conf_plugin.c @@ -0,0 +1,66 @@ +/* + * 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. + * + * $Id$ + */ + +#include "resolv_conf_plugin.h" +#include "resolv_conf_handler.h" + +#include <daemon.h> + +typedef struct private_resolv_conf_plugin_t private_resolv_conf_plugin_t; + +/** + * private data of resolv_conf plugin + */ +struct private_resolv_conf_plugin_t { + + /** + * implements plugin interface + */ + resolv_conf_plugin_t public; + + /** + * The registerd DNS attribute handler + */ + resolv_conf_handler_t *handler; +}; + +/** + * Implementation of plugin_t.destroy + */ +static void destroy(private_resolv_conf_plugin_t *this) +{ + charon->attributes->remove_handler(charon->attributes, + &this->handler->handler); + this->handler->destroy(this->handler); + free(this); +} + +/* + * see header file + */ +plugin_t *plugin_create() +{ + private_resolv_conf_plugin_t *this = malloc_thing(private_resolv_conf_plugin_t); + + this->public.plugin.destroy = (void(*)(plugin_t*))destroy; + + this->handler = resolv_conf_handler_create(); + charon->attributes->add_handler(charon->attributes, &this->handler->handler); + + return &this->public.plugin; +} + diff --git a/src/charon/plugins/resolv_conf/resolv_conf_plugin.h b/src/charon/plugins/resolv_conf/resolv_conf_plugin.h new file mode 100644 index 000000000..1a93bfcdf --- /dev/null +++ b/src/charon/plugins/resolv_conf/resolv_conf_plugin.h @@ -0,0 +1,49 @@ +/* + * 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. + * + * $Id$ + */ + +/** + * @defgroup resolv_conf resolv_conf + * @ingroup cplugins + * + * @defgroup resolv_conf_plugin resolv_conf_plugin + * @{ @ingroup resolv_conf + */ + +#ifndef RESOLV_CONF_PLUGIN_H_ +#define RESOLV_CONF_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct resolv_conf_plugin_t resolv_conf_plugin_t; + +/** + * Plugin that writes received DNS servers in a resolv.conf file. + */ +struct resolv_conf_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +/** + * Create a resolv_conf_plugin instance. + */ +plugin_t *plugin_create(); + +#endif /** RESOLV_CONF_PLUGIN_H_ @}*/ |