/* keyctl.c: key control program
 *
 * 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 General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <asm/unistd.h>
#include "keyutils.h"

struct command {
	int (*action)(int argc, char *argv[]);
	const char	*name;
	const char	*format;
};

static int act_keyctl___version(int argc, char *argv[]);
static int act_keyctl_show(int argc, char *argv[]);
static int act_keyctl_add(int argc, char *argv[]);
static int act_keyctl_padd(int argc, char *argv[]);
static int act_keyctl_request(int argc, char *argv[]);
static int act_keyctl_request2(int argc, char *argv[]);
static int act_keyctl_prequest2(int argc, char *argv[]);
static int act_keyctl_update(int argc, char *argv[]);
static int act_keyctl_pupdate(int argc, char *argv[]);
static int act_keyctl_newring(int argc, char *argv[]);
static int act_keyctl_revoke(int argc, char *argv[]);
static int act_keyctl_clear(int argc, char *argv[]);
static int act_keyctl_link(int argc, char *argv[]);
static int act_keyctl_unlink(int argc, char *argv[]);
static int act_keyctl_search(int argc, char *argv[]);
static int act_keyctl_read(int argc, char *argv[]);
static int act_keyctl_pipe(int argc, char *argv[]);
static int act_keyctl_print(int argc, char *argv[]);
static int act_keyctl_list(int argc, char *argv[]);
static int act_keyctl_rlist(int argc, char *argv[]);
static int act_keyctl_describe(int argc, char *argv[]);
static int act_keyctl_rdescribe(int argc, char *argv[]);
static int act_keyctl_chown(int argc, char *argv[]);
static int act_keyctl_chgrp(int argc, char *argv[]);
static int act_keyctl_setperm(int argc, char *argv[]);
static int act_keyctl_session(int argc, char *argv[]);
static int act_keyctl_instantiate(int argc, char *argv[]);
static int act_keyctl_pinstantiate(int argc, char *argv[]);
static int act_keyctl_negate(int argc, char *argv[]);
static int act_keyctl_timeout(int argc, char *argv[]);
static int act_keyctl_security(int argc, char *argv[]);
static int act_keyctl_new_session(int argc, char *argv[]);
static int act_keyctl_reject(int argc, char *argv[]);
static int act_keyctl_reap(int argc, char *argv[]);
static int act_keyctl_purge(int argc, char *argv[]);

const struct command commands[] = {
	{ act_keyctl___version,	"--version",	"" },
	{ act_keyctl_add,	"add",		"<type> <desc> <data> <keyring>" },
	{ act_keyctl_chgrp,	"chgrp",	"<key> <gid>" },
	{ act_keyctl_chown,	"chown",	"<key> <uid>" },
	{ act_keyctl_clear,	"clear",	"<keyring>" },
	{ act_keyctl_describe,	"describe",	"<keyring>" },
	{ act_keyctl_instantiate, "instantiate","<key> <data> <keyring>" },
	{ act_keyctl_link,	"link",		"<key> <keyring>" },
	{ act_keyctl_list,	"list",		"<keyring>" },
	{ act_keyctl_negate,	"negate",	"<key> <timeout> <keyring>" },
	{ act_keyctl_new_session, "new_session",	"" },
	{ act_keyctl_newring,	"newring",	"<name> <keyring>" },
	{ act_keyctl_padd,	"padd",		"<type> <desc> <keyring>" },
	{ act_keyctl_pinstantiate, "pinstantiate","<key> <keyring>" },
	{ act_keyctl_pipe,	"pipe",		"<key>" },
	{ act_keyctl_prequest2,	"prequest2",	"<type> <desc> [<dest_keyring>]" },
	{ act_keyctl_print,	"print",	"<key>" },
	{ act_keyctl_pupdate,	"pupdate",	"<key>" },
	{ act_keyctl_purge,	"purge",	"<type>" },
	{ NULL,			"purge",	"[-p] [-i] <type> <desc>" },
	{ NULL,			"purge",	"-s <type> <desc>" },
	{ act_keyctl_rdescribe,	"rdescribe",	"<keyring> [sep]" },
	{ act_keyctl_read,	"read",		"<key>" },
	{ act_keyctl_reap,	"reap",		"[-v]" },
	{ act_keyctl_reject,	"reject",	"<key> <timeout> <error> <keyring>" },
	{ act_keyctl_request,	"request",	"<type> <desc> [<dest_keyring>]" },
	{ act_keyctl_request2,	"request2",	"<type> <desc> <info> [<dest_keyring>]" },
	{ act_keyctl_revoke,	"revoke",	"<key>" },
	{ act_keyctl_rlist,	"rlist",	"<keyring>" },
	{ act_keyctl_search,	"search",	"<keyring> <type> <desc> [<dest_keyring>]" },
	{ act_keyctl_security,	"security",	"<key>" },
	{ act_keyctl_session,	"session",	"" },
	{ NULL,			"session",	"- [<prog> <arg1> <arg2> ...]" },
	{ NULL,			"session",	"<name> [<prog> <arg1> <arg2> ...]" },
	{ act_keyctl_setperm,	"setperm",	"<key> <mask>" },
	{ act_keyctl_show,	"show",		"[-x] [<keyring>]" },
	{ act_keyctl_timeout,	"timeout",	"<key> <timeout>" },
	{ act_keyctl_unlink,	"unlink",	"<key> [<keyring>]" },
	{ act_keyctl_update,	"update",	"<key> <data>" },
	{ NULL,			NULL,		NULL }
};

static int dump_key_tree(key_serial_t keyring, const char *name, int hex_key_IDs);
static void format(void) __attribute__((noreturn));
static void error(const char *msg) __attribute__((noreturn));
static key_serial_t get_key_id(const char *arg);

static uid_t myuid;
static gid_t mygid, *mygroups;
static int myngroups;
static int verbose;

/*****************************************************************************/
/*
 * handle an error
 */
