/*
 * DNS Resolver Module User-space Helper for AFSDB records
 *
 * Copyright (C) Wang Lei (wang840925@gmail.com) 2010
 * Authors: Wang Lei (wang840925@gmail.com)
 *          David Howells (dhowells@redhat.com)
 *
 * This is a userspace tool for querying AFSDB RR records in the DNS on behalf
 * of the kernel, and converting the VL server addresses to IPv4 format so that
 * they can be used by the kAFS filesystem.
 *
 * Compile with:
 *
 * 	cc -o key.dns_resolver key.dns_resolver.c -lresolv -lkeyutils
 *
 * As some function like res_init() should use the static library, which is a
 * bug of libresolv, that is the reason for cifs.upcall to reimplement.
 *
 * To use this program, you must tell /sbin/request-key how to invoke it.  You
 * need to have the keyutils package installed and something like the following
 * lines added to your /etc/request-key.conf file:
 *
 * 	#OP    TYPE         DESCRIPTION CALLOUT INFO PROGRAM ARG1 ARG2 ARG3 ...
 * 	====== ============ =========== ============ ==========================
 * 	create dns_resolver afsdb:*     *            /sbin/key.dns_resolver %k
 *
 *
 * 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.
 *
 * 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.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#include "key.dns.h"

static const char *DNS_PARSE_VERSION = "1.0";
static const char prog[] = "key.dns_resolver";
static const char key_type[] = "dns_resolver";
static const char a_query_type[] = "a";
static const char aaaa_query_type[] = "aaaa";
static const char afsdb_query_type[] = "afsdb";
key_serial_t key;
static int verbose;
int debug_mode;
unsigned mask = INET_ALL;


/*
 * segmental payload
 */
struct iovec payload[N_PAYLOAD];
int payload_index;

/*
 * Print an error to stderr or the syslog, negate the key being created and
 * exit
 */
void error(const char *fmt, ...)
{
	va_list va;

	va_start(va, fmt);
	if (isatty(2)) {
		vfprintf(stderr, fmt, va);
		fputc('\n', stderr);
	} else {
		vsyslog(LOG_ERR, fmt, va);
	}
	va_end(va);

	/*
	 * on error, negatively instantiate the key ourselves so that we can
	 * make sure the kernel doesn't hang it off of a searchable keyring
	 * and interfere with the next attempt to instantiate the key.
	 */
	if (!debug_mode)
		keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT);

	exit(1);
}

#define error(FMT, ...) error("Error: " FMT, ##__VA_ARGS__);

/*
 * Just print an error to stderr or the syslog
 */
void _error(const char *fmt, ...)
{
	va_list va;

	va_start(va, fmt);
	if (isatty(2)) {
		vfprintf(stderr, fmt, va);
		fputc('\n', stderr);
	} else {
		vsyslog(LOG_ERR, fmt, va);
	}
	va_end(va);
}

/*
 * Print status information
 */
void info(const char *fmt, ...)
{
	va_list va;

	if (verbose < 1)
		return;

	va_start(va, fmt);
	if (isatty(1)) {
		fputs("I: ", stdout);
		vfprintf(stdout, fmt, va);
		fputc('\n', stdout);
	} else {
		vsyslog(LOG_INFO, fmt, va);
	}
	va_end(va);
}

/*
 * Print a nameserver error and exit
 */
static const int ns_errno_map[] = {
	[0]			= ECONNREFUSED,
	[HOST_NOT_FOUND]	= ENODATA,
	[TRY_AGAIN]		= EAGAIN,
	[NO_RECOVERY]		= ECONNREFUSED,
	[NO_DATA]		= ENODATA,
};

void _nsError(int err, const char *domain)
{
	if (isatty(2))
		fprintf(stderr, "NS:%s: %s.\n", domain, hstrerror(err));
	else
		syslog(LOG_INFO, "%s: %s", domain, hstrerror(err));

	if (err >= sizeof(ns_errno_map) / sizeof(ns_errno_map[0]))
		err = ECONNREFUSED;
	else
		err = ns_errno_map[err];

	info("Reject the key with error %d", err);
}

void nsError(int err, const char *domain)
{
	unsigned timeout;
	int ret;

	_nsError(err, domain);

	switch (err) {
	case TRY_AGAIN:
		timeout = 1;
		break;
	case 0:
	case NO_RECOVERY:
		timeout = 10;
		break;
	default:
		timeout = 1 * 60;
		break;
	}

	if (!debug_mode) {
		ret = keyctl_reject(key, timeout, err, KEY_REQKEY_DEFL_DEFAULT);
		if (ret == -1)
			error("%s: keyctl_reject: %m", __func__);
	}
	exit(0);
}

/*
 * Print debugging information
 */
void debug(const char *fmt, ...)
{
	va_list va;

	if (verbose < 2)
		return;

	va_start(va, fmt);
	if (isatty(1)) {
		fputs("D: ", stdout);
		vfprintf(stdout, fmt, va);
		fputc('\n', stdout);
	} else {
		vsyslog(LOG_DEBUG, fmt, va);
	}
	va_end(va);
}

/*
 * Append an address to the payload segment list
 */
