diff --git a/configure.in b/configure.in index 2c7851069..a24a6ebe2 100644 --- a/configure.in +++ b/configure.in @@ -748,11 +748,12 @@ if test x$gmp = xtrue; then fi if test x$attr = xtrue; then libhydra_plugins=${libhydra_plugins}" attr" - pluto_plugins=${pluto_plugins}" attr" fi if test x$attr_sql = xtrue -o x$sql = xtrue; then libhydra_plugins=${libhydra_plugins}" attr-sql" - pluto_plugins=${pluto_plugins}" attr-sql" +fi +if test x$resolve = xtrue; then + libhydra_plugins=${libhydra_plugins}" resolve" fi AC_SUBST(libstrongswan_plugins) @@ -912,6 +913,7 @@ AC_OUTPUT( src/libhydra/Makefile src/libhydra/plugins/attr/Makefile src/libhydra/plugins/attr_sql/Makefile + src/libhydra/plugins/resolve/Makefile src/libfreeswan/Makefile src/libsimaka/Makefile src/pluto/Makefile @@ -948,7 +950,6 @@ AC_OUTPUT( src/libcharon/plugins/stroke/Makefile src/libcharon/plugins/updown/Makefile src/libcharon/plugins/dhcp/Makefile - src/libcharon/plugins/resolve/Makefile src/libcharon/plugins/unit_tester/Makefile src/libcharon/plugins/load_tester/Makefile src/stroke/Makefile diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index 0eaccf7a0..baf568c52 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -374,14 +374,6 @@ if MONOLITHIC endif endif -if USE_RESOLVE - SUBDIRS += plugins/resolve - PLUGINS += resolve -if MONOLITHIC - libcharon_la_LIBADD += plugins/resolve/libstrongswan-resolve.la -endif -endif - if USE_ANDROID SUBDIRS += plugins/android PLUGINS += android diff --git a/src/libhydra/Makefile.am b/src/libhydra/Makefile.am index 601a56e38..4e5c55d3f 100644 --- a/src/libhydra/Makefile.am +++ b/src/libhydra/Makefile.am @@ -40,3 +40,10 @@ if MONOLITHIC endif endif +if USE_RESOLVE + SUBDIRS += plugins/resolve +if MONOLITHIC + libhydra_la_LIBADD += plugins/resolve/libstrongswan-resolve.la +endif +endif + diff --git a/src/libcharon/plugins/resolve/Makefile.am b/src/libhydra/plugins/resolve/Makefile.am similarity index 100% rename from src/libcharon/plugins/resolve/Makefile.am rename to src/libhydra/plugins/resolve/Makefile.am diff --git a/src/libcharon/plugins/resolve/resolve_handler.c b/src/libhydra/plugins/resolve/resolve_handler.c similarity index 98% rename from src/libcharon/plugins/resolve/resolve_handler.c rename to src/libhydra/plugins/resolve/resolve_handler.c index 714c751a6..cdc639038 100644 --- a/src/libcharon/plugins/resolve/resolve_handler.c +++ b/src/libhydra/plugins/resolve/resolve_handler.c @@ -17,7 +17,8 @@ #include -#include +#include +#include #include typedef struct private_resolve_handler_t private_resolve_handler_t; @@ -244,7 +245,7 @@ resolve_handler_t *resolve_handler_create() this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); this->file = lib->settings->get_str(lib->settings, - "charon.plugins.resolve.file", RESOLV_CONF); + "%s.plugins.resolve.file", RESOLV_CONF, hydra->daemon); return &this->public; } diff --git a/src/libcharon/plugins/resolve/resolve_handler.h b/src/libhydra/plugins/resolve/resolve_handler.h similarity index 100% rename from src/libcharon/plugins/resolve/resolve_handler.h rename to src/libhydra/plugins/resolve/resolve_handler.h diff --git a/src/libcharon/plugins/resolve/resolve_plugin.c b/src/libhydra/plugins/resolve/resolve_plugin.c similarity index 100% rename from src/libcharon/plugins/resolve/resolve_plugin.c rename to src/libhydra/plugins/resolve/resolve_plugin.c diff --git a/src/libcharon/plugins/resolve/resolve_plugin.h b/src/libhydra/plugins/resolve/resolve_plugin.h similarity index 100% rename from src/libcharon/plugins/resolve/resolve_plugin.h rename to src/libhydra/plugins/resolve/resolve_plugin.h diff --git a/src/libhydra/plugins/resolve_handler.c b/src/libhydra/plugins/resolve_handler.c new file mode 100644 index 000000000..cdc639038 --- /dev/null +++ b/src/libhydra/plugins/resolve_handler.c @@ -0,0 +1,252 @@ +/* + * 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 . + * + * 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 "resolve_handler.h" + +#include + +#include +#include +#include + +typedef struct private_resolve_handler_t private_resolve_handler_t; + +/** + * Private data of an resolve_handler_t object. + */ +struct private_resolve_handler_t { + + /** + * Public resolve_handler_t interface. + */ + resolve_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_resolve_handler_t *this, identification_t *server, + configuration_attribute_type_t type, chunk_t data) +{ + FILE *in, *out; + char buf[1024]; + host_t *addr; + size_t len; + bool handled = FALSE; + + switch (type) + { + case INTERNAL_IP4_DNS: + addr = host_create_from_chunk(AF_INET, data, 0); + break; + case INTERNAL_IP6_DNS: + addr = host_create_from_chunk(AF_INET6, data, 0); + break; + default: + return FALSE; + } + + if (!addr || addr->is_anyaddr(addr)) + { + DESTROY_IF(addr); + 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) + { + fprintf(out, "nameserver %H # by strongSwan, from %Y\n", addr, server); + DBG1(DBG_IKE, "installing DNS server %H to %s", addr, this->file); + 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(out); + } + if (in) + { + fclose(in); + } + this->mutex->unlock(this->mutex); + addr->destroy(addr); + + if (!handled) + { + DBG1(DBG_IKE, "adding DNS server failed", this->file); + } + return handled; +} + +/** + * Implementation of attribute_handler_t.release + */ +static void release(private_resolve_handler_t *this, identification_t *server, + 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 %Y\n", + addr, server); + + /* 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); +} + +/** + * Attribute enumerator implementation + */ +typedef struct { + /** implements enumerator_t interface */ + enumerator_t public; + /** virtual IP we are requesting */ + host_t *vip; +} attribute_enumerator_t; + +/** + * Implementation of create_attribute_enumerator().enumerate() + */ +static bool attribute_enumerate(attribute_enumerator_t *this, + configuration_attribute_type_t *type, chunk_t *data) +{ + switch (this->vip->get_family(this->vip)) + { + case AF_INET: + *type = INTERNAL_IP4_DNS; + break; + case AF_INET6: + *type = INTERNAL_IP6_DNS; + break; + default: + return FALSE; + } + *data = chunk_empty; + /* enumerate only once */ + this->public.enumerate = (void*)return_false; + return TRUE; +} + +/** + * Implementation of attribute_handler_t.create_attribute_enumerator + */ +static enumerator_t* create_attribute_enumerator(private_resolve_handler_t *this, + identification_t *server, host_t *vip) +{ + if (vip) + { + attribute_enumerator_t *enumerator; + + enumerator = malloc_thing(attribute_enumerator_t); + enumerator->public.enumerate = (void*)attribute_enumerate; + enumerator->public.destroy = (void*)free; + enumerator->vip = vip; + + return &enumerator->public; + } + return enumerator_create_empty(); +} + +/** + * Implementation of resolve_handler_t.destroy. + */ +static void destroy(private_resolve_handler_t *this) +{ + this->mutex->destroy(this->mutex); + free(this); +} + +/** + * See header + */ +resolve_handler_t *resolve_handler_create() +{ + private_resolve_handler_t *this = malloc_thing(private_resolve_handler_t); + + this->public.handler.handle = (bool(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))handle; + this->public.handler.release = (void(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))release; + this->public.handler.create_attribute_enumerator = (enumerator_t*(*)(attribute_handler_t*, identification_t *server, host_t *vip))create_attribute_enumerator; + this->public.destroy = (void(*)(resolve_handler_t*))destroy; + + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->file = lib->settings->get_str(lib->settings, + "%s.plugins.resolve.file", RESOLV_CONF, hydra->daemon); + + return &this->public; +} + diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am index a264e642e..b65c80cdb 100644 --- a/src/pluto/Makefile.am +++ b/src/pluto/Makefile.am @@ -72,7 +72,7 @@ AM_CFLAGS = \ -DIPSEC_CONFDIR=\"${sysconfdir}\" \ -DIPSEC_PIDDIR=\"${piddir}\" \ -DSHARED_SECRETS_FILE=\"${sysconfdir}/ipsec.secrets\" \ --DPLUGINS=\""${pluto_plugins}\"" \ +-DPLUGINS=\""${pluto_plugins} ${libhydra_plugins}\"" \ -DPKCS11_DEFAULT_LIB=\"${default_pkcs11}\" \ -DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES \ -DPLUTO -DKLIPS -DDEBUG