static inline void error(const char *msg)
{
	perror(msg);
	exit(1);

} /* end error() */

/*****************************************************************************/
/*
 * execute the appropriate subcommand
 */
int main(int argc, char *argv[])
{
	const struct command *cmd, *best;
	int n;

	argv++;
	argc--;

	if (argc == 0)
		format();

	/* find the best fit command */
	best = NULL;
	n = strlen(*argv);

	for (cmd = commands; cmd->name; cmd++) {
		if (!cmd->action)
			continue;
		if (memcmp(cmd->name, *argv, n) != 0)
			continue;

		if (cmd->name[n] == 0) {
			/* exact match */
			best = cmd;
			break;
		}

		/* partial match */
		if (best) {
			fprintf(stderr, "Ambiguous command\n");
			exit(2);
		}

		best = cmd;
	}

	if (!best) {
		fprintf(stderr, "Unknown command\n");
		exit(2);
	}

	/* grab my UID, GID and groups */
	myuid = geteuid();
	mygid = getegid();
	myngroups = getgroups(0, NULL);

	if (myuid == -1 || mygid == -1 || myngroups == -1)
		error("Unable to get UID/GID/#Groups\n");

	mygroups = calloc(myngroups, sizeof(gid_t));
	if (!mygroups)
		error("calloc");

	myngroups = getgroups(myngroups, mygroups);
	if (myngroups < 0)
		error("Unable to get Groups\n");

	return best->action(argc, argv);

} /* end main() */

/*****************************************************************************/
/*
 * display command format information
 */
static void format(void)
{
	const struct command *cmd;

	fprintf(stderr, "Format:\n");

	for (cmd = commands; cmd->name; cmd++)
		fprintf(stderr, "  keyctl %s %s\n", cmd->name, cmd->format);

	fprintf(stderr, "\n");
	fprintf(stderr, "Key/keyring ID:\n");
	fprintf(stderr, "  <nnn>   numeric keyring ID\n");
	fprintf(stderr, "  @t      thread keyring\n");
	fprintf(stderr, "  @p      process keyring\n");
	fprintf(stderr, "  @s      session keyring\n");
	fprintf(stderr, "  @u      user keyring\n");
	fprintf(stderr, "  @us     user default session keyring\n");
	fprintf(stderr, "  @g      group keyring\n");
	fprintf(stderr, "  @a      assumed request_key authorisation key\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "<type> can be \"user\" for a user-defined keyring\n");
	fprintf(stderr, "If you do this, prefix the description with \"<subtype>:\"\n");

	exit(2);

} /* end format() */

/*****************************************************************************/
/*
 * Display version information
 */
static int act_keyctl___version(int argc, char *argv[])
{
	printf("keyctl from %s (Built %s)\n",
	       keyutils_version_string, keyutils_build_string);
	return 0;
}

/*****************************************************************************/
/*
 * grab data from stdin
 */
static char *grab_stdin(size_t *_size)
{
	static char input[65536 + 1];
	int n, tmp;

	n = 0;
	do {
		tmp = read(0, input + n, sizeof(input) - 1 - n);
		if (tmp < 0)
			error("stdin");

		if (tmp == 0)
			break;

		n += tmp;

	} while (n < sizeof(input));

	if (n >= sizeof(input)) {
		fprintf(stderr, "Too much data read on stdin\n");
		exit(1);
	}

	input[n] = '\0';
	*_size = n;

	return input;

} /* end grab_stdin() */

/*****************************************************************************/
/*
 * convert the permissions mask to a string representing the permissions we
 * have actually been granted
 */
static void calc_perms(char *pretty, key_perm_t perm, uid_t uid, gid_t gid)
{
	unsigned perms;
	gid_t *pg;
	int loop;

	perms = (perm & KEY_POS_ALL) >> 24;

	if (uid == myuid) {
		perms |= (perm & KEY_USR_ALL) >> 16;
		goto write_mask;
	}

	if (gid != -1) {
		if (gid == mygid) {
			perms |= (perm & KEY_GRP_ALL) >> 8;
			goto write_mask;
		}

		pg = mygroups;
		for (loop = myngroups; loop > 0; loop--, pg++) {
			if (gid == *pg) {
				perms |= (perm & KEY_GRP_ALL) >> 8;
				goto write_mask;
			}
		}
	}

	perms |= (perm & KEY_OTH_ALL);

write_mask:
	sprintf(pretty, "--%c%c%c%c%c%c",
		perms & KEY_OTH_SETATTR	? 'a' : '-',
		perms & KEY_OTH_LINK	? 'l' : '-',
		perms & KEY_OTH_SEARCH	? 's' : '-',
		perms & KEY_OTH_WRITE	? 'w' : '-',
		perms & KEY_OTH_READ	? 'r' : '-',
		perms & KEY_OTH_VIEW	? 'v' : '-');

} /* end calc_perms() */

/*****************************************************************************/
/*
 * show the parent process's session keyring
 */
static int act_keyctl_show(int argc, char *argv[])
{
	key_serial_t keyring = KEY_SPEC_SESSION_KEYRING;
	int hex_key_IDs = 0;

	if (argc >= 2 && strcmp(argv[1], "-x") == 0) {
		hex_key_IDs = 1;
		argc--;
		argv++;
	}

	if (argc > 2)
		format();

	if (argc == 2)
		keyring = get_key_id(argv[1]);

	dump_key_tree(keyring, argc == 2 ? "Keyring" : "Session Keyring", hex_key_IDs);
	return 0;

} /* end act_keyctl_show() */

