#include "std.h"
#include "dat.h"

/*
 * Factotum RPC
 *
 * Must be paired write/read cycles on /mnt/factotum/rpc.
 * The format of a request is verb, single space, data.
 * Data format is verb-dependent; in particular, it can be binary.
 * The format of a response is the same.  The write only sets up
 * the RPC.  The read tries to execute it.  If the /mnt/factotum/key
 * file is open, we ask for new keys using that instead of returning
 * an error in the RPC.  This means the read blocks.
 * Textual arguments are parsed with tokenize, so rc-style quoting
 * rules apply.
 *
 * Only authentication protocol messages go here.  Configuration
 * is still via ctl (below).
 *
 * Request RPCs are:
 *	start attrs - initializes protocol for authentication, can fail.
 *		returns "ok read" or "ok write" on success.
 *	read - execute protocol read
 *	write - execute protocol write
 *	authinfo - if the protocol is finished, return the AI if any
 *	attr - return protocol information
 * Return values are:
 *	error message - an error happened.
 *	ok [data] - success, possible data is request dependent.
 *	needkey attrs - request aborted, get me this key and try again
 *	badkey attrs - request aborted, this key might be bad
 *	done [haveai] - authentication is done [haveai: you can get an ai with authinfo]
 */

char *rpcname[] = 
{
	"unknown",
	"authinfo",
	"attr",
	"read",
	"start",
	"write",
};

static int
classify(char *s)
{
	int i;

	for(i=1; i<nelem(rpcname); i++)
		if(strcmp(s, rpcname[i]) == 0)
			return i;
	return RpcUnknown;
}

int
rpcwrite(Conv *c, void *data, int count)
{
	int op;
	uchar *p;

	if(count >= MaxRpc){
		werrstr("rpc too large");
		return -1;
	}

	/* cancel any current rpc */
	c->rpc.op = RpcUnknown;
	c->nreply = 0;

	/* parse new rpc */
	memmove(c->rpcbuf, data, count);
	c->rpcbuf[count] = 0;
	if(p = (uchar*)strchr((char*)c->rpcbuf, ' ')){
		*p++ = '\0';
		c->rpc.data = p;
		c->rpc.count = count - (p - (uchar*)c->rpcbuf);
	}else{
		c->rpc.data = "";
		c->rpc.count = 0;
	}
	op = classify(c->rpcbuf);
	if(op == RpcUnknown){
		werrstr("bad rpc verb: %s", c->rpcbuf);
		return -1;
	}

	c->rpc.op = op;
	return 0;
}

void
convthread(void *v)
{
	Conv *c;
	Attr *a;
	char *role, *proto;
	Proto *p;
	Role *r;

	c = v;
	a = parseattr(c->rpc.data);
	if(a == nil){
		werrstr("empty attr");
		goto out;
	}
	c->attr = a;
	proto = strfindattr(a, "proto");
	role = strfindattr(a, "role");

	if(proto == nil){
		werrstr("no proto in attrs");
		goto out;
	}
	if(role == nil){
		werrstr("no role in attrs");
		goto out;
	}

	p = protolookup(proto);
	if(p == nil){
		werrstr("unknown proto %s", proto);
		goto out;
	}

	c->proto = p;
	for(r=p->roles; r->name; r++){
		if(strcmp(r->name, role) != 0)
			continue;
		rpcrespond(c, "ok");
		c->active = 1;
		if((*r->fn)(c) == 0){
			c->done = 1;
			werrstr("protocol finished");
		}else
			werrstr("%s %s %s: %r", p->name, r->name, c->state);
		goto out;
	}
	werrstr("unknown role");

out:
	c->active = 0;
	c->state = 0;
	rerrstr(c->err, sizeof c->err);
	rpcrespond(c, "error %r");
	convclose(c);
}

static uchar* convAI2M(uchar *p, int n, char *cuid, char *suid, char *cap, char *hex);

