#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");
	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;

	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;
}