/*****************************************************************************/
/*
 * add a key
 */
static int act_keyctl_add(int argc, char *argv[])
{
	key_serial_t dest;
	int ret;

	if (argc != 5)
		format();

	dest = get_key_id(argv[4]);

	ret = add_key(argv[1], argv[2], argv[3], strlen(argv[3]), dest);
	if (ret < 0)
		error("add_key");

	/* print the resulting key ID */
	printf("%d\n", ret);
	return 0;

} /* end act_keyctl_add() */

/*****************************************************************************/
/*
 * add a key, reading from a pipe
 */
static int act_keyctl_padd(int argc, char *argv[])
{
	key_serial_t dest;
	size_t datalen;
	void *data;
	int ret;


	if (argc != 4)
		format();

	dest = get_key_id(argv[3]);

	data = grab_stdin(&datalen);

	ret = add_key(argv[1], argv[2], data, datalen, dest);
	if (ret < 0)
		error("add_key");

	/* print the resulting key ID */
	printf("%d\n", ret);
	return 0;

} /* end act_keyctl_padd() */

/*****************************************************************************/
/*
 * request a key
 */
static int act_keyctl_request(int argc, char *argv[])
{
	key_serial_t dest;
	int ret;

	if (argc != 3 && argc != 4)
		format();

	dest = 0;
	if (argc == 4)
		dest = get_key_id(argv[3]);

	ret = request_key(argv[1], argv[2], NULL, dest);
	if (ret < 0)
		error("request_key");

	/* print the resulting key ID */
	printf("%d\n", ret);
	return 0;

} /* end act_keyctl_request() */

/*****************************************************************************/
/*
 * request a key, with recourse to /sbin/request-key
 */
static int act_keyctl_request2(int argc, char *argv[])
{
	key_serial_t dest;
	int ret;

	if (argc != 4 && argc != 5)
		format();

	dest = 0;
	if (argc == 5)
		dest = get_key_id(argv[4]);

	ret = request_key(argv[1], argv[2], argv[3], dest);
	if (ret < 0)
		error("request_key");

	/* print the resulting key ID */
	printf("%d\n", ret);
	return 0;

} /* end act_keyctl_request2() */

/*****************************************************************************/
/*
 * request a key, with recourse to /sbin/request-key, reading the callout info
 * from a pipe
 */
static int act_keyctl_prequest2(int argc, char *argv[])
{
	char *args[6];
	size_t datalen;

	if (argc != 3 && argc != 4)
		format();

	args[0] = argv[0];
	args[1] = argv[1];
	args[2] = argv[2];
	args[3] = grab_stdin(&datalen);
	args[4] = argv[3];
	args[5] = NULL;

	return act_keyctl_request2(argc + 1, args);

} /* end act_keyctl_prequest2() */

/*****************************************************************************/
/*
 * update a key
 */
static int act_keyctl_update(int argc, char *argv[])
{
	key_serial_t key;

	if (argc != 3)
		format();

	key = get_key_id(argv[1]);

	if (keyctl_update(key, argv[2], strlen(argv[2])) < 0)
		error("keyctl_update");

	return 0;

} /* end act_keyctl_update() */

/*****************************************************************************/
/*
 * update a key, reading from a pipe
 */
static int act_keyctl_pupdate(int argc, char *argv[])
{
	key_serial_t key;
	size_t datalen;
	void *data;

	if (argc != 2)
		format();

	key = get_key_id(argv[1]);
	data = grab_stdin(&datalen);

	if (keyctl_update(key, data, datalen) < 0)
		error("keyctl_update");

	return 0;

} /* end act_keyctl_pupdate() */

/*****************************************************************************/
/*
 * create a new keyring
 */
static int act_keyctl_newring(int argc, char *argv[])
{
	key_serial_t dest;
	int ret;

	if (argc != 3)
		format();

	dest = get_key_id(argv[2]);

	ret = add_key("keyring", argv[1], NULL, 0, dest);
	if (ret < 0)
		error("add_key");

	printf("%d\n", ret);
	return 0;

} /* end act_keyctl_newring() */

/*****************************************************************************/
/*
 * revoke a key
 */
static int act_keyctl_revoke(int argc, char *argv[])
{
	key_serial_t key;

	if (argc != 2)
		format();

	key = get_key_id(argv[1]);

	if (keyctl_revoke(key) < 0)
		error("keyctl_revoke");

	return 0;

} /* end act_keyctl_revoke() */

/*****************************************************************************/
/*
 * clear a keyring
 */
static int act_keyctl_clear(int argc, char *argv[])
{
	key_serial_t keyring;

	if (argc != 2)
		format();

	keyring = get_key_id(argv[1]);

	if (keyctl_clear(keyring) < 0)
		error("keyctl_clear");

	return 0;

} /* end act_keyctl_clear() */

/*****************************************************************************/
/*
 * link a key to a keyring
 */
static int act_keyctl_link(int argc, char *argv[])
{
	key_serial_t keyring, key;

	if (argc != 3)
		format();

	key = get_key_id(argv[1]);
	keyring = get_key_id(argv[2]);

	if (keyctl_link(key, keyring) < 0)
		error("keyctl_link");

	return 0;

} /* end act_keyctl_link() */

/*
 * Attempt to unlink a key matching the ID
 */
static int act_keyctl_unlink_func(key_serial_t parent, key_serial_t key,
				  char *desc, int desc_len, void *data)
{
	key_serial_t *target = data;

	if (key == *target)
		return keyctl_unlink(key, parent) < 0 ? 0 : 1;
	return 0;
}

