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