/*
 * 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 <vfs.h>
#include <kfs.h>
#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 <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,
                               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 int32_t capstat(struct chan *c, uint8_t *db, int32_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 long capread(struct chan *c, void *va, long n, int64_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 long capwrite(struct chan *c, void *va, long n, int64_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,
};