/*
 * Unlink a key from a keyring or from the session keyring tree.
 */
static int act_keyctl_unlink(int argc, char *argv[])
{
	key_serial_t keyring, key;
	int n;

	if (argc != 2 && argc != 3)
		format();

	key = get_key_id(argv[1]);

	if (argc == 3) {
		keyring = get_key_id(argv[2]);
		if (keyctl_unlink(key, keyring) < 0)
			error("keyctl_unlink");
	} else {
		n = recursive_session_key_scan(act_keyctl_unlink_func, &key);
		printf("%d links removed\n", n);
	}

	return 0;
}

/*****************************************************************************/
/*
 * search a keyring for a key
 */
static int act_keyctl_search(int argc, char *argv[])
{
	key_serial_t keyring, dest;
	int ret;

	if (argc != 4 && argc != 5)
		format();

	keyring = get_key_id(argv[1]);

	dest = 0;
	if (argc == 5)
		dest = get_key_id(argv[4]);

	ret = keyctl_search(keyring, argv[2], argv[3], dest);
	if (ret < 0)
		error("keyctl_search");

	/* print the ID of the key we found */
	printf("%d\n", ret);
	return 0;

} /* end act_keyctl_search() */

/*****************************************************************************/
/*
 * read a key
 */
static int act_keyctl_read(int argc, char *argv[])
{
	key_serial_t key;
	void *buffer;
	char *p;
	int ret, sep, col;

	if (argc != 2)
		format();

	key = get_key_id(argv[1]);

	/* read the key payload data */
	ret = keyctl_read_alloc(key, &buffer);
	if (ret < 0)
		error("keyctl_read_alloc");

	if (ret == 0) {
		printf("No data in key\n");
		return 0;
	}

	/* hexdump the contents */
	printf("%u bytes of data in key:\n", ret);

	sep = 0;
	col = 0;
	p = buffer;

	do {
		if (sep) {
			putchar(sep);
			sep = 0;
		}

		printf("%02hhx", *p);
		p++;

		col++;
		if (col % 32 == 0)
			sep = '\n';
		else if (col % 4 == 0)
			sep = ' ';

	} while (--ret > 0);

	printf("\n");
	return 0;

} /* end act_keyctl_read() */

/*****************************************************************************/
/*
 * read a key and dump raw to stdout
 */
static int act_keyctl_pipe(int argc, char *argv[])
{
	key_serial_t key;
	void *buffer;
	int ret;

	if (argc != 2)
		format();

	key = get_key_id(argv[1]);

	/* read the key payload data */
	ret = keyctl_read_alloc(key, &buffer);
	if (ret < 0)
		error("keyctl_read_alloc");

	if (ret > 0 && write(1, buffer, ret) < 0)
		error("write");
	return 0;

} /* end act_keyctl_pipe() */

/*****************************************************************************/
/*
 * read a key and dump to stdout in printable form
 */
static int act_keyctl_print(int argc, char *argv[])
{
	key_serial_t key;
	void *buffer;
	char *p;
	int loop, ret;

	if (argc != 2)
		format();

	key = get_key_id(argv[1]);

	/* read the key payload data */
	ret = keyctl_read_alloc(key, &buffer);
	if (ret < 0)
		error("keyctl_read_alloc");

	/* see if it's printable */
	p = buffer;
	for (loop = ret; loop > 0; loop--, p++)
		if (!isprint(*p))
			goto not_printable;

	/* it is */
	printf("%s\n", (char *) buffer);
	return 0;

not_printable:
	/* it isn't */
	printf(":hex:");
	p = buffer;
	for (loop = ret; loop > 0; loop--, p++)
		printf("%02hhx", *p);
	printf("\n");
	return 0;

} /* end act_keyctl_print() */

/*****************************************************************************/
/*
 * list a keyring
 */
static int act_keyctl_list(int argc, char *argv[])
{
	key_serial_t keyring, key, *pk;
	key_perm_t perm;
	void *keylist;
	char *buffer, pretty_mask[9];
	uid_t uid;
	gid_t gid;
	int count, tlen, dpos, n, ret;

	if (argc != 2)
		format();

	keyring = get_key_id(argv[1]);

	/* read the key payload data */
	count = keyctl_read_alloc(keyring, &keylist);
	if (count < 0)
		error("keyctl_read_alloc");

	count /= sizeof(key_serial_t);

	if (count == 0) {
		printf("keyring is empty\n");
		return 0;
	}

	/* list the keys in the keyring */
	if (count == 1)
		printf("1 key in keyring:\n");
	else
		printf("%u keys in keyring:\n", count);

	pk = keylist;
	do {
		key = *pk++;

		ret = keyctl_describe_alloc(key, &buffer);
		if (ret < 0) {
			printf("%9d: key inaccessible (%m)\n", key);
			continue;
		}

		uid = 0;
		gid = 0;
		perm = 0;

		tlen = -1;
		dpos = -1;

		n = sscanf((char *) buffer, "%*[^;]%n;%d;%d;%x;%n",
			   &tlen, &uid, &gid, &perm, &dpos);
		if (n != 3) {
			fprintf(stderr, "Unparseable description obtained for key %d\n", key);
			exit(3);
		}

		calc_perms(pretty_mask, perm, uid, gid);

		printf("%9d: %s %5d %5d %*.*s: %s\n",
		       key,
		       pretty_mask,
		       uid, gid,
		       tlen, tlen, buffer,
		       buffer + dpos);

		free(buffer);

	} while (--count);

	return 0;

} /* end act_keyctl_list() */

/*****************************************************************************/
/*
 * produce a raw list of a keyring
 */