void append_address_to_payload(const char *addr)
{
	size_t sz = strlen(addr);
	char *copy;
	int loop;

	debug("append '%s'", addr);

	if (payload_index + 2 > N_PAYLOAD - 1)
		return;

	/* discard duplicates */
	for (loop = 0; loop < payload_index; loop++)
		if (payload[loop].iov_len == sz &&
		    memcmp(payload[loop].iov_base, addr, sz) == 0)
			return;

	copy = malloc(sz);
	if (!copy)
		error("%s: malloc: %m", __func__);
	memcpy(copy, addr, sz);

	if (payload_index != 0) {
		payload[payload_index  ].iov_base = ",";
		payload[payload_index++].iov_len = 1;
	}
	payload[payload_index  ].iov_base = copy;
	payload[payload_index++].iov_len = sz;
}

/*
 * Dump the payload when debugging
 */
void dump_payload(void)
{
	size_t plen, n;
	char *buf, *p;
	int loop;

	if (debug_mode)
		verbose = 1;
	if (verbose < 1)
		return;

	plen = 0;
	for (loop = 0; loop < payload_index; loop++) {
		n = payload[loop].iov_len;
		debug("seg[%d]: %zu", loop, n);
		plen += n;
	}
	if (plen == 0) {
		info("The key instantiation data is empty");
		return;
	}

	debug("total: %zu", plen);
	buf = malloc(plen + 1);
	if (!buf)
		return;

	p = buf;
	for (loop = 0; loop < payload_index; loop++) {
		n = payload[loop].iov_len;
		memcpy(p, payload[loop].iov_base, n);
		p += n;
	}

	info("The key instantiation data is '%s'", buf);
	free(buf);
}

/*
 * Perform address resolution on a hostname and add the resulting address as a
 * string to the list of payload segments.
 */
int dns_resolver(const char *server_name, const char *port)
{
	struct addrinfo hints, *addr, *ai;
	char buf[INET6_ADDRSTRLEN + 8 + 1];
	int ret, len;
	void *sa;

	debug("Resolve '%s' with %x", server_name, mask);

	memset(&hints, 0, sizeof(hints));
	switch (mask & INET_ALL) {
	case INET_IP4_ONLY:	hints.ai_family = AF_INET;	debug("IPv4"); break;
	case INET_IP6_ONLY:	hints.ai_family = AF_INET6;	debug("IPv6"); break;
	default: break;
	}

	/* resolve name to ip */
	ret = getaddrinfo(server_name, NULL, &hints, &addr);
	if (ret) {
		info("unable to resolve hostname: %s [%s]",
		     server_name, gai_strerror(ret));
		return -1;
	}

	for (ai = addr; ai; ai = ai->ai_next) {
		debug("RR: %x,%x,%x,%x,%x,%s",
		      ai->ai_flags, ai->ai_family,
		      ai->ai_socktype, ai->ai_protocol,
		      ai->ai_addrlen, ai->ai_canonname);

		/* convert address to string */
		switch (ai->ai_family) {
		case AF_INET:
			if (!(mask & INET_IP4_ONLY))
				continue;
			sa = &(((struct sockaddr_in *)ai->ai_addr)->sin_addr);
			len = INET_ADDRSTRLEN;
			break;
		case AF_INET6:
			if (!(mask & INET_IP6_ONLY))
				continue;
			sa = &(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr);
			len = INET6_ADDRSTRLEN;
			break;
		default:
			debug("Address of unknown family %u", addr->ai_family);
			continue;
		}

		if (!inet_ntop(ai->ai_family, sa, buf, len))
			error("%s: inet_ntop: %m", __func__);

		if (port)
			strcat(buf, port);
		append_address_to_payload(buf);
		if (mask & ONE_ADDR_ONLY)
			break;
	}

	freeaddrinfo(addr);
	return 0;
}

/*
 * Look up a A and/or AAAA records to get host addresses
 *
 * The callout_info is parsed for request options.  For instance, "ipv4" to
 * request only IPv4 addresses, "ipv6" to request only IPv6 addresses and
 * "list" to get multiple addresses.
 */
static __attribute__((noreturn))
int dns_query_a_or_aaaa(const char *hostname, char *options)
{
	int ret;

	debug("Get A/AAAA RR for hostname:'%s', options:'%s'",
	      hostname, options);

	if (!options[0]) {
		/* legacy mode */
		mask = INET_IP4_ONLY | ONE_ADDR_ONLY;
	} else {
		char *k, *val;

		mask = INET_ALL | ONE_ADDR_ONLY;

		do {
			k = options;
			options = strchr(options, ' ');
			if (!options)
				options = k + strlen(k);
			else
				*options++ = '\0';
			if (!*k)
				continue;
			if (strchr(k, ','))
				error("Option name '%s' contains a comma", k);

			val = strchr(k, '=');
			if (val)
				*val++ = '\0';

			debug("Opt %s", k);

			if (strcmp(k, "ipv4") == 0) {
				mask &= ~INET_ALL;
				mask |= INET_IP4_ONLY;
			} else if (strcmp(k, "ipv6") == 0) {
				mask &= ~INET_ALL;
				mask |= INET_IP6_ONLY;
			} else if (strcmp(k, "list") == 0) {
				mask &= ~ONE_ADDR_ONLY;
			}

		} while (*options);
	}

	/* Turn the hostname into IP addresses */
	ret = dns_resolver(hostname, NULL);
	if (ret)
		nsError(NO_DATA, hostname);

	/* handle a lack of results */
	if (payload_index == 0)
		nsError(NO_DATA, hostname);

	/* must include a NUL char at the end of the payload */
	payload[payload_index].iov_base = "";
	payload[payload_index++].iov_len = 1;
	dump_payload();

	/* load the key with data key */
	if (!debug_mode) {
		ret = keyctl_instantiate_iov(key, payload, payload_index, 0);
		if (ret == -1)
			error("%s: keyctl_instantiate: %m", __func__);
	}

	exit(0);
}

