/* 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 {
	void (*action)(int argc, char *argv[]) __attribute__((noreturn));
	const char	*name;
	const char	*format;
};

#define nr __attribute__((noreturn))

static nr void act_keyctl___version(int argc, char *argv[]);
static nr void act_keyctl_show(int argc, char *argv[]);
static nr void act_keyctl_add(int argc, char *argv[]);
static nr void act_keyctl_padd(int argc, char *argv[]);
static nr void act_keyctl_request(int argc, char *argv[]);
static nr void act_keyctl_request2(int argc, char *argv[]);
static nr void act_keyctl_prequest2(int argc, char *argv[]);
static nr void act_keyctl_update(int argc, char *argv[]);
static nr void act_keyctl_pupdate(int argc, char *argv[]);
static nr void act_keyctl_newring(int argc, char *argv[]);
static nr void act_keyctl_revoke(int argc, char *argv[]);
static nr void act_keyctl_clear(int argc, char *argv[]);
static nr void act_keyctl_link(int argc, char *argv[]);
static nr void act_keyctl_unlink(int argc, char *argv[]);
static nr void act_keyctl_search(int argc, char *argv[]);
static nr void act_keyctl_read(int argc, char *argv[]);
static nr void act_keyctl_pipe(int argc, char *argv[]);
static nr void act_keyctl_print(int argc, char *argv[]);
static nr void act_keyctl_list(int argc, char *argv[]);
static nr void act_keyctl_rlist(int argc, char *argv[]);
static nr void act_keyctl_describe(int argc, char *argv[]);
static nr void act_keyctl_rdescribe(int argc, char *argv[]);
static nr void act_keyctl_chown(int argc, char *argv[]);
static nr void act_keyctl_chgrp(int argc, char *argv[]);
static nr void act_keyctl_setperm(int argc, char *argv[]);
static nr void act_keyctl_session(int argc, char *argv[]);
static nr void act_keyctl_instantiate(int argc, char *argv[]);
static nr void act_keyctl_pinstantiate(int argc, char *argv[]);
static nr void act_keyctl_negate(int argc, char *argv[]);
static nr void act_keyctl_timeout(int argc, char *argv[]);
static nr void act_keyctl_security(int argc, char *argv[]);
static nr void act_keyctl_new_session(int argc, char *argv[]);
static nr void act_keyctl_reject(int argc, char *argv[]);
static nr void act_keyctl_reap(int argc, char *argv[]);
static nr void act_keyctl_purge(int argc, char *argv[]);
static nr void act_keyctl_invalidate(int argc, char *argv[]);
static nr void act_keyctl_get_persistent(int argc, char *argv[]);
static nr void act_keyctl_dh_compute(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_dh_compute, "dh_compute",	"<private> <prime> <base>" },
	{ act_keyctl_instantiate, "instantiate","<key> <data> <keyring>" },
	{ act_keyctl_invalidate,"invalidate",	"<key>" },
	{ act_keyctl_get_persistent, "get_persistent", "<keyring> [<uid>]" },
	{ 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(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 (strlen(cmd->name) > n)
			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);
	}

	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 void act_keyctl___version(int argc, char *argv[])
{
	printf("keyctl from %s (Built %s)\n",
	       keyutils_version_string, keyutils_build_string);
	exit(0);
}

/*****************************************************************************/
/*
 * grab data from stdin
 */
static char *grab_stdin(size_t *_size)
{
	static char input[1024 * 1024 + 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() */

/*
 * Load the groups list and grab the process's UID and GID.
 */
static void grab_creds(void)
{
	static int inited;

	if (inited)
		return;
	inited = 1;

	/* 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");
}

/*****************************************************************************/
/*
 * 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;

	grab_creds();

	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 void 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);
	exit(0);

} /* end act_keyctl_show() */

/*****************************************************************************/
/*
 * add a key
 */
static void 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);
	exit(0);

} /* end act_keyctl_add() */

/*****************************************************************************/
/*
 * add a key, reading from a pipe
 */
static void 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);
	exit(0);

} /* end act_keyctl_padd() */

/*****************************************************************************/
/*
 * request a key
 */
static void 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);
	exit(0);

} /* end act_keyctl_request() */

/*****************************************************************************/
/*
 * request a key, with recourse to /sbin/request-key
 */
static void 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);
	exit(0);

} /* end act_keyctl_request2() */

/*****************************************************************************/
/*
 * request a key, with recourse to /sbin/request-key, reading the callout info
 * from a pipe
 */
static void 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;

	act_keyctl_request2(argc + 1, args);

} /* end act_keyctl_prequest2() */

/*****************************************************************************/
/*
 * update a key
 */
static void 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");

	exit(0);

} /* end act_keyctl_update() */

/*****************************************************************************/
/*
 * update a key, reading from a pipe
 */
static void 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");

	exit(0);

} /* end act_keyctl_pupdate() */

/*****************************************************************************/
/*
 * create a new keyring
 */
static void 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);
	exit(0);

} /* end act_keyctl_newring() */

/*****************************************************************************/
/*
 * revoke a key
 */
static void 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");

	exit(0);

} /* end act_keyctl_revoke() */

/*****************************************************************************/
/*
 * clear a keyring
 */
static void 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");

	exit(0);

} /* end act_keyctl_clear() */

/*****************************************************************************/
/*
 * link a key to a keyring
 */
static void 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");

	exit(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 void 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);
	}

	exit(0);
}