static int act_keyctl_rlist(int argc, char *argv[])
{
	key_serial_t keyring, key, *pk;
	void *keylist;
	int count;

	if (argc != 2)
		format();

	keyring = get_key_id(argv[1]);

	/* read the key payload data */
	count = keyctl_read_alloc(keyring, &keylist);
	if (count < 0)
		error("keyctl_read_alloc");

	count /= sizeof(key_serial_t);

	/* list the keys in the keyring */
	if (count <= 0) {
		printf("\n");
	}
	else {
		pk = keylist;
		for (; count > 0; count--) {
			key = *pk++;
			printf("%d%c", key, count == 1 ? '\n' : ' ');
		}
	}

	return 0;

} /* end act_keyctl_rlist() */

/*****************************************************************************/
/*
 * describe a key
 */
static int act_keyctl_describe(int argc, char *argv[])
{
	key_serial_t key;
	key_perm_t perm;
	char *buffer;
	uid_t uid;
	gid_t gid;
	int tlen, dpos, n, ret;

	if (argc != 2)
		format();

	key = get_key_id(argv[1]);

	/* get key description */
	ret = keyctl_describe_alloc(key, &buffer);
	if (ret < 0)
		error("keyctl_describe");

	/* parse it */
	uid = 0;
	gid = 0;
	perm = 0;

	tlen = -1;
	dpos = -1;

	n = sscanf(buffer, "%*[^;]%n;%d;%d;%x;%n",
		   &tlen, &uid, &gid, &perm, &dpos);
	if (n != 3) {
		fprintf(stderr, "Unparseable description obtained for key %d\n", key);
		exit(3);
	}

	/* display it */
	printf("%9d:"
	       " %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c"
	       " %5d %5d %*.*s: %s\n",
	       key,
	       perm & KEY_POS_SETATTR	? 'a' : '-',
	       perm & KEY_POS_LINK	? 'l' : '-',
	       perm & KEY_POS_SEARCH	? 's' : '-',
	       perm & KEY_POS_WRITE	? 'w' : '-',
	       perm & KEY_POS_READ	? 'r' : '-',
	       perm & KEY_POS_VIEW	? 'v' : '-',

	       perm & KEY_USR_SETATTR	? 'a' : '-',
	       perm & KEY_USR_LINK	? 'l' : '-',
	       perm & KEY_USR_SEARCH	? 's' : '-',
	       perm & KEY_USR_WRITE	? 'w' : '-',
	       perm & KEY_USR_READ	? 'r' : '-',
	       perm & KEY_USR_VIEW	? 'v' : '-',

	       perm & KEY_GRP_SETATTR	? 'a' : '-',
	       perm & KEY_GRP_LINK	? 'l' : '-',
	       perm & KEY_GRP_SEARCH	? 's' : '-',
	       perm & KEY_GRP_WRITE	? 'w' : '-',
	       perm & KEY_GRP_READ	? 'r' : '-',
	       perm & KEY_GRP_VIEW	? 'v' : '-',

	       perm & KEY_OTH_SETATTR	? 'a' : '-',
	       perm & KEY_OTH_LINK	? 'l' : '-',
	       perm & KEY_OTH_SEARCH	? 's' : '-',
	       perm & KEY_OTH_WRITE	? 'w' : '-',
	       perm & KEY_OTH_READ	? 'r' : '-',
	       perm & KEY_OTH_VIEW	? 'v' : '-',
	       uid, gid,
	       tlen, tlen, buffer,
	       buffer + dpos);

	return 0;

} /* end act_keyctl_describe() */

/*****************************************************************************/
/*
 * get raw key description
 */
static int act_keyctl_rdescribe(int argc, char *argv[])
{
	key_serial_t key;
	char *buffer, *q;
	int ret;

	if (argc != 2 && argc != 3)
		format();
	if (argc == 3 && !argv[2][0])
		format();

	key = get_key_id(argv[1]);

	/* get key description */
	ret = keyctl_describe_alloc(key, &buffer);
	if (ret < 0)
		error("keyctl_describe");

	/* replace semicolon separators with requested alternative */
	if (argc == 3) {
		for (q = buffer; *q; q++)
			if (*q == ';')
				*q = argv[2][0];
	}

	/* display raw description */
	printf("%s\n", buffer);
	return 0;

} /* end act_keyctl_rdescribe() */

/*****************************************************************************/
/*
 * change a key's ownership
 */
static int act_keyctl_chown(int argc, char *argv[])
{
	key_serial_t key;
	uid_t uid;
	char *q;

	if (argc != 3)
		format();

	key = get_key_id(argv[1]);

	uid = strtoul(argv[2], &q, 0);
	if (*q) {
		fprintf(stderr, "Unparsable uid: '%s'\n", argv[2]);
		exit(2);
	}

	if (keyctl_chown(key, uid, -1) < 0)
		error("keyctl_chown");

	return 0;

} /* end act_keyctl_chown() */

/*****************************************************************************/
/*
 * change a key's group ownership
 */
static int act_keyctl_chgrp(int argc, char *argv[])
{
	key_serial_t key;
	gid_t gid;
	char *q;

	if (argc != 3)
		format();

	key = get_key_id(argv[1]);

	gid = strtoul(argv[2], &q, 0);
	if (*q) {
		fprintf(stderr, "Unparsable gid: '%s'\n", argv[2]);
		exit(2);
	}

	if (keyctl_chown(key, -1, gid) < 0)
		error("keyctl_chown");

	return 0;

} /* end act_keyctl_chgrp() */

/*****************************************************************************/
/*
 * set the permissions on a key
 */
