diff options
Diffstat (limited to 'src/libauth/auth_respond.c')
-rw-r--r-- | src/libauth/auth_respond.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/libauth/auth_respond.c b/src/libauth/auth_respond.c new file mode 100644 index 00000000..910f06b2 --- /dev/null +++ b/src/libauth/auth_respond.c @@ -0,0 +1,73 @@ +#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; + int afd; + AuthRpc *rpc; + Attr *a; + + if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0) + return -1; + + if((rpc = auth_allocrpc(afd)) == nil){ + close(afd); + 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); + close(afd); + 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); + close(afd); + auth_freerpc(rpc); + return nresp; +} |