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 65 l = strlen(verb); 66 if(na+l+1 > AuthRpcMax){ 67 werrstr("rpc too big"); 68 return ARtoobig; 69 } 70 71 memmove(rpc->obuf, verb, l); 72 rpc->obuf[l] = ' '; 73 memmove(rpc->obuf+l+1, a, na); 74 if((n=write(rpc->afd, rpc->obuf, l+1+na)) != l+1+na){ 75 if(n >= 0) 76 werrstr("auth_rpc short write"); 77 return ARrpcfailure; 78 } 79 80 if((n=read(rpc->afd, rpc->ibuf, AuthRpcMax)) < 0) 81 return ARrpcfailure; 82 rpc->ibuf[n] = '\0'; 83 84 /* 85 * Set error string for good default behavior. 86 */ 87 switch(type = classify(rpc->ibuf, n, rpc)){ 88 default: 89 werrstr("unknown rpc type %d (bug in auth_rpc.c)", type); 90 break; 91 case ARok: 92 break; 93 case ARrpcfailure: 94 break; 95 case ARerror: 96 if(rpc->narg == 0) 97 werrstr("unspecified rpc error"); 98 else 99 werrstr("%s", rpc->arg); 100 break; 101 case ARneedkey: 102 werrstr("needkey %s", rpc->arg); 103 break; 104 case ARbadkey: 105 werrstr("badkey %s", rpc->arg); 106 break; 107 case ARphase: 108 werrstr("phase error %s", rpc->arg); 109 break; 110 } 111 return type; 112 } 113