static int act_keyctl_setperm(int argc, char *argv[])
{
	key_serial_t key;
	key_perm_t perm;
	char *q;

	if (argc != 3)
		format();

	key = get_key_id(argv[1]);
	perm = strtoul(argv[2], &q, 0);
	if (*q) {
		fprintf(stderr, "Unparsable permissions: '%s'\n", argv[2]);
		exit(2);
	}

	if (keyctl_setperm(key, perm) < 0)
		error("keyctl_setperm");

	return 0;

} /* end act_keyctl_setperm() */

/*****************************************************************************/
/*
 * start a process in a new session
 */
static int act_keyctl_session(int argc, char *argv[])
{
	char *p, *q;
	int ret;

	argv++;
	argc--;

	/* no extra arguments signifies a standard shell in an anonymous
	 * session */
	p = NULL;
	if (argc != 0) {
		/* a dash signifies an anonymous session */
		p = *argv;
		if (strcmp(p, "-") == 0)
			p = NULL;

		argv++;
		argc--;
	}

	/* create a new session keyring */
	ret = keyctl_join_session_keyring(p);
	if (ret < 0)
		error("keyctl_join_session_keyring");

	fprintf(stderr, "Joined session keyring: %d\n", ret);

	/* run the standard shell if no arguments */
	if (argc == 0) {
		q = getenv("SHELL");
		if (!q)
			q = "/bin/sh";
		execl(q, q, NULL);
		error(q);
	}

	/* run the command specified */
	execvp(argv[0], argv);
	error(argv[0]);

} /* end act_keyctl_session() */

/*****************************************************************************/
/*
 * instantiate a key that's under construction
 */
static int act_keyctl_instantiate(int argc, char *argv[])
{
	key_serial_t key, dest;

	if (argc != 4)
		format();

	key = get_key_id(argv[1]);
	dest = get_key_id(argv[3]);

	if (keyctl_instantiate(key, argv[2], strlen(argv[2]), dest) < 0)
		error("keyctl_instantiate");

	return 0;

} /* end act_keyctl_instantiate() */

/*****************************************************************************/
/*
 * instantiate a key, reading from a pipe
 */
static int act_keyctl_pinstantiate(int argc, char *argv[])
{
	key_serial_t key, dest;
	size_t datalen;
	void *data;

	if (argc != 3)
		format();

	key = get_key_id(argv[1]);
	dest = get_key_id(argv[2]);
	data = grab_stdin(&datalen);

	if (keyctl_instantiate(key, data, datalen, dest) < 0)
		error("keyctl_instantiate");

	return 0;

} /* end act_keyctl_pinstantiate() */

/*****************************************************************************/
/*
 * negate a key that's under construction
 */
static int act_keyctl_negate(int argc, char *argv[])
{
	unsigned long timeout;
	key_serial_t key, dest;
	char *q;

	if (argc != 4)
		format();

	key = get_key_id(argv[1]);

	timeout = strtoul(argv[2], &q, 10);
	if (*q) {
		fprintf(stderr, "Unparsable timeout: '%s'\n", argv[2]);
		exit(2);
	}

	dest = get_key_id(argv[3]);

	if (keyctl_negate(key, timeout, dest) < 0)
		error("keyctl_negate");

	return 0;

} /* end act_keyctl_negate() */

/*****************************************************************************/
/*
 * set a key's timeout
 */
static int act_keyctl_timeout(int argc, char *argv[])
{
	unsigned long timeout;
	key_serial_t key;
	char *q;

	if (argc != 3)
		format();

	key = get_key_id(argv[1]);

	timeout = strtoul(argv[2], &q, 10);
	if (*q) {
		fprintf(stderr, "Unparsable timeout: '%s'\n", argv[2]);
		exit(2);
	}

	if (keyctl_set_timeout(key, timeout) < 0)
		error("keyctl_set_timeout");

	return 0;

} /* end act_keyctl_timeout() */

/*****************************************************************************/
/*
 * get a key's security label
 */
static int act_keyctl_security(int argc, char *argv[])
{
	key_serial_t key;
	char *buffer;
	int ret;

	if (argc != 2)
		format();

	key = get_key_id(argv[1]);

	/* get key description */
	ret = keyctl_get_security_alloc(key, &buffer);
	if (ret < 0)
		error("keyctl_getsecurity");

	printf("%s\n", buffer);
	return 0;
}

/*****************************************************************************/
/*
 * install a new session keyring on the parent process
 */
static int act_keyctl_new_session(int argc, char *argv[])
{
	key_serial_t keyring;

	if (argc != 1)
		format();

	if (keyctl_join_session_keyring(NULL) < 0)
		error("keyctl_join_session_keyring");

	if (keyctl_session_to_parent() < 0)
		error("keyctl_session_to_parent");

	keyring = keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0);
	if (keyring < 0)
		error("keyctl_get_keyring_ID");

	/* print the resulting key ID */
	printf("%d\n", keyring);
	return 0;
}

/*****************************************************************************/
/*
 * reject a key that's under construction
 */
static int act_keyctl_reject(int argc, char *argv[])
{
	unsigned long timeout;
	key_serial_t key, dest;
	unsigned long rejerr;
	char *q;

	if (argc != 5)
		format();

	key = get_key_id(argv[1]);

	timeout = strtoul(argv[2], &q, 10);
	if (*q) {
		fprintf(stderr, "Unparsable timeout: '%s'\n", argv[2]);
		exit(2);
	}

	if (strcmp(argv[3], "rejected") == 0) {
		rejerr = EKEYREJECTED;
	} else if (strcmp(argv[3], "revoked") == 0) {
		rejerr = EKEYREVOKED;
	} else if (strcmp(argv[3], "expired") == 0) {
		rejerr = EKEYEXPIRED;
	} else {
		rejerr = strtoul(argv[3], &q, 10);
		if (*q) {
			fprintf(stderr, "Unparsable error: '%s'\n", argv[3]);
			exit(2);
		}
	}

	dest = get_key_id(argv[4]);

	if (keyctl_reject(key, timeout, rejerr, dest) < 0)
		error("keyctl_negate");

	return 0;
}

