/* keyutils.c: key utility library
 *
 * Copyright (C) 2005,2011 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
#include <sys/uio.h>
#include <errno.h>
#include <asm/unistd.h>
#include "keyutils.h"

const char keyutils_version_string[] = PKGVERSION;
const char keyutils_build_string[] = PKGBUILD;

#ifdef NO_GLIBC_KEYERR
static int error_inited;
static void (*libc_perror)(const char *msg);
static char *(*libc_strerror_r)(int errnum, char *buf, size_t n);
//static int (*libc_xpg_strerror_r)(int errnum, char *buf, size_t n);
#define RTLD_NEXT      ((void *) -1L)
#endif

#define __weak __attribute__((weak))

key_serial_t __weak add_key(const char *type,
			    const char *description,
			    const void *payload,
			    size_t plen,
			    key_serial_t ringid)
{
	return syscall(__NR_add_key,
		       type, description, payload, plen, ringid);
}

key_serial_t __weak request_key(const char *type,
				const char *description,
				const char * callout_info,
				key_serial_t destringid)
{
	return syscall(__NR_request_key,
		       type, description, callout_info, destringid);
}

static inline long __keyctl(int cmd,
			    unsigned long arg2,
			    unsigned long arg3,
			    unsigned long arg4,
			    unsigned long arg5)
{
	return syscall(__NR_keyctl,
		       cmd, arg2, arg3, arg4, arg5);
}

long __weak keyctl(int cmd, ...)
{
	va_list va;
	unsigned long arg2, arg3, arg4, arg5;

	va_start(va, cmd);
	arg2 = va_arg(va, unsigned long);
	arg3 = va_arg(va, unsigned long);
	arg4 = va_arg(va, unsigned long);
	arg5 = va_arg(va, unsigned long);
	va_end(va);

	return __keyctl(cmd, arg2, arg3, arg4, arg5);
}

key_serial_t keyctl_get_keyring_ID(key_serial_t id, int create)
{
	return keyctl(KEYCTL_GET_KEYRING_ID, id, create);
}

key_serial_t keyctl_join_session_keyring(const char *name)
{
	return keyctl(KEYCTL_JOIN_SESSION_KEYRING, name);
}

long keyctl_update(key_serial_t id, const void *payload, size_t plen)
{
	return keyctl(KEYCTL_UPDATE, id, payload, plen);
}

long keyctl_revoke(key_serial_t id)
{
	return keyctl(KEYCTL_REVOKE, id);
}

long keyctl_chown(key_serial_t id, uid_t uid, gid_t gid)
{
	return keyctl(KEYCTL_CHOWN, id, uid, gid);
}

long keyctl_setperm(key_serial_t id, key_perm_t perm)
{
	return keyctl(KEYCTL_SETPERM, id, perm);
}

long keyctl_describe(key_serial_t id, char *buffer, size_t buflen)
{
	return keyctl(KEYCTL_DESCRIBE, id, buffer, buflen);
}

long keyctl_clear(key_serial_t ringid)
{
	return keyctl(KEYCTL_CLEAR, ringid);
}

long keyctl_link(key_serial_t id, key_serial_t ringid)
{
	return keyctl(KEYCTL_LINK, id, ringid);
}

long keyctl_unlink(key_serial_t id, key_serial_t ringid)
{
	return keyctl(KEYCTL_UNLINK, id, ringid);
}

long keyctl_search(key_serial_t ringid,
		   const char *type,
		   const char *description,
		   key_serial_t destringid)
{
	return keyctl(KEYCTL_SEARCH, ringid, type, description, destringid);
}

long keyctl_read(key_serial_t id, char *buffer, size_t buflen)
{
	return keyctl(KEYCTL_READ, id, buffer, buflen);
}

long keyctl_instantiate(key_serial_t id,
			const void *payload,
			size_t plen,
			key_serial_t ringid)
{
	return keyctl(KEYCTL_INSTANTIATE, id, payload, plen, ringid);
}

long keyctl_negate(key_serial_t id, unsigned timeout, key_serial_t ringid)
{
	return keyctl(KEYCTL_NEGATE, id, timeout, ringid);
}

long keyctl_set_reqkey_keyring(int reqkey_defl)
{
	return keyctl(KEYCTL_SET_REQKEY_KEYRING, reqkey_defl);
}

long keyctl_set_timeout(key_serial_t id, unsigned timeout)
{
	return keyctl(KEYCTL_SET_TIMEOUT, id, timeout);
}

long keyctl_assume_authority(key_serial_t id)
{
	return keyctl(KEYCTL_ASSUME_AUTHORITY, id);
}

long keyctl_get_security(key_serial_t id, char *buffer, size_t buflen)
{
	return keyctl(KEYCTL_GET_SECURITY, id, buffer, buflen);
}

long keyctl_session_to_parent(void)
{
	return keyctl(KEYCTL_SESSION_TO_PARENT);
}

long keyctl_reject(key_serial_t id, unsigned timeout, unsigned error,
		   key_serial_t ringid)
{
	long ret = keyctl(KEYCTL_REJECT, id, timeout, error, ringid);

	/* fall back to keyctl_negate() if this op is not supported by this
	 * kernel version */
	if (ret == -1 && errno == EOPNOTSUPP)
		return keyctl_negate(id, timeout, ringid);
	return ret;
}

