Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#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;   
}