/*
 * Attempt to unlink a key if we can't read it for reasons other than we don't
 * have permission
 */
static int act_keyctl_reap_func(key_serial_t parent, key_serial_t key,
				char *desc, int desc_len, void *data)
{
	if (desc_len < 0 && errno != EACCES) {
		if (verbose)
			printf("Reap %d", key);
		if (keyctl_unlink(key, parent) < 0) {
			if (verbose)
				printf("... failed %m\n");
			return 0;
		} else {
			if (verbose)
				printf("\n");
			return 1;
		};
	}
	return 0;
}

/*
 * Reap the dead keys from the session keyring tree
 */
static int act_keyctl_reap(int argc, char *argv[])
{
	int n;

	if (argc > 1 && strcmp(argv[1], "-v") == 0) {
		verbose = 1;
		argc--;
		argv++;
	}

	if (argc != 1)
		format();

	n = recursive_session_key_scan(act_keyctl_reap_func, NULL);
	printf("%d keys reaped\n", n);
	return 0;
}

struct purge_data {
	const char	*type;
	const char	*desc;
	size_t		desc_len;
	size_t		type_len;
	char		prefix_match;
	char		case_indep;
};

/*
 * Attempt to unlink a key matching the type
 */
static int act_keyctl_purge_type_func(key_serial_t parent, key_serial_t key,
				      char *raw, int raw_len, void *data)
{
	const struct purge_data *purge = data;
	char *p, *type;

	if (parent == 0 || !raw)
		return 0;

	/* type is everything before the first semicolon */
	type = raw;
	p = memchr(raw, ';', raw_len);
	if (!p)
		return 0;
	*p = 0;
	if (strcmp(type, purge->type) != 0)
		return 0;

	return keyctl_unlink(key, parent) < 0 ? 0 : 1;
}

/*
 * Attempt to unlink a key matching the type and description literally
 */
static int act_keyctl_purge_literal_func(key_serial_t parent, key_serial_t key,
					 char *raw, int raw_len, void *data)
{
	const struct purge_data *purge = data;
	size_t tlen;
	char *p, *type, *desc;

	if (parent == 0 || !raw)
		return 0;

	/* type is everything before the first semicolon */
	type = raw;
	p = memchr(type, ';', raw_len);
	if (!p)
		return 0;

	tlen = p - type;
	if (tlen != purge->type_len)
		return 0;
	if (memcmp(type, purge->type, tlen) != 0)
		return 0;

	/* description is everything after the last semicolon */
	p++;
	desc = memrchr(p, ';', raw + raw_len - p);
	if (!desc)
		return 0;
	desc++;

	if (purge->prefix_match) {
		if (raw_len - (desc - raw) < purge->desc_len)
			return 0;
	} else {
		if (raw_len - (desc - raw) != purge->desc_len)
			return 0;
	}

	if (purge->case_indep) {
		if (strncasecmp(purge->desc, desc, purge->desc_len) != 0)
			return 0;
	} else {
		if (memcmp(purge->desc, desc, purge->desc_len) != 0)
			return 0;
	}

	printf("%*.*s '%s'\n", (int)tlen, (int)tlen, type, desc);

	return keyctl_unlink(key, parent) < 0 ? 0 : 1;
}

/*
 * Attempt to unlink a key matching the type and description literally
 */
static int act_keyctl_purge_search_func(key_serial_t parent, key_serial_t keyring,
					char *raw, int raw_len, void *data)
{
	const struct purge_data *purge = data;
	key_serial_t key;
	int kcount = 0;

	if (!raw || memcmp(raw, "keyring;", 8) != 0)
		return 0;

	for (;;) {
		key = keyctl_search(keyring, purge->type, purge->desc, 0);
		if (keyctl_unlink(key, keyring) < 0)
			return kcount;
		kcount++;
	}
	return kcount;
}

/*
 * Purge matching keys from a keyring
 */
static int act_keyctl_purge(int argc, char *argv[])
{
	recursive_key_scanner_t func;
	struct purge_data purge = {
		.prefix_match	= 0,
		.case_indep	= 0,
	};
	int n = 0, search_mode = 0;

	argc--;
	argv++;
	while (argc > 0 && argv[0][0] == '-') {
		if (argv[0][1] == 's')
			search_mode = 1;
		else if (argv[0][1] == 'p')
			purge.prefix_match = 1;
		else if (argv[0][1] == 'i')
			purge.case_indep = 1;
		else
			format();
		argc--;
		argv++;
	}

	if (argc < 1)
		format();

	purge.type	= argv[0];
	purge.desc	= argv[1];
	purge.type_len	= strlen(purge.type);
	purge.desc_len	= purge.desc ? strlen(purge.desc) : 0;

	if (search_mode == 1) {
		if (argc != 2 || purge.prefix_match || purge.case_indep)
			format();
		/* purge all keys of a specific type and description, according
		 * to the kernel's comparator */
		func = act_keyctl_purge_search_func;
	} else if (argc == 1) {
		if (purge.prefix_match || purge.case_indep)
			format();
		/* purge all keys of a specific type */
		func = act_keyctl_purge_type_func;
	} else if (argc == 2) {
		/* purge all keys of a specific type with literally matching
		 * description */
		func = act_keyctl_purge_literal_func;
	} else {
		format();
	}

	n = recursive_session_key_scan(func, &purge);
	printf("purged %d keys\n", n);
	return 0;
}

