/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */

#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <net/ip.h>

#include <crypto/2crypto.h>
#include <crypto/2hmac.h>
#include <crypto/2id.h>
#include <crypto/2sha.h>

#include <ctype.h>

enum {
	Hashlen = VB2_MAX_DIGEST_SIZE * 2,
	Maxhash = 256,
};

/*
 *  if a process knows cap->cap, it can change user
 *  to capabilty->user.
 */
struct Caphash {
	struct Caphash *next;
	char hash[Hashlen + 1];
};

struct {
	qlock_t qlock;
	struct Caphash *first;
	int nhash;
} capalloc;

enum {
	Qdir,
	Qhash,
	Quse,
};

/* caphash must be last */
struct dirtab capdir[] = {
	{".",       {Qdir, 0, QTDIR}, 0, DMDIR | 0500},
	{"capuse",  {Quse},           0, 0222,},
	{"caphash", {Qhash},          0, 0200,},
};
int ncapdir = ARRAY_SIZE(capdir);

static void capinit(void)
{
	qlock_init(&capalloc.qlock);
}

static struct chan *capattach(char *spec)
{
	return devattach("capability", spec);
}

static struct walkqid *capwalk(struct chan *c, struct chan *nc, char **name,
                               unsigned int nname)
{
	return devwalk(c, nc, name, nname, capdir, ncapdir, devgen);
}

static void capremove(struct chan *c)
{
	if (iseve() && c->qid.path == Qhash)
		ncapdir = ARRAY_SIZE(capdir) - 1;
	else
		error(EPERM, "Permission denied");
}

static size_t capstat(struct chan *c, uint8_t *db, size_t n)
{
	return devstat(c, db, n, capdir, ncapdir, devgen);
}

/*
 *  if the stream doesn't exist, create it
 */
static struct chan *capopen(struct chan *c, int omode)
{
	if (c->qid.type & QTDIR) {
		if (openmode(omode) != O_READ)
			error(EISDIR, "Can only read a directory");
		c->mode = openmode(omode);
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}

	switch ((uint32_t)c->qid.path) {
	case Qhash:
		if (!iseve())
			error(EPERM,
			      "Permission denied: only eve can open Qhash");
		break;
	}

	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

static size_t __hashstr(char *buf, uint8_t *hash, size_t bytes_to_split)
{
	int i;

	for (i = 0; i < bytes_to_split; i++)
		snprintf(buf + 2 * i, 3, "%02x", hash[i]);

	return bytes_to_split;
}

static struct Caphash *remcap(uint8_t *hash)
{
	struct Caphash *t, **l;

	qlock(&capalloc.qlock);

	/* find the matching capability */
	for (l = &capalloc.first; *l != NULL;) {
		t = *l;
		if (memcmp(hash, t->hash, Hashlen) == 0)
			break;
		l = &t->next;
	}
	t = *l;
	if (t != NULL) {
		capalloc.nhash--;
		*l = t->next;
	}
	qunlock(&capalloc.qlock);

	return t;
}

/* add a capability, throwing out any old ones */
static void addcap(uint8_t *hash)
{
	struct Caphash *p, *t, **l;

	p = kzmalloc(sizeof(*p), 0);
	memmove(p->hash, hash, Hashlen);
	p->next = NULL;

	qlock(&capalloc.qlock);

	/* trim extras */
	while (capalloc.nhash >= Maxhash) {
		t = capalloc.first;
		if (t == NULL)
			panic("addcap");
		capalloc.first = t->next;
		kfree(t);
		capalloc.nhash--;
	}

	/* add new one */
	for (l = &capalloc.first; *l != NULL; l = &(*l)->next)
		;
	*l = p;
	capalloc.nhash++;

	qunlock(&capalloc.qlock);
}

static void capclose(struct chan *c)
{
}

static size_t capread(struct chan *c, void *va, size_t n, off64_t m)
{
	switch ((uint32_t)c->qid.path) {
	case Qdir:
		return devdirread(c, va, n, capdir, ncapdir, devgen);

	default:
		error(EPERM, "Permission denied: can't read capability files");
		break;
	}
	return n;
}

static size_t capwrite(struct chan *c, void *va, size_t n, off64_t m)
{
	struct Caphash *p;
	char *cp;
	uint8_t hash[Hashlen + 1] = {0};
	char *hashstr = NULL;
	char *key, *from, *to;
	char err[256];
	int ret;
	ERRSTACK(1);

	switch ((uint32_t)c->qid.path) {
	case Qhash:
		if (!iseve())
			error(EPERM, "permission denied: you must be eve");
		if (n < VB2_SHA256_DIGEST_SIZE * 2)
			error(EIO, "Short read: on Qhash");
		memmove(hash, va, Hashlen);
		for (int i = 0; i < Hashlen; i++)
			hash[i] = tolower(hash[i]);
		addcap(hash);
		break;

	case Quse:
		/* copy key to avoid a fault in hmac_xx */
		cp = NULL;
		if (waserror()) {
			kfree(cp);
			kfree(hashstr);
			nexterror();
		}
		cp = kzmalloc(n + 1, 0);
		memmove(cp, va, n);
		cp[n] = 0;

		from = cp;
		key = strrchr(cp, '@');
		if (key == NULL)
			error(EIO, "short read: Quse");
		*key++ = 0;

		ret = hmac(VB2_HASH_SHA256, key, strlen(key),
		           from, strlen(from), hash, Hashlen);
		if (ret)
			error(EINVAL, "HMAC failed");

		// Convert to ASCII text
		hashstr = (char *)kzmalloc(sizeof(hash), MEM_WAIT);
		ret = __hashstr(hashstr, hash, VB2_SHA256_DIGEST_SIZE);
		if (ret != VB2_SHA256_DIGEST_SIZE)
			error(EINVAL, "hash is wrong length");

		p = remcap((uint8_t *)hashstr);
		if (p == NULL) {
			snprintf(err, sizeof(err), "invalid capability %s@%s",
				 from, key);
			error(EINVAL, err);
		}

		kfree(hashstr);
		hashstr = NULL;

		/* if a from user is supplied, make sure it matches */
		to = strchr(from, '@');
		if (to == NULL) {
			to = from;
		} else {
			*to++ = 0;
			if (strcmp(from, current->user.name) != 0)
				error(EINVAL, "capability must match user");
		}

		/* set user id */
		// In the original user names were NULL-terminated; ensure
		// that is still the case.
		if (strlen(to) > sizeof(current->user.name) - 1)
			error(EINVAL, "New user name is > %d bytes",
			      sizeof(current->user.name) - 1);
		proc_set_username(current, to);
		//up->basepri = PriNormal;

		kfree(p);
		kfree(cp);
		poperror();
		break;

	default:
		error(EPERM, "permission denied: capwrite");
		break;
	}

	return n;
}

struct dev capdevtab __devtab = {
	.name = "capability",

	.reset = devreset,
	.init = capinit,
	.shutdown = devshutdown,
	.attach = capattach,
	.walk = capwalk,
	.stat = capstat,
	.open = capopen,
	.create = devcreate,
	.close = capclose,
	.read = capread,
	.bread = devbread,
	.write = capwrite,
	.bwrite = devbwrite,
	.remove = capremove,
	.wstat = devwstat,
};
