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