/* * this just proxies what the factotum tells it to. */ AuthInfo* fsfauth_proxy(CFid *fid, AuthRpc *rpc, AuthGetkey *getkey, char *params) { char *buf; int m, n, ret; AuthInfo *a; char oerr[ERRMAX]; rerrstr(oerr, sizeof oerr); werrstr("UNKNOWN AUTH ERROR"); if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){ werrstr("fauth_proxy start: %r"); return nil; } buf = malloc(AuthRpcMax); if(buf == nil) return nil; for(;;){ switch(dorpc(rpc, "read", nil, 0, getkey)){ case ARdone: free(buf); a = auth_getinfo(rpc); errstr(oerr, sizeof oerr); /* no error, restore whatever was there */ return a; case ARok: if(fswrite(fid, rpc->arg, rpc->narg) != rpc->narg){ werrstr("auth_proxy write fid: %r"); goto Error; } break; case ARphase: n = 0; memset(buf, 0, AuthRpcMax); while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){ if(atoi(rpc->arg) > AuthRpcMax) break; m = fsread(fid, buf+n, atoi(rpc->arg)-n); if(m <= 0){ if(m == 0) werrstr("auth_proxy short read: %s", buf); goto Error; } n += m; } if(ret != ARok){ werrstr("auth_proxy rpc write: %s: %r", buf); goto Error; } break; default: werrstr("auth_proxy rpc: %r"); goto Error; } } Error: free(buf); return nil; }
static int _authread(Afid *afid, void *data, int count) { AuthInfo *ai; switch(auth_rpc(afid->rpc, "read", nil, 0)){ case ARdone: ai = auth_getinfo(afid->rpc); if(ai == nil) return -1; auth_freeAI(ai); if(chatty9p) fprint(2, "authenticate %s/%s: ok\n", afid->uname, afid->aname); afid->authok = 1; return 0; case ARok: if(count < afid->rpc->narg){ werrstr("authread count too small"); return -1; } count = afid->rpc->narg; memmove(data, afid->rpc->arg, count); return count; case ARphase: default: werrstr("authrpc botch"); return -1; } }
AuthInfo* auth_response(Chalstate *c) { int ret; AuthInfo *ai; ai = nil; if(c->afd < 0){ 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: close(c->afd); auth_freerpc(c->rpc); c->afd = -1; c->rpc = nil; return ai; }
/* * this just proxies what the factotum tells it to. */ AuthInfo* fauth_proxy(FFid *f, AuthRpc *rpc, AuthGetkey *getkey, char *params) { char *buf; int m, n, ret; AuthInfo *a; if(rpc == nil){ return nil; } if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){ return nil; } buf = emalloc(AuthRpcMax); if(buf == nil) return nil; for(;;){ switch(dorpc(rpc, "read", nil, 0, getkey)){ case ARdone: free(buf); a = auth_getinfo(rpc); return a; case ARok: if(_9pwrite(f, rpc->arg, rpc->narg) != rpc->narg){ goto Error; } break; case ARphase: n = 0; memset(buf, 0, AuthRpcMax); while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){ m = atoi(rpc->arg); if(m <= n || m > AuthRpcMax) break; m = _9pread(f, buf + n, m - n); if(m <= 0) goto Error; n += m; } if(ret != ARok) goto Error; break; default: goto Error; } } Error: free(buf); return nil; }
int authRead(Fid* afid, void* data, int count) { AuthInfo *ai; AuthRpc *rpc; if((rpc = afid->rpc) == nil){ werrstr("not an auth fid"); return -1; } switch(auth_rpc(rpc, "read", nil, 0)){ default: werrstr("fossil authRead: auth protocol not finished"); return -1; case ARdone: if((ai = auth_getinfo(rpc)) == nil){ werrstr("%r"); break; } if(ai->cuid == nil || *ai->cuid == '\0'){ werrstr("auth with no cuid"); auth_freeAI(ai); break; } assert(afid->cuname == nil); afid->cuname = vtstrdup(ai->cuid); auth_freeAI(ai); if(Dflag) fprint(2, "authRead cuname %s\n", afid->cuname); assert(afid->uid == nil); if((afid->uid = uidByUname(afid->cuname)) == nil){ werrstr("unknown user %#q", afid->cuname); break; } return 0; case ARok: if(count < rpc->narg){ werrstr("not enough data in auth read"); break; } memmove(data, rpc->arg, rpc->narg); return rpc->narg; case ARphase: werrstr("%r"); break; } return -1; }
int authread(File *file, uchar *data, int count) { AuthInfo *ai; AuthRpc *rpc; Chan *chan; chan = file->cp; if((rpc = file->auth) == nil){ snprint(chan->err, sizeof(chan->err), "not an auth fid"); return -1; } switch(auth_rpc(rpc, "read", nil, 0)){ default: snprint(chan->err, sizeof(chan->err), "authread: auth protocol not finished"); return -1; case ARdone: if((ai = auth_getinfo(rpc)) == nil) goto Phase; file->uid = strtouid(ai->cuid); if(file->uid < 0){ snprint(chan->err, sizeof(chan->err), "unknown user '%s'", ai->cuid); auth_freeAI(ai); return -1; } auth_freeAI(ai); return 0; case ARok: if(count < rpc->narg){ snprint(chan->err, sizeof(chan->err), "not enough data in auth read"); return -1; } memmove(data, rpc->arg, rpc->narg); return rpc->narg; case ARphase: Phase: rerrstr(chan->err, sizeof(chan->err)); return -1; } }