aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/factotum/rpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/factotum/rpc.c')
-rw-r--r--src/cmd/factotum/rpc.c315
1 files changed, 0 insertions, 315 deletions
diff --git a/src/cmd/factotum/rpc.c b/src/cmd/factotum/rpc.c
deleted file mode 100644
index e9c163aa..00000000
--- a/src/cmd/factotum/rpc.c
+++ /dev/null
@@ -1,315 +0,0 @@
-#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;
-}
-