/*
 * Print usage details,
 */
static __attribute__((noreturn))
void usage(void)
{
	if (isatty(2)) {
		fprintf(stderr,
			"Usage: %s [-vv] key_serial\n",
			prog);
		fprintf(stderr,
			"Usage: %s -D [-vv] <desc> <calloutinfo>\n",
			prog);
	} else {
		info("Usage: %s [-vv] key_serial", prog);
	}
	exit(2);
}

const struct option long_options[] = {
	{ "debug",	0, NULL, 'D' },
	{ "verbose",	0, NULL, 'v' },
	{ "version",	0, NULL, 'V' },
	{ NULL,		0, NULL, 0 }
};

/*
 *
 */
int main(int argc, char *argv[])
{
	int ktlen, qtlen, ret;
	char *keyend, *p;
	char *callout_info = NULL;
	char *buf = NULL, *name;

	openlog(prog, 0, LOG_DAEMON);

	while ((ret = getopt_long(argc, argv, "vDV", long_options, NULL)) != -1) {
		switch (ret) {
		case 'D':
			debug_mode = 1;
			continue;
		case 'V':
			printf("version: %s from %s (%s)\n",
			       DNS_PARSE_VERSION,
			       keyutils_version_string,
			       keyutils_build_string);
			exit(0);
		case 'v':
			verbose++;
			continue;
		default:
			if (!isatty(2))
				syslog(LOG_ERR, "unknown option: %c", ret);
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (!debug_mode) {
		if (argc != 1)
			usage();

		/* get the key ID */
		if (!**argv)
			error("Invalid blank key ID");
		key = strtol(*argv, &p, 10);
		if (*p)
			error("Invalid key ID format");

		/* get the key description (of the form "x;x;x;x;<query_type>:<name>") */
		ret = keyctl_describe_alloc(key, &buf);
		if (ret == -1)
			error("keyctl_describe_alloc failed: %m");

		/* get the callout_info (which can supply options) */
		ret = keyctl_read_alloc(KEY_SPEC_REQKEY_AUTH_KEY, (void **)&callout_info);
		if (ret == -1)
			error("Invalid key callout_info read: %m");
	} else {
		if (argc != 2)
			usage();

		ret = asprintf(&buf, "%s;-1;-1;0;%s", key_type, argv[0]);
		if (ret < 0)
			error("Error %m");
		callout_info = argv[1];
	}

	ret = 1;
	info("Key description: '%s'", buf);
	info("Callout info: '%s'", callout_info);

	p = strchr(buf, ';');
	if (!p)
		error("Badly formatted key description '%s'", buf);
	ktlen = p - buf;

	/* make sure it's the type we are expecting */
	if (ktlen != sizeof(key_type) - 1 ||
	    memcmp(buf, key_type, ktlen) != 0)
		error("Key type is not supported: '%*.*s'", ktlen, ktlen, buf);

	keyend = buf + ktlen + 1;

	/* the actual key description follows the last semicolon */
	keyend = rindex(keyend, ';');
	if (!keyend)
		error("Invalid key description: %s", buf);
	keyend++;

	name = index(keyend, ':');
	if (!name)
		dns_query_a_or_aaaa(keyend, callout_info);

	qtlen = name - keyend;
	name++;

	info("Query type: '%*.*s'", qtlen, qtlen, keyend);
	
	if ((qtlen == sizeof(a_query_type) - 1 &&
	     memcmp(keyend, a_query_type, sizeof(a_query_type) - 1) == 0) ||
	    (qtlen == sizeof(aaaa_query_type) - 1 &&
	     memcmp(keyend, aaaa_query_type, sizeof(aaaa_query_type) - 1) == 0)
	    ) {
		info("Do DNS query of A/AAAA type for:'%s' mask:'%s'",
		     name, callout_info);
		dns_query_a_or_aaaa(name, callout_info);
	}

	if (qtlen == sizeof(afsdb_query_type) - 1 &&
	    memcmp(keyend, afsdb_query_type, sizeof(afsdb_query_type) - 1) == 0
	    ) {
		info("Do AFS VL server query for:'%s' mask:'%s'",
		     name, callout_info);
		afs_look_up_VL_servers(name, callout_info);
	}

	error("Query type: \"%*.*s\" is not supported", qtlen, qtlen, keyend);
}
