/*
 * Copyright (C) 2012-2016 Tobias Brunner
 * Copyright (C) 2009 Martin Willi
 * HSR 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 <utils/debug.h>
#include <utils/process.h>
#include <collections/array.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;

	/**
	 * Reference counting for DNS servers dns_server_t
	 */
	array_t *servers;
};

/**
 * Reference counting for DNS servers
 */
typedef struct {

	/**
	 * DNS server address
	 */
	host_t *server;

	/**
	 * Reference count
	 */
	u_int refcount;

} dns_server_t;

/**
 * Compare a server and a stored reference
 */
static int dns_server_find(const void *a, const void *b)
{
	host_t *server = (host_t*)a;
	dns_server_t *item = (dns_server_t*)b;
	return chunk_compare(server->get_address(server),
						 item->server->get_address(item->server));
}

/**
 * Sort references by DNS server
 */
static int dns_server_sort(const void *a, const void *b, void *user)
{
	const dns_server_t *da = a, *db = b;
	return chunk_compare(da->server->get_address(da->server),
						 db->server->get_address(db->server));
}

/**
 * Writes the given nameserver to resolv.conf
 */
static bool write_nameserver(private_resolve_handler_t *this, 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\n", addr);
		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, 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\n", addr);

			/* 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, host_t *addr,
							  bool install)
{
	process_t *process;
	FILE *shell;
	int in, out, retval;

	/* we use the nameserver's IP address as part of the interface name to
	 * make them unique */
	process = process_start_shell(NULL, install ? &in : NULL, &out, NULL,
							"2>&1 %s %s %s%H", RESOLVCONF_EXEC,
							install ? "-a" : "-d", this->iface_prefix, addr);

	if (!process)
	{
		return FALSE;
	}
	if (install)
	{
		shell = fdopen(in, "w");
		if (shell)
		{
			DBG1(DBG_IKE, "installing DNS server %H via resolvconf", addr);
			fprintf(shell, "nameserver %H\n", addr);
			fclose(shell);
		}
		else
		{
			close(in);
			close(out);
			process->wait(process, NULL);
			return FALSE;
		}
	}
	else
	{
		DBG1(DBG_IKE, "removing DNS server %H via resolvconf", addr);
	}
	shell = fdopen(out, "r");
	if (shell)
	{
		while (TRUE)
		{
			char resp[128], *e;

			if (fgets(resp, sizeof(resp), shell) == NULL)
			{
				if (ferror(shell))
				{
					DBG1(DBG_IKE, "error reading from resolvconf");
				}
				break;
			}
			else
			{
				e = resp + strlen(resp);
				if (e > resp && e[-1] == '\n')
				{
					e[-1] = '\0';
				}
				DBG1(DBG_IKE, "resolvconf: %s", resp);
			}
		}
		fclose(shell);
	}
	else
	{
		close(out);
	}
	if (!process->wait(process, &retval) || retval != EXIT_SUCCESS)
	{
		if (install)
		{	/* revert changes when installing fails */
			invoke_resolvconf(this, addr, FALSE);
			return FALSE;
		}
	}
	return TRUE;
}

METHOD(attribute_handler_t, handle, bool,
	private_resolve_handler_t *this, ike_sa_t *ike_sa,
	configuration_attribute_type_t type, chunk_t data)
{
	dns_server_t *found = NULL;
	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 (array_bsearch(this->servers, addr, dns_server_find, &found) == -1)
	{
		if (this->use_resolvconf)
		{
			handled = invoke_resolvconf(this, addr, TRUE);
		}
		else
		{
			handled = write_nameserver(this, addr);
		}
		if (handled)
		{
			INIT(found,
				.server = addr->clone(addr),
				.refcount = 1,
			);
			array_insert_create(&this->servers, ARRAY_TAIL, found);
			array_sort(this->servers, dns_server_sort, NULL);
		}
	}
	else
	{
		DBG1(DBG_IKE, "DNS server %H already installed, increasing refcount",
			 addr);
		found->refcount++;
		handled = TRUE;
	}
	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, ike_sa_t *ike_sa,
	configuration_attribute_type_t type, chunk_t data)
{
	dns_server_t *found = NULL;
	host_t *addr;
	int family, idx;

	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);
	idx = array_bsearch(this->servers, addr, dns_server_find, &found);
	if (idx != -1)
	{
		if (--found->refcount > 0)
		{
			DBG1(DBG_IKE, "DNS server %H still used, decreasing refcount",
				 addr);
		}
		else
		{
			if (this->use_resolvconf)
			{
				invoke_resolvconf(this, addr, FALSE);
			}
			else
			{
				remove_nameserver(this, addr);
			}
			array_remove(this->servers, idx, NULL);
			found->server->destroy(found->server);
			free(found);
		}
	}
	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;

METHOD(enumerator_t, attribute_enumerate, bool,
	attribute_enumerator_t *this, va_list args)
{
	configuration_attribute_type_t *type;
	chunk_t *data;

	VA_ARGS_VGET(args, type, 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, ike_sa_t *ike_sa,
	linked_list_t *vips)
{
	attribute_enumerator_t *enumerator;

	INIT(enumerator,
		.public = {
			.enumerate = enumerator_enumerate_default,
			.venumerate = _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)
{
	array_destroy(this->servers);
	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;
}
