xref: /plan9/sys/src/libauth/auth_rpc.c (revision fb7f0c934c48abaed6040d054ef636408c3c522d)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <auth.h>
49a747e4fSDavid du Colombier #include "authlocal.h"
59a747e4fSDavid du Colombier 
69a747e4fSDavid du Colombier static struct {
79a747e4fSDavid du Colombier 	char *verb;
89a747e4fSDavid du Colombier 	int val;
99a747e4fSDavid du Colombier } tab[] = {
109a747e4fSDavid du Colombier 	"ok",			ARok,
119a747e4fSDavid du Colombier 	"done",		ARdone,
129a747e4fSDavid du Colombier 	"error",		ARerror,
139a747e4fSDavid du Colombier 	"needkey",	ARneedkey,
149a747e4fSDavid du Colombier 	"badkey",		ARbadkey,
159a747e4fSDavid du Colombier 	"phase",		ARphase,
169a747e4fSDavid du Colombier 	"toosmall",	ARtoosmall,
179a747e4fSDavid du Colombier 	"error",		ARerror,
189a747e4fSDavid du Colombier };
199a747e4fSDavid du Colombier 
209a747e4fSDavid du Colombier static int
classify(char * buf,uint n,AuthRpc * rpc)219a747e4fSDavid du Colombier classify(char *buf, uint n, AuthRpc *rpc)
229a747e4fSDavid du Colombier {
239a747e4fSDavid du Colombier 	int i, len;
249a747e4fSDavid du Colombier 
259a747e4fSDavid du Colombier 	for(i=0; i<nelem(tab); i++){
269a747e4fSDavid du Colombier 		len = strlen(tab[i].verb);
279a747e4fSDavid du Colombier 		if(n >= len && memcmp(buf, tab[i].verb, len) == 0 && (n==len || buf[len]==' ')){
289a747e4fSDavid du Colombier 			if(n==len){
299a747e4fSDavid du Colombier 				rpc->narg = 0;
309a747e4fSDavid du Colombier 				rpc->arg = "";
319a747e4fSDavid du Colombier 			}else{
329a747e4fSDavid du Colombier 				rpc->narg = n - (len+1);
339a747e4fSDavid du Colombier 				rpc->arg = (char*)buf+len+1;
349a747e4fSDavid du Colombier 			}
359a747e4fSDavid du Colombier 			return tab[i].val;
369a747e4fSDavid du Colombier 		}
379a747e4fSDavid du Colombier 	}
389a747e4fSDavid du Colombier 	werrstr("malformed rpc response: %s", buf);
399a747e4fSDavid du Colombier 	return ARrpcfailure;
409a747e4fSDavid du Colombier }
419a747e4fSDavid du Colombier 
429a747e4fSDavid du Colombier AuthRpc*
auth_allocrpc(int afd)439a747e4fSDavid du Colombier auth_allocrpc(int afd)
449a747e4fSDavid du Colombier {
459a747e4fSDavid du Colombier 	AuthRpc *rpc;
469a747e4fSDavid du Colombier 
479a747e4fSDavid du Colombier 	rpc = mallocz(sizeof(*rpc), 1);
489a747e4fSDavid du Colombier 	if(rpc == nil)
499a747e4fSDavid du Colombier 		return nil;
509a747e4fSDavid du Colombier 	rpc->afd = afd;
519a747e4fSDavid du Colombier 	return rpc;
529a747e4fSDavid du Colombier }
539a747e4fSDavid du Colombier 
549a747e4fSDavid du Colombier void
auth_freerpc(AuthRpc * rpc)559a747e4fSDavid du Colombier auth_freerpc(AuthRpc *rpc)
569a747e4fSDavid du Colombier {
579a747e4fSDavid du Colombier 	free(rpc);
589a747e4fSDavid du Colombier }
599a747e4fSDavid du Colombier 
609a747e4fSDavid du Colombier uint
auth_rpc(AuthRpc * rpc,char * verb,void * a,int na)619a747e4fSDavid du Colombier auth_rpc(AuthRpc *rpc, char *verb, void *a, int na)
629a747e4fSDavid du Colombier {
639a747e4fSDavid du Colombier 	int l, n, type;
64*fb7f0c93SDavid du Colombier 	char *f[4];
659a747e4fSDavid du Colombier 
669a747e4fSDavid du Colombier 	l = strlen(verb);
679a747e4fSDavid du Colombier 	if(na+l+1 > AuthRpcMax){
689a747e4fSDavid du Colombier 		werrstr("rpc too big");
699a747e4fSDavid du Colombier 		return ARtoobig;
709a747e4fSDavid du Colombier 	}
719a747e4fSDavid du Colombier 
729a747e4fSDavid du Colombier 	memmove(rpc->obuf, verb, l);
739a747e4fSDavid du Colombier 	rpc->obuf[l] = ' ';
749a747e4fSDavid du Colombier 	memmove(rpc->obuf+l+1, a, na);
759a747e4fSDavid du Colombier 	if((n=write(rpc->afd, rpc->obuf, l+1+na)) != l+1+na){
769a747e4fSDavid du Colombier 		if(n >= 0)
779a747e4fSDavid du Colombier 			werrstr("auth_rpc short write");
789a747e4fSDavid du Colombier 		return ARrpcfailure;
799a747e4fSDavid du Colombier 	}
809a747e4fSDavid du Colombier 
819a747e4fSDavid du Colombier 	if((n=read(rpc->afd, rpc->ibuf, AuthRpcMax)) < 0)
829a747e4fSDavid du Colombier 		return ARrpcfailure;
839a747e4fSDavid du Colombier 	rpc->ibuf[n] = '\0';
849a747e4fSDavid du Colombier 
859a747e4fSDavid du Colombier 	/*
869a747e4fSDavid du Colombier 	 * Set error string for good default behavior.
879a747e4fSDavid du Colombier 	 */
889a747e4fSDavid du Colombier 	switch(type = classify(rpc->ibuf, n, rpc)){
899a747e4fSDavid du Colombier 	default:
909a747e4fSDavid du Colombier 		werrstr("unknown rpc type %d (bug in auth_rpc.c)", type);
919a747e4fSDavid du Colombier 		break;
929a747e4fSDavid du Colombier 	case ARok:
939a747e4fSDavid du Colombier 		break;
949a747e4fSDavid du Colombier 	case ARrpcfailure:
959a747e4fSDavid du Colombier 		break;
969a747e4fSDavid du Colombier 	case ARerror:
979a747e4fSDavid du Colombier 		if(rpc->narg == 0)
989a747e4fSDavid du Colombier 			werrstr("unspecified rpc error");
999a747e4fSDavid du Colombier 		else
1009a747e4fSDavid du Colombier 			werrstr("%s", rpc->arg);
1019a747e4fSDavid du Colombier 		break;
1029a747e4fSDavid du Colombier 	case ARneedkey:
1039a747e4fSDavid du Colombier 		werrstr("needkey %s", rpc->arg);
1049a747e4fSDavid du Colombier 		break;
1059a747e4fSDavid du Colombier 	case ARbadkey:
106*fb7f0c93SDavid du Colombier 		if(getfields(rpc->arg, f, nelem(f), 0, "\n") < 2)
1079a747e4fSDavid du Colombier 			werrstr("badkey %s", rpc->arg);
108*fb7f0c93SDavid du Colombier 		else
109*fb7f0c93SDavid du Colombier 			werrstr("badkey %s", f[1]);
1109a747e4fSDavid du Colombier 		break;
1119a747e4fSDavid du Colombier 	case ARphase:
1129a747e4fSDavid du Colombier 		werrstr("phase error %s", rpc->arg);
1139a747e4fSDavid du Colombier 		break;
1149a747e4fSDavid du Colombier 	}
1159a747e4fSDavid du Colombier 	return type;
1169a747e4fSDavid du Colombier }
117