/*****************************************************************************/
/*
 * search a keyring for a key
 */
static void 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);
	exit(0);

} /* end act_keyctl_search() */

/*****************************************************************************/
/*
 * read a key
 */
static void 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");
		exit(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");
	exit(0);

} /* end act_keyctl_read() */

/*****************************************************************************/
/*
 * read a key and dump raw to stdout
 */
static void 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");
	exit(0);

} /* end act_keyctl_pipe() */

/*****************************************************************************/
/*
 * read a key and dump to stdout in printable form
 */
static void 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);
	exit(0);

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

} /* end act_keyctl_print() */

/*****************************************************************************/
/*
 * list a keyring
 */
static void 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");
		exit(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);

	exit(0);

} /* end act_keyctl_list() */

/*****************************************************************************/
/*
 * produce a raw list of a keyring
 */
static void 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' : ' ');
		}
	}

	exit(0);

} /* end act_keyctl_rlist() */

/*****************************************************************************/
/*
 * describe a key
 */
static void 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);

	exit(0);

} /* end act_keyctl_describe() */

/*****************************************************************************/
/*
 * get raw key description
 */
static void 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);
	exit(0);

} /* end act_keyctl_rdescribe() */

/*****************************************************************************/
/*
 * change a key's ownership
 */
static void 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");

	exit(0);

} /* end act_keyctl_chown() */

/*****************************************************************************/
/*
 * change a key's group ownership
 */
static void 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");

	exit(0);

} /* end act_keyctl_chgrp() */

/*****************************************************************************/
/*
 * set the permissions on a key
 */
static void 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");

	exit(0);

} /* end act_keyctl_setperm() */

/*****************************************************************************/
/*
 * start a process in a new session
 */
static void 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 void 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");

	exit(0);

} /* end act_keyctl_instantiate() */

/*****************************************************************************/
/*
 * instantiate a key, reading from a pipe
 */
static void 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");

	exit(0);

} /* end act_keyctl_pinstantiate() */

/*****************************************************************************/
/*
 * negate a key that's under construction
 */
static void 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");

	exit(0);

} /* end act_keyctl_negate() */

/*****************************************************************************/
/*
 * set a key's timeout
 */
static void 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");

	exit(0);

} /* end act_keyctl_timeout() */

/*****************************************************************************/
/*
 * get a key's security label
 */
static void 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);
	exit(0);
}

/*****************************************************************************/
/*
 * install a new session keyring on the parent process
 */
static void 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);
	exit(0);
}

/*****************************************************************************/
/*
 * reject a key that's under construction
 */
static void 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");

	exit(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 void 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);
	exit(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 void 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);
	exit(0);
}

/*****************************************************************************/
/*
 * Invalidate a key
 */
static void act_keyctl_invalidate(int argc, char *argv[])
{
	key_serial_t key;

	if (argc != 2)
		format();

	key = get_key_id(argv[1]);

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

	exit(0);
}

/*****************************************************************************/
/*
 * Get the per-UID persistent keyring
 */
static void act_keyctl_get_persistent(int argc, char *argv[])
{
	key_serial_t dest, ret;
	uid_t uid = -1;
	char *q;

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

	dest = get_key_id(argv[1]);

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

	ret = keyctl_get_persistent(uid, dest);
	if (ret < 0)
		error("keyctl_get_persistent");

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

/*****************************************************************************/
/*
 * Perform Diffie-Hellman computation
 */
static void act_keyctl_dh_compute(int argc, char *argv[])
{
	key_serial_t priv, prime, base;
	void *buffer;
	char *p;
	int ret, sep, col;

	if (argc != 4)
		format();

	priv = get_key_id(argv[1]);
	prime = get_key_id(argv[2]);
	base = get_key_id(argv[3]);

	ret = keyctl_dh_compute_alloc(priv, prime, base, &buffer);
	if (ret < 0)
		error("keyctl_dh_compute_alloc");

	/* hexdump the contents */
	printf("%u bytes of data in result:\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");
	exit(0);
}

/*****************************************************************************/
/*
 * parse a key identifier
 */
static key_serial_t get_key_id(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 lookup-by-name request "%<type>:<desc>", eg: "%keyring:_ses" */
	if (arg[0] == '%') {
		char *type;

		arg++;
		if (!*arg)
			goto incorrect_key_by_name_spec;

		if (*arg == ':') {
			type = "keyring";
			arg++;
		} else {
			type = arg;
			arg = strchr(arg, ':');
			if (!arg)
				goto incorrect_key_by_name_spec;
			*(arg++) = '\0';
		}

		if (!*arg)
			goto incorrect_key_by_name_spec;

		id = find_key_by_type_and_desc(type, arg, 0);
		if (id == -1) {
			fprintf(stderr, "Can't find '%s:%s'\n", type, arg);
			exit(1);
		}
		return id;
	}

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

	return id;

incorrect_key_by_name_spec:
	fprintf(stderr, "Incorrect key-by-name spec\n");
	exit(2);

} /* 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;
	void *payload;
	char *desc, type[255], pretty_mask[9];
	int uid, gid, ret, n, dpos, rdepth, kcount = 0;

	if (depth > 8 * 4)
		return 0;

	/* read the description */
	ret = keyctl_describe_alloc(key, &desc);
	if (ret < 0) {
		printf("%d: key inaccessible (%m)\n", key);
		return 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);

	free(desc);

	/* 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);
	}

	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() */