void
rpcexec(Conv *c)
{
	uchar *p;

	switch(c->rpc.op){
	case RpcRead:
		if(c->rpc.count > 0){
			rpcrespond(c, "error read takes no parameters");
			break;
		}
		/* fall through */
	default:
		if(!c->active){
			if(c->done)
				rpcrespond(c, "done");
			else
				rpcrespond(c, "error %s", c->err);
			break;
		}
		nbsendp(c->rpcwait, 0);
		break;
	case RpcUnknown:
		break;
	case RpcAuthinfo:
		/* deprecated */
		if(c->active)
			rpcrespond(c, "error conversation still active");
		else if(!c->done)
			rpcrespond(c, "error conversation not successful");
		else{
			/* make up an auth info using the attr */
			p = convAI2M((uchar*)c->reply+3, sizeof c->reply-3, 
				strfindattr(c->attr, "cuid"),
				strfindattr(c->attr, "suid"),
				strfindattr(c->attr, "cap"),
				strfindattr(c->attr, "secret"));
			if(p == nil)
				rpcrespond(c, "error %r");
			else
				rpcrespondn(c, "ok", c->reply+3, p-(uchar*)(c->reply+3));
		}
		break;
	case RpcAttr:
		rpcrespond(c, "ok %A", c->attr);
		break;
	case RpcStart:
		convreset(c);
		c->ref++;
		threadcreate(convthread, c, STACK);
		break;
	}
}

void
rpcrespond(Conv *c, char *fmt, ...)
{
	va_list arg;

	if(c->hangup)
		return;

	if(fmt == nil)
		fmt = "";

	va_start(arg, fmt);
	c->nreply = vsnprint(c->reply, sizeof c->reply, fmt, arg);
	va_end(arg);
	(*c->kickreply)(c);
	c->rpc.op = RpcUnknown;
}

void
rpcrespondn(Conv *c, char *verb, void *data, int count)
{
	char *p;

	if(c->hangup)
		return;

	if(strlen(verb)+1+count > sizeof c->reply){
		print("RPC response too large; caller %#lux", getcallerpc(&c));
		return;
	}

	strcpy(c->reply, verb);
	p = c->reply + strlen(c->reply);
	*p++ = ' ';
	memmove(p, data, count);
	c->nreply = count + (p - c->reply);
	(*c->kickreply)(c);
	c->rpc.op = RpcUnknown;
}

/* deprecated */
static uchar*
pstring(uchar *p, uchar *e, char *s)
{
	uint n;

	if(p == nil)
		return nil;
	if(s == nil)
		s = "";
	n = strlen(s);
	if(p+n+BIT16SZ >= e)
		return nil;
	PBIT16(p, n);
	p += BIT16SZ;
	memmove(p, s, n);
	p += n;
	return p;
}

static uchar*
pcarray(uchar *p, uchar *e, uchar *s, uint n)
{
	if(p == nil)
		return nil;
	if(s == nil){
		if(n > 0)
			sysfatal("pcarray");
		s = (uchar*)"";
	}
	if(p+n+BIT16SZ >= e)
		return nil;
	PBIT16(p, n);
	p += BIT16SZ;
	memmove(p, s, n);
	p += n;
	return p;
}

static uchar*
convAI2M(uchar *p, int n, char *cuid, char *suid, char *cap, char *hex)
{
	uchar *e = p+n;
	uchar *secret;
	int nsecret;

	if(cuid == nil)
		cuid = "";
	if(suid == nil)
		suid = "";
	if(cap == nil)
		cap = "";
	if(hex == nil)
		hex = "";
	nsecret = strlen(hex)/2;
	secret = emalloc(nsecret);
	if(hexparse(hex, secret, nsecret) < 0){
		werrstr("hexparse %s failed", hex);	/* can't happen */
		free(secret);
		return nil;
	}
	p = pstring(p, e, cuid);
	p = pstring(p, e, suid);
	p = pstring(p, e, cap);
	p = pcarray(p, e, secret, nsecret);
	free(secret);
	if(p == nil)
		werrstr("authinfo too big");
	return p;
}

