|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <auth.h> | 
|  | #include <authsrv.h> | 
|  | #include "authlocal.h" | 
|  |  | 
|  | Chalstate* | 
|  | auth_challenge(char *fmt, ...) | 
|  | { | 
|  | char *p; | 
|  | va_list arg; | 
|  | Chalstate *c; | 
|  |  | 
|  | quotefmtinstall();	/* just in case */ | 
|  | va_start(arg, fmt); | 
|  | p = vsmprint(fmt, arg); | 
|  | va_end(arg); | 
|  | if(p == nil) | 
|  | return nil; | 
|  |  | 
|  | c = mallocz(sizeof(*c), 1); | 
|  | if(c == nil){ | 
|  | free(p); | 
|  | return nil; | 
|  | } | 
|  |  | 
|  | if((c->rpc=auth_allocrpc()) == nil | 
|  | || auth_rpc(c->rpc, "start", p, strlen(p)) != ARok | 
|  | || auth_rpc(c->rpc, "read", nil, 0) != ARok){ | 
|  | Error: | 
|  | auth_freechal(c); | 
|  | free(p); | 
|  | return nil; | 
|  | } | 
|  |  | 
|  | if(c->rpc->narg > sizeof(c->chal)-1){ | 
|  | werrstr("buffer too small for challenge"); | 
|  | goto Error; | 
|  | } | 
|  | memmove(c->chal, c->rpc->arg, c->rpc->narg); | 
|  | c->nchal = c->rpc->narg; | 
|  | free(p); | 
|  | return c; | 
|  | } | 
|  |  | 
|  | AuthInfo* | 
|  | auth_response(Chalstate *c) | 
|  | { | 
|  | int ret; | 
|  | AuthInfo *ai; | 
|  |  | 
|  | ai = nil; | 
|  | if(c->rpc == nil){ | 
|  | werrstr("auth_response: connection not open"); | 
|  | return nil; | 
|  | } | 
|  | if(c->resp == nil){ | 
|  | werrstr("auth_response: nil response"); | 
|  | return nil; | 
|  | } | 
|  | if(c->nresp == 0){ | 
|  | werrstr("auth_response: unspecified response length"); | 
|  | return nil; | 
|  | } | 
|  |  | 
|  | if(c->user){ | 
|  | if(auth_rpc(c->rpc, "write", c->user, strlen(c->user)) != ARok){ | 
|  | /* | 
|  | * if this fails we're out of phase with factotum. | 
|  | * give up. | 
|  | */ | 
|  | goto Out; | 
|  | } | 
|  | } | 
|  |  | 
|  | if(auth_rpc(c->rpc, "write", c->resp, c->nresp) != ARok){ | 
|  | /* | 
|  | * don't close the connection -- maybe we'll try again. | 
|  | */ | 
|  | return nil; | 
|  | } | 
|  |  | 
|  | switch(ret = auth_rpc(c->rpc, "read", nil, 0)){ | 
|  | case ARok: | 
|  | default: | 
|  | werrstr("factotum protocol botch %d %s", ret, c->rpc->ibuf); | 
|  | break; | 
|  | case ARdone: | 
|  | ai = auth_getinfo(c->rpc); | 
|  | break; | 
|  | } | 
|  |  | 
|  | Out: | 
|  | auth_freerpc(c->rpc); | 
|  | c->rpc = nil; | 
|  | return ai; | 
|  | } | 
|  |  | 
|  | void | 
|  | auth_freechal(Chalstate *c) | 
|  | { | 
|  | if(c == nil) | 
|  | return; | 
|  | if(c->rpc != nil) | 
|  | auth_freerpc(c->rpc); | 
|  | memset(c, 0xBB, sizeof(*c)); | 
|  | free(c); | 
|  | } |