long keyctl_instantiate_iov(key_serial_t id,
			    const struct iovec *payload_iov,
			    unsigned ioc,
			    key_serial_t ringid)
{
	long ret = keyctl(KEYCTL_INSTANTIATE_IOV, id, payload_iov, ioc, ringid);

	/* fall back to keyctl_instantiate() if this op is not supported by
	 * this kernel version */
	if (ret == -1 && errno == EOPNOTSUPP) {
		unsigned loop;
		size_t bsize = 0, seg;
		void *buf, *p;

		if (!payload_iov || !ioc)
			return keyctl_instantiate(id, NULL, 0, ringid);
		for (loop = 0; loop < ioc; loop++)
			bsize += payload_iov[loop].iov_len;
		if (bsize == 0)
			return keyctl_instantiate(id, NULL, 0, ringid);
		p = buf = malloc(bsize);
		if (!buf)
			return -1;
		for (loop = 0; loop < ioc; loop++) {
			seg = payload_iov[loop].iov_len;
			p = memcpy(p, payload_iov[loop].iov_base, seg) + seg;
		}
		ret = keyctl_instantiate(id, buf, bsize, ringid);
		free(buf);
	}
	return ret;
}

long keyctl_invalidate(key_serial_t id)
{
	return keyctl(KEYCTL_INVALIDATE, id);
}

long keyctl_get_persistent(uid_t uid, key_serial_t id)
{
	return keyctl(KEYCTL_GET_PERSISTENT, uid, id);
}

/*****************************************************************************/
/*
 * fetch key description into an allocated buffer
 * - resulting string is NUL terminated
 * - returns count not including NUL
 */
int keyctl_describe_alloc(key_serial_t id, char **_buffer)
{
	char *buf;
	long buflen, ret;

	ret = keyctl_describe(id, NULL, 0);
	if (ret < 0)
		return -1;

	for (;;) {
		buflen = ret;
		buf = malloc(buflen);
		if (!buf)
			return -1;

		ret = keyctl_describe(id, buf, buflen);
		if (ret < 0) {
			free(buf);
			return -1;
		}

		if (buflen >= ret)
			break;
		free(buf);
	}

	*_buffer = buf;
	return ret - 1;
}

/*****************************************************************************/
/*
 * fetch key contents into an allocated buffer
 * - resulting buffer has an extra NUL added to the end
 * - returns count (not including extraneous NUL)
 */
int keyctl_read_alloc(key_serial_t id, void **_buffer)
{
	char *buf;
	long buflen, ret;

	ret = keyctl_read(id, NULL, 0);
	if (ret < 0)
		return -1;

	for (;;) {
		buflen = ret;
		buf = malloc(buflen + 1);
		if (!buf)
			return -1;

		ret = keyctl_read(id, buf, buflen);
		if (ret < 0) {
			free(buf);
			return -1;
		}

		if (buflen >= ret)
			break;
		free(buf);
	}

	buf[ret] = 0;
	*_buffer = buf;
	return ret;
}

/*****************************************************************************/
/*
 * fetch key security label into an allocated buffer
 * - resulting string is NUL terminated
 * - returns count not including NUL
 */
int keyctl_get_security_alloc(key_serial_t id, char **_buffer)
{
	char *buf;
	long buflen, ret;

	ret = keyctl_get_security(id, NULL, 0);
	if (ret < 0)
		return -1;

	for (;;) {
		buflen = ret;
		buf = malloc(buflen);
		if (!buf)
			return -1;

		ret = keyctl_get_security(id, buf, buflen);
		if (ret < 0) {
			free(buf);
			return -1;
		}

		if (buflen >= ret)
			break;
		free(buf);
	}

	*_buffer = buf;
	return ret - 1;
}

