blob: b3cf6665f16a877f6e0899d81066a83c45a2c31a [file] [log] [blame]
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <authsrv.h>
#include "authlocal.h"
enum {
ARgiveup = 100
};
static int
dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
{
int ret;
for(;;){
if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
return ret;
if(getkey == nil)
return ARgiveup; /* don't know how */
if((*getkey)(rpc->arg) < 0)
return ARgiveup; /* user punted */
}
}
int
auth_respond(void *chal, uint nchal, char *user, uint nuser, void *resp, uint nresp, AuthGetkey *getkey, char *fmt, ...)
{
char *p, *s;
va_list arg;
AuthRpc *rpc;
Attr *a;
if((rpc = auth_allocrpc()) == nil)
return -1;
quotefmtinstall(); /* just in case */
va_start(arg, fmt);
p = vsmprint(fmt, arg);
va_end(arg);
if(p==nil
|| dorpc(rpc, "start", p, strlen(p), getkey) != ARok
|| dorpc(rpc, "write", chal, nchal, getkey) != ARok
|| dorpc(rpc, "read", nil, 0, getkey) != ARok){
free(p);
auth_freerpc(rpc);
return -1;
}
free(p);
if(rpc->narg < nresp)
nresp = rpc->narg;
memmove(resp, rpc->arg, nresp);
if((a = auth_attr(rpc)) != nil
&& (s = _strfindattr(a, "user")) != nil && strlen(s) < nuser)
strcpy(user, s);
else if(nuser > 0)
user[0] = '\0';
_freeattr(a);
auth_freerpc(rpc);
return nresp;
}