diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2015-04-11 22:03:59 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2015-04-11 22:30:17 +0200 |
commit | 8404fb0212f9fb77bc53b23004b829b488430700 (patch) | |
tree | 23876c7540d138f58a6a7d90793ccf9004f6afd2 /src/libhydra/plugins/resolve/resolve_handler.c | |
parent | 1b7c683a32c62b6e08ad7bf5af39b9f4edd634f3 (diff) | |
download | vyos-strongswan-8404fb0212f9fb77bc53b23004b829b488430700.tar.gz vyos-strongswan-8404fb0212f9fb77bc53b23004b829b488430700.zip |
Imported Upstream version 5.3.0
Diffstat (limited to 'src/libhydra/plugins/resolve/resolve_handler.c')
-rw-r--r-- | src/libhydra/plugins/resolve/resolve_handler.c | 377 |
1 files changed, 0 insertions, 377 deletions
diff --git a/src/libhydra/plugins/resolve/resolve_handler.c b/src/libhydra/plugins/resolve/resolve_handler.c deleted file mode 100644 index 069466ab5..000000000 --- a/src/libhydra/plugins/resolve/resolve_handler.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2012 Tobias Brunner - * 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. - */ - -#include "resolve_handler.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <hydra.h> -#include <utils/debug.h> -#include <threading/mutex.h> - -/* path to resolvconf executable */ -#define RESOLVCONF_EXEC "/sbin/resolvconf" - -/* default prefix used for resolvconf interfaces (should have high prio) */ -#define RESOLVCONF_PREFIX "lo.inet.ipsec." - -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; - - /** - * use resolvconf instead of writing directly to resolv.conf - */ - bool use_resolvconf; - - /** - * prefix to be used for interface names sent to resolvconf - */ - char *iface_prefix; - - /** - * Mutex to access file exclusively - */ - mutex_t *mutex; -}; - -/** - * Writes the given nameserver to resolv.conf - */ -static bool write_nameserver(private_resolve_handler_t *this, - identification_t *server, host_t *addr) -{ - FILE *in, *out; - char buf[1024]; - size_t len; - bool handled = FALSE; - - 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); - } - return handled; -} - -/** - * Removes the given nameserver from resolv.conf - */ -static void remove_nameserver(private_resolve_handler_t *this, - identification_t *server, host_t *addr) -{ - FILE *in, *out; - char line[1024], matcher[512]; - - 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) - { - snprintf(matcher, sizeof(matcher), - "nameserver %H # by strongSwan, from %Y\n", - addr, server); - - /* copy all, but matching line */ - while (fgets(line, sizeof(line), in)) - { - if (strpfx(line, matcher)) - { - DBG1(DBG_IKE, "removing DNS server %H from %s", - addr, this->file); - } - else - { - fputs(line, out); - } - } - fclose(out); - } - fclose(in); - } -} - -/** - * Add or remove the given nameserver by invoking resolvconf. - */ -static bool invoke_resolvconf(private_resolve_handler_t *this, - identification_t *server, host_t *addr, - bool install) -{ - char cmd[128]; - bool success = TRUE; - - /* we use the nameserver's IP address as part of the interface name to - * make them unique */ - if (snprintf(cmd, sizeof(cmd), "%s %s %s%H", RESOLVCONF_EXEC, - install ? "-a" : "-d", this->iface_prefix, addr) >= sizeof(cmd)) - { - return FALSE; - } - - if (install) - { - FILE *out; - - out = popen(cmd, "w"); - if (!out) - { - return FALSE; - } - DBG1(DBG_IKE, "installing DNS server %H via resolvconf", addr); - fprintf(out, "nameserver %H\n", addr); - success = !ferror(out); - if (pclose(out)) - { - return FALSE; - } - } - else - { - ignore_result(system(cmd)); - } - return success; -} - -METHOD(attribute_handler_t, handle, bool, - private_resolve_handler_t *this, identification_t *server, - configuration_attribute_type_t type, chunk_t data) -{ - host_t *addr; - bool handled; - - 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); - if (this->use_resolvconf) - { - handled = invoke_resolvconf(this, server, addr, TRUE); - } - else - { - handled = write_nameserver(this, server, addr); - } - this->mutex->unlock(this->mutex); - addr->destroy(addr); - - if (!handled) - { - DBG1(DBG_IKE, "adding DNS server failed"); - } - return handled; -} - -METHOD(attribute_handler_t, release, void, - private_resolve_handler_t *this, identification_t *server, - configuration_attribute_type_t type, chunk_t data) -{ - 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; - } - addr = host_create_from_chunk(family, data, 0); - - this->mutex->lock(this->mutex); - if (this->use_resolvconf) - { - invoke_resolvconf(this, server, addr, FALSE); - } - else - { - remove_nameserver(this, server, addr); - } - this->mutex->unlock(this->mutex); - - addr->destroy(addr); -} - -/** - * Attribute enumerator implementation - */ -typedef struct { - /** implements enumerator_t interface */ - enumerator_t public; - /** request IPv4 DNS? */ - bool v4; - /** request IPv6 DNS? */ - bool v6; -} attribute_enumerator_t; - -static bool attribute_enumerate(attribute_enumerator_t *this, - configuration_attribute_type_t *type, - chunk_t *data) -{ - if (this->v4) - { - *type = INTERNAL_IP4_DNS; - *data = chunk_empty; - this->v4 = FALSE; - return TRUE; - } - if (this->v6) - { - *type = INTERNAL_IP6_DNS; - *data = chunk_empty; - this->v6 = FALSE; - return TRUE; - } - return FALSE; -} - -/** - * Check if a list has a host of given family - */ -static bool has_host_family(linked_list_t *list, int family) -{ - enumerator_t *enumerator; - host_t *host; - bool found = FALSE; - - enumerator = list->create_enumerator(list); - while (enumerator->enumerate(enumerator, &host)) - { - if (host->get_family(host) == family) - { - found = TRUE; - break; - } - } - enumerator->destroy(enumerator); - - return found; -} - -METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, - private_resolve_handler_t *this, identification_t *server, - linked_list_t *vips) -{ - attribute_enumerator_t *enumerator; - - INIT(enumerator, - .public = { - .enumerate = (void*)attribute_enumerate, - .destroy = (void*)free, - }, - .v4 = has_host_family(vips, AF_INET), - .v6 = has_host_family(vips, AF_INET6), - ); - return &enumerator->public; -} - -METHOD(resolve_handler_t, destroy, void, - 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; - struct stat st; - - INIT(this, - .public = { - .handler = { - .handle = _handle, - .release = _release, - .create_attribute_enumerator = _create_attribute_enumerator, - }, - .destroy = _destroy, - }, - .mutex = mutex_create(MUTEX_TYPE_DEFAULT), - .file = lib->settings->get_str(lib->settings, "%s.plugins.resolve.file", - RESOLV_CONF, lib->ns), - ); - - if (stat(RESOLVCONF_EXEC, &st) == 0) - { - this->use_resolvconf = TRUE; - this->iface_prefix = lib->settings->get_str(lib->settings, - "%s.plugins.resolve.resolvconf.iface_prefix", - RESOLVCONF_PREFIX, lib->ns); - } - - return &this->public; -} - |