/*****************************************************************************/
/*
 * parse a key identifier
 */
static key_serial_t get_key_id(const char *arg)
{
	key_serial_t id;
	char *end;

	/* handle a special keyring name */
	if (arg[0] == '@') {
		if (strcmp(arg, "@t" ) == 0) return KEY_SPEC_THREAD_KEYRING;
		if (strcmp(arg, "@p" ) == 0) return KEY_SPEC_PROCESS_KEYRING;
		if (strcmp(arg, "@s" ) == 0) return KEY_SPEC_SESSION_KEYRING;
		if (strcmp(arg, "@u" ) == 0) return KEY_SPEC_USER_KEYRING;
		if (strcmp(arg, "@us") == 0) return KEY_SPEC_USER_SESSION_KEYRING;
		if (strcmp(arg, "@g" ) == 0) return KEY_SPEC_GROUP_KEYRING;
		if (strcmp(arg, "@a" ) == 0) return KEY_SPEC_REQKEY_AUTH_KEY;

		fprintf(stderr, "Unknown special key: '%s'\n", arg);
		exit(2);
	}

	/* handle a numeric key ID */
	id = strtoul(arg, &end, 0);
	if (*end) {
		fprintf(stderr, "Unparsable key: '%s'\n", arg);
		exit(2);
	}

	return id;

} /* end get_key_id() */

/*****************************************************************************/
/*
 * recursively display a key/keyring tree
 */
static int dump_key_tree_aux(key_serial_t key, int depth, int more, int hex_key_IDs)
{
	static char dumpindent[64];
	key_serial_t *pk;
	key_perm_t perm;
	size_t ringlen, desclen;
	void *payload;
	char *desc, type[255], pretty_mask[9];
	int uid, gid, ret, n, dpos, rdepth, kcount = 0;

	if (depth > 8)
		return 0;

	/* find out how big this key's description is */
	ret = keyctl_describe(key, NULL, 0);
	if (ret < 0) {
		printf("%d: key inaccessible (%m)\n", key);
		return 0;
	}
	desclen = ret + 1;

	desc = malloc(desclen);
	if (!desc)
		error("malloc");

	/* read the description */
	ret = keyctl_describe(key, desc, desclen);
	if (ret < 0) {
		printf("%d: key inaccessible (%m)\n", key);
		free(desc);
		return 0;
	}

	desclen = ret < desclen ? ret : desclen;

	desc[desclen] = 0;

	/* parse */
	type[0] = 0;
	uid = 0;
	gid = 0;
	perm = 0;

	n = sscanf(desc, "%[^;];%d;%d;%x;%n",
		   type, &uid, &gid, &perm, &dpos);

	if (n != 4) {
		fprintf(stderr, "Unparseable description obtained for key %d\n", key);
		exit(3);
	}

	/* and print */
	calc_perms(pretty_mask, perm, uid, gid);

	if (hex_key_IDs)
		printf("0x%08x %s  %5d %5d  %s%s%s: %s\n",
		       key,
		       pretty_mask,
		       uid, gid,
		       dumpindent,
		       depth > 0 ? "\\_ " : "",
		       type, desc + dpos);
	else
		printf("%10d %s  %5d %5d  %s%s%s: %s\n",
		       key,
		       pretty_mask,
		       uid, gid,
		       dumpindent,
		       depth > 0 ? "\\_ " : "",
		       type, desc + dpos);

	/* if it's a keyring then we're going to want to recursively
	 * display it if we can */
	if (strcmp(type, "keyring") == 0) {
		/* find out how big the keyring is */
		ret = keyctl_read(key, NULL, 0);
		if (ret < 0)
			error("keyctl_read");
		if (ret == 0)
			return 0;
		ringlen = ret;

		/* read its contents */
		payload = malloc(ringlen);
		if (!payload)
			error("malloc");

		ret = keyctl_read(key, payload, ringlen);
		if (ret < 0)
			error("keyctl_read");

		ringlen = ret < ringlen ? ret : ringlen;
		kcount = ringlen / sizeof(key_serial_t);

		/* walk the keyring */
		pk = payload;
		do {
			key = *pk++;

			/* recurse into nexted keyrings */
			if (strcmp(type, "keyring") == 0) {
				if (depth == 0) {
					rdepth = depth;
					dumpindent[rdepth++] = ' ';
					dumpindent[rdepth] = 0;
				}
				else {
					rdepth = depth;
					dumpindent[rdepth++] = ' ';
					dumpindent[rdepth++] = ' ';
					dumpindent[rdepth++] = ' ';
					dumpindent[rdepth++] = ' ';
					dumpindent[rdepth] = 0;
				}

				if (more)
					dumpindent[depth + 0] = '|';

				kcount += dump_key_tree_aux(key,
							    rdepth,
							    ringlen - 4 >= sizeof(key_serial_t),
							    hex_key_IDs);
			}

		} while (ringlen -= 4, ringlen >= sizeof(key_serial_t));

		free(payload);
	}

	free(desc);
	return kcount;

} /* end dump_key_tree_aux() */

/*****************************************************************************/
/*
 * recursively list a keyring's contents
 */
static int dump_key_tree(key_serial_t keyring, const char *name, int hex_key_IDs)
{
	printf("%s\n", name);

	keyring = keyctl_get_keyring_ID(keyring, 0);
	if (keyring == -1)
		error("Unable to dump key");

	return dump_key_tree_aux(keyring, 0, 0, hex_key_IDs);

} /* end dump_key_tree() */
