1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 #include <authsrv.h> 5 #include "authlocal.h" 6 7 Chalstate* 8 auth_challenge(char *fmt, ...) 9 { 10 char *p; 11 va_list arg; 12 Chalstate *c; 13 14 quotefmtinstall(); /* just in case */ 15 va_start(arg, fmt); 16 p = vsmprint(fmt, arg); 17 va_end(arg); 18 if(p == nil) 19 return nil; 20 21 c = mallocz(sizeof(*c), 1); 22 if(c == nil){ 23 free(p); 24 return nil; 25 } 26 27 if((c->afd = open("/mnt/factotum/rpc", ORDWR)) < 0){ 28 Error: 29 auth_freechal(c); 30 free(p); 31 return nil; 32 } 33 34 if((c->rpc=auth_allocrpc(c->afd)) == nil 35 || auth_rpc(c->rpc, "start", p, strlen(p)) != ARok 36 || auth_rpc(c->rpc, "read", nil, 0) != ARok) 37 goto Error; 38 39 if(c->rpc->narg > sizeof(c->chal)-1){ 40 werrstr("buffer too small for challenge"); 41 goto Error; 42 } 43 memmove(c->chal, c->rpc->arg, c->rpc->narg); 44 c->nchal = c->rpc->narg; 45 free(p); 46 return c; 47 } 48 49 AuthInfo* 50 auth_response(Chalstate *c) 51 { 52 int ret; 53 AuthInfo *ai; 54 55 ai = nil; 56 if(c->afd < 0){ 57 werrstr("auth_response: connection not open"); 58 return nil; 59 } 60 if(c->resp == nil){ 61 werrstr("auth_response: nil response"); 62 return nil; 63 } 64 if(c->nresp == 0){ 65 werrstr("auth_response: unspecified response length"); 66 return nil; 67 } 68 69 if(c->user){ 70 if(auth_rpc(c->rpc, "write", c->user, strlen(c->user)) != ARok){ 71 /* 72 * if this fails we're out of phase with factotum. 73 * give up. 74 */ 75 goto Out; 76 } 77 } 78 79 if(auth_rpc(c->rpc, "write", c->resp, c->nresp) != ARok){ 80 /* 81 * don't close the connection -- maybe we'll try again. 82 */ 83 return nil; 84 } 85 86 switch(ret = auth_rpc(c->rpc, "read", nil, 0)){ 87 case ARok: 88 default: 89 werrstr("factotum protocol botch %d %s", ret, c->rpc->ibuf); 90 break; 91 case ARdone: 92 ai = auth_getinfo(c->rpc); 93 break; 94 } 95 96 Out: 97 close(c->afd); 98 auth_freerpc(c->rpc); 99 c->afd = -1; 100 c->rpc = nil; 101 return ai; 102 } 103 104 void 105 auth_freechal(Chalstate *c) 106 { 107 if(c == nil) 108 return; 109 110 if(c->afd >= 0) 111 close(c->afd); 112 if(c->rpc != nil) 113 auth_freerpc(c->rpc); 114 115 memset(c, 0xBB, sizeof(*c)); 116 free(c); 117 } 118