xref: /plan9/sys/src/cmd/unix/drawterm/libauth/auth_rpc.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include <u.h>
2*8ccd4a63SDavid du Colombier #include <libc.h>
3*8ccd4a63SDavid du Colombier #include <auth.h>
4*8ccd4a63SDavid du Colombier #include "authlocal.h"
5*8ccd4a63SDavid du Colombier 
6*8ccd4a63SDavid du Colombier static struct {
7*8ccd4a63SDavid du Colombier 	char *verb;
8*8ccd4a63SDavid du Colombier 	int val;
9*8ccd4a63SDavid du Colombier } tab[] = {
10*8ccd4a63SDavid du Colombier 	"ok",			ARok,
11*8ccd4a63SDavid du Colombier 	"done",		ARdone,
12*8ccd4a63SDavid du Colombier 	"error",		ARerror,
13*8ccd4a63SDavid du Colombier 	"needkey",	ARneedkey,
14*8ccd4a63SDavid du Colombier 	"badkey",		ARbadkey,
15*8ccd4a63SDavid du Colombier 	"phase",		ARphase,
16*8ccd4a63SDavid du Colombier 	"toosmall",	ARtoosmall,
17*8ccd4a63SDavid du Colombier 	"error",		ARerror,
18*8ccd4a63SDavid du Colombier };
19*8ccd4a63SDavid du Colombier 
20*8ccd4a63SDavid du Colombier static int
classify(char * buf,uint n,AuthRpc * rpc)21*8ccd4a63SDavid du Colombier classify(char *buf, uint n, AuthRpc *rpc)
22*8ccd4a63SDavid du Colombier {
23*8ccd4a63SDavid du Colombier 	int i, len;
24*8ccd4a63SDavid du Colombier 
25*8ccd4a63SDavid du Colombier 	for(i=0; i<nelem(tab); i++){
26*8ccd4a63SDavid du Colombier 		len = strlen(tab[i].verb);
27*8ccd4a63SDavid du Colombier 		if(n >= len && memcmp(buf, tab[i].verb, len) == 0 && (n==len || buf[len]==' ')){
28*8ccd4a63SDavid du Colombier 			if(n==len){
29*8ccd4a63SDavid du Colombier 				rpc->narg = 0;
30*8ccd4a63SDavid du Colombier 				rpc->arg = "";
31*8ccd4a63SDavid du Colombier 			}else{
32*8ccd4a63SDavid du Colombier 				rpc->narg = n - (len+1);
33*8ccd4a63SDavid du Colombier 				rpc->arg = (char*)buf+len+1;
34*8ccd4a63SDavid du Colombier 			}
35*8ccd4a63SDavid du Colombier 			return tab[i].val;
36*8ccd4a63SDavid du Colombier 		}
37*8ccd4a63SDavid du Colombier 	}
38*8ccd4a63SDavid du Colombier 	werrstr("malformed rpc response: %s", buf);
39*8ccd4a63SDavid du Colombier 	return ARrpcfailure;
40*8ccd4a63SDavid du Colombier }
41*8ccd4a63SDavid du Colombier 
42*8ccd4a63SDavid du Colombier AuthRpc*
auth_allocrpc(int afd)43*8ccd4a63SDavid du Colombier auth_allocrpc(int afd)
44*8ccd4a63SDavid du Colombier {
45*8ccd4a63SDavid du Colombier 	AuthRpc *rpc;
46*8ccd4a63SDavid du Colombier 
47*8ccd4a63SDavid du Colombier 	rpc = mallocz(sizeof(*rpc), 1);
48*8ccd4a63SDavid du Colombier 	if(rpc == nil)
49*8ccd4a63SDavid du Colombier 		return nil;
50*8ccd4a63SDavid du Colombier 	rpc->afd = afd;
51*8ccd4a63SDavid du Colombier 	return rpc;
52*8ccd4a63SDavid du Colombier }
53*8ccd4a63SDavid du Colombier 
54*8ccd4a63SDavid du Colombier void
auth_freerpc(AuthRpc * rpc)55*8ccd4a63SDavid du Colombier auth_freerpc(AuthRpc *rpc)
56*8ccd4a63SDavid du Colombier {
57*8ccd4a63SDavid du Colombier 	free(rpc);
58*8ccd4a63SDavid du Colombier }
59*8ccd4a63SDavid du Colombier 
60*8ccd4a63SDavid du Colombier uint
auth_rpc(AuthRpc * rpc,char * verb,void * a,int na)61*8ccd4a63SDavid du Colombier auth_rpc(AuthRpc *rpc, char *verb, void *a, int na)
62*8ccd4a63SDavid du Colombier {
63*8ccd4a63SDavid du Colombier 	int l, n, type;
64*8ccd4a63SDavid du Colombier 	char *f[4];
65*8ccd4a63SDavid du Colombier 
66*8ccd4a63SDavid du Colombier 	l = strlen(verb);
67*8ccd4a63SDavid du Colombier 	if(na+l+1 > AuthRpcMax){
68*8ccd4a63SDavid du Colombier 		werrstr("rpc too big");
69*8ccd4a63SDavid du Colombier 		return ARtoobig;
70*8ccd4a63SDavid du Colombier 	}
71*8ccd4a63SDavid du Colombier 
72*8ccd4a63SDavid du Colombier 	memmove(rpc->obuf, verb, l);
73*8ccd4a63SDavid du Colombier 	rpc->obuf[l] = ' ';
74*8ccd4a63SDavid du Colombier 	memmove(rpc->obuf+l+1, a, na);
75*8ccd4a63SDavid du Colombier 	if((n=write(rpc->afd, rpc->obuf, l+1+na)) != l+1+na){
76*8ccd4a63SDavid du Colombier 		if(n >= 0)
77*8ccd4a63SDavid du Colombier 			werrstr("auth_rpc short write");
78*8ccd4a63SDavid du Colombier 		return ARrpcfailure;
79*8ccd4a63SDavid du Colombier 	}
80*8ccd4a63SDavid du Colombier 
81*8ccd4a63SDavid du Colombier 	if((n=read(rpc->afd, rpc->ibuf, AuthRpcMax)) < 0)
82*8ccd4a63SDavid du Colombier 		return ARrpcfailure;
83*8ccd4a63SDavid du Colombier 	rpc->ibuf[n] = '\0';
84*8ccd4a63SDavid du Colombier 
85*8ccd4a63SDavid du Colombier 	/*
86*8ccd4a63SDavid du Colombier 	 * Set error string for good default behavior.
87*8ccd4a63SDavid du Colombier 	 */
88*8ccd4a63SDavid du Colombier 	switch(type = classify(rpc->ibuf, n, rpc)){
89*8ccd4a63SDavid du Colombier 	default:
90*8ccd4a63SDavid du Colombier 		werrstr("unknown rpc type %d (bug in auth_rpc.c)", type);
91*8ccd4a63SDavid du Colombier 		break;
92*8ccd4a63SDavid du Colombier 	case ARok:
93*8ccd4a63SDavid du Colombier 		break;
94*8ccd4a63SDavid du Colombier 	case ARrpcfailure:
95*8ccd4a63SDavid du Colombier 		break;
96*8ccd4a63SDavid du Colombier 	case ARerror:
97*8ccd4a63SDavid du Colombier 		if(rpc->narg == 0)
98*8ccd4a63SDavid du Colombier 			werrstr("unspecified rpc error");
99*8ccd4a63SDavid du Colombier 		else
100*8ccd4a63SDavid du Colombier 			werrstr("%s", rpc->arg);
101*8ccd4a63SDavid du Colombier 		break;
102*8ccd4a63SDavid du Colombier 	case ARneedkey:
103*8ccd4a63SDavid du Colombier 		werrstr("needkey %s", rpc->arg);
104*8ccd4a63SDavid du Colombier 		break;
105*8ccd4a63SDavid du Colombier 	case ARbadkey:
106*8ccd4a63SDavid du Colombier 		if(getfields(rpc->arg, f, nelem(f), 0, "\n") < 2)
107*8ccd4a63SDavid du Colombier 			werrstr("badkey %s", rpc->arg);
108*8ccd4a63SDavid du Colombier 		else
109*8ccd4a63SDavid du Colombier 			werrstr("badkey %s", f[1]);
110*8ccd4a63SDavid du Colombier 		break;
111*8ccd4a63SDavid du Colombier 	case ARphase:
112*8ccd4a63SDavid du Colombier 		werrstr("phase error %s", rpc->arg);
113*8ccd4a63SDavid du Colombier 		break;
114*8ccd4a63SDavid du Colombier 	}
115*8ccd4a63SDavid du Colombier 	return type;
116*8ccd4a63SDavid du Colombier }
117