#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",
	"readhex",
	"writehex"
};

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");
	if(proto == nil){
		werrstr("no proto in attrs");
		goto out;
	}

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

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

	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;

	c->rpc.hex = 0;
	switch(c->rpc.op){
	case RpcWriteHex:
		c->rpc.op = RpcWrite;
		if(dec16(c->rpc.data, c->rpc.count, c->rpc.data, c->rpc.count) != c->rpc.count/2){
			rpcrespond(c, "bad hex");
			break;
		}
		c->rpc.count /= 2;
		goto Default;
	case RpcReadHex:
		c->rpc.hex = 1;
		c->rpc.op = RpcRead;
		/* fall through */
	case RpcRead:
		if(c->rpc.count > 0){
			rpcrespond(c, "error read takes no parameters");
			break;
		}
		/* fall through */
	default:
	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;
	int need, hex;

	if(c->hangup)
		return;

	need = strlen(verb)+1+count;
	hex = 0;
	if(c->rpc.hex && strcmp(verb, "ok") == 0){
		need += count;
		hex = 1;
	}
	if(need > sizeof c->reply){
		print("RPC response too large; caller %#lux", getcallerpc(&c));
		return;
	}

	strcpy(c->reply, verb);
	p = c->reply + strlen(c->reply);
	*p++ = ' ';
	if(hex){
		enc16(p, 2*count+1, data, count);
		p += 2*count;
	}else{
		memmove(p, data, count);
		p += count;
	}
	c->nreply = 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;
}