/*
 * Depth-first recursively apply a function over a keyring tree
 */
static int recursive_key_scan_aux(key_serial_t parent, key_serial_t key,
				  int depth, recursive_key_scanner_t func,
				  void *data)
{
	key_serial_t *pk;
	key_perm_t perm;
	size_t ringlen;
	void *ring;
	char *desc, type[255];
	int desc_len, uid, gid, ret, n, kcount = 0;

	if (depth > 800)
		return 0;

	/* read the key description */
	desc = NULL;
	desc_len = keyctl_describe_alloc(key, &desc);
	if (desc_len < 0)
		goto do_this_key;

	/* parse */
	type[0] = 0;

	n = sscanf(desc, "%[^;];%d;%d;%x;", type, &uid, &gid, &perm);
	if (n != 4) {
		free(desc);
		desc = NULL;
		errno = -EINVAL;
		desc_len = -1;
		goto do_this_key;
	}

	/* if it's a keyring then we're going to want to recursively search it
	 * if we can */
	if (strcmp(type, "keyring") == 0) {
		/* read the keyring's contents */
		ret = keyctl_read_alloc(key, &ring);
		if (ret < 0)
			goto do_this_key;

		ringlen = ret;

		/* walk the keyring */
		pk = ring;
		for (ringlen = ret;
		     ringlen >= sizeof(key_serial_t);
		     ringlen -= sizeof(key_serial_t)
		     )
			kcount += recursive_key_scan_aux(key, *pk++, depth + 1,
							 func, data);

		free(ring);
	}

do_this_key:
	kcount += func(parent, key, desc, desc_len, data);
	free(desc);
	return kcount;
}

/*
 * Depth-first apply a function over a keyring tree
 */
int recursive_key_scan(key_serial_t key, recursive_key_scanner_t func, void *data)
{
	return recursive_key_scan_aux(0, key, 0, func, data);
}

/*
 * Depth-first apply a function over session keyring tree
 */
int recursive_session_key_scan(recursive_key_scanner_t func, void *data)
{
	key_serial_t session =
		keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0);
	if (session > 0)
		return recursive_key_scan(session, func, data);
	return 0;
}

/*
 * Find a key by type and description
 */
key_serial_t find_key_by_type_and_desc(const char *type, const char *desc,
				       key_serial_t destringid)
{
	key_serial_t id, error;
	FILE *f;
	char buf[1024], typebuf[40], rdesc[1024], *kdesc, *cp;
	int n, ndesc, dlen;

	error = ENOKEY;

	id = request_key(type, desc, NULL, destringid);
	if (id >= 0 || errno == ENOMEM)
		return id;
	if (errno != ENOKEY)
		error = errno;

	dlen = strlen(desc);

	f = fopen("/proc/keys", "r");
	if (!f) {
		fprintf(stderr, "libkeyutils: Can't open /proc/keys: %m\n");
		return -1;
	}

	while (fgets(buf, sizeof(buf), f)) {
		cp = strchr(buf, '\n');
		if (*cp)
			*cp = '\0';

		ndesc = 0;
		n = sscanf(buf, "%x %*s %*u %*s %*x %*d %*d %s %n",
			   &id, typebuf, &ndesc);
		if (n == 2 && ndesc > 0 && ndesc <= cp - buf) {
			if (strcmp(typebuf, type) != 0)
				continue;
			kdesc = buf + ndesc;
			if (memcmp(kdesc, desc, dlen) != 0)
				continue;
			if (kdesc[dlen] != ':' &&
			    kdesc[dlen] != '\0' &&
			    kdesc[dlen] != ' ')
				continue;
			kdesc[dlen] = '\0';

			/* The key type appends extra stuff to the end of the
			 * description after a colon in /proc/keys.  Colons,
			 * however, are allowed in descriptions, so we need to
			 * make a further check. */
			n = keyctl_describe(id, rdesc, sizeof(rdesc) - 1);
			if (n == -1) {
				if (errno != ENOKEY)
					error = errno;
				if (errno == ENOMEM)
					break;
			}
			if (n >= sizeof(rdesc) - 1)
				continue;
			rdesc[n] = '\0';

			cp = strrchr(rdesc, ';');
			if (!cp)
				continue;
			cp++;
			if (strcmp(cp, desc) != 0)
				continue;

			fclose(f);

			if (destringid &&
			    keyctl_link(id, destringid) == -1)
				return -1;

			return id;
		}
	}

	fclose(f);
	errno = error;
	return -1;
}

#ifdef NO_GLIBC_KEYERR
/*****************************************************************************/
/*
 * initialise error handling
 */
static void error_init(void)
{
	char *err;

	error_inited = 1;

	dlerror();

	libc_perror = dlsym(RTLD_NEXT,"perror");
	if (!libc_perror) {
		fprintf(stderr, "Failed to look up next perror\n");
		err = dlerror();
		if (err)
			fprintf(stderr, "%s\n", err);
		abort();
	}

	//fprintf(stderr, "next perror at %p\n", libc_perror);

	libc_strerror_r = dlsym(RTLD_NEXT,"strerror_r");
	if (!libc_strerror_r) {
		fprintf(stderr, "Failed to look up next strerror_r\n");
		err = dlerror();
		if (err)
			fprintf(stderr, "%s\n", err);
		abort();
	}

	//fprintf(stderr, "next strerror_r at %p\n", libc_strerror_r);

#if 0
	libc_xpg_strerror_r = dlsym(RTLD_NEXT,"xpg_strerror_r");
	if (!libc_xpg_strerror_r) {
		fprintf(stderr, "Failed to look up next xpg_strerror_r\n");
		err = dlerror();
		if (err)
			fprintf(stderr, "%s\n", err);
		abort();
	}

	//fprintf(stderr, "next xpg_strerror_r at %p\n", libc_xpg_strerror_r);
#endif

} /* end error_init() */

/*****************************************************************************/
/*
 * overload glibc's strerror_r() with a version that knows about key errors
 */
char *strerror_r(int errnum, char *buf, size_t n)
{
	const char *errstr;
	int len;

	printf("hello\n");

	if (!error_inited)
		error_init();

	switch (errnum) {
	case ENOKEY:
		errstr = "Requested key not available";
		break;

	case EKEYEXPIRED:
		errstr = "Key has expired";
		break;

	case EKEYREVOKED:
		errstr = "Key has been revoked";
		break;

	case EKEYREJECTED:
		errstr = "Key was rejected by service";
		break;

	default:
		return libc_strerror_r(errnum, buf, n);
	}

	len = strlen(errstr) + 1;
	if (n > len) {
		errno = ERANGE;
		if (n > 0) {
			memcpy(buf, errstr, n - 1);
			buf[n - 1] = 0;
		}
		return NULL;
	}
	else {
		memcpy(buf, errstr, len);
		return buf;
	}

} /* end strerror_r() */

#if 0
/*****************************************************************************/
/*
 * overload glibc's strerror_r() with a version that knows about key errors
 */
int xpg_strerror_r(int errnum, char *buf, size_t n)
{
	const char *errstr;
	int len;

	if (!error_inited)
		error_init();

	switch (errnum) {
	case ENOKEY:
		errstr = "Requested key not available";
		break;

	case EKEYEXPIRED:
		errstr = "Key has expired";
		break;

	case EKEYREVOKED:
		errstr = "Key has been revoked";
		break;

	case EKEYREJECTED:
		errstr = "Key was rejected by service";
		break;

	default:
		return libc_xpg_strerror_r(errnum, buf, n);
	}

	len = strlen(errstr) + 1;
	if (n > len) {
		errno = ERANGE;
		if (n > 0) {
			memcpy(buf, errstr, n - 1);
			buf[n - 1] = 0;
		}
		return -1;
	}
	else {
		memcpy(buf, errstr, len);
		return 0;
	}

} /* end xpg_strerror_r() */
#endif

/*****************************************************************************/
/*
 *
 */
void perror(const char *msg)
{
	if (!error_inited)
		error_init();

	switch (errno) {
	case ENOKEY:
		fprintf(stderr, "%s: Requested key not available\n", msg);
		return;

	case EKEYEXPIRED:
		fprintf(stderr, "%s: Key has expired\n", msg);
		return;

	case EKEYREVOKED:
		fprintf(stderr, "%s: Key has been revoked\n", msg);
		return;

	case EKEYREJECTED:
		fprintf(stderr, "%s: Key was rejected by service\n", msg);
		return;

	default:
		libc_perror(msg);
		return;
	}

} /* end perror() */
#endif
