15e96a66cSDavid du Colombier #include "stdinc.h" 25e96a66cSDavid du Colombier #include "9.h" 35e96a66cSDavid du Colombier 45e96a66cSDavid du Colombier int 55e96a66cSDavid du Colombier authRead(Fid* afid, void* data, int count) 65e96a66cSDavid du Colombier { 75e96a66cSDavid du Colombier AuthInfo *ai; 85e96a66cSDavid du Colombier AuthRpc *rpc; 95e96a66cSDavid du Colombier 1081cf8742SDavid du Colombier if((rpc = afid->rpc) == nil){ 1181cf8742SDavid du Colombier vtSetError("not an auth fid"); 125e96a66cSDavid du Colombier return -1; 1381cf8742SDavid du Colombier } 145e96a66cSDavid du Colombier 155e96a66cSDavid du Colombier switch(auth_rpc(rpc, "read", nil, 0)){ 165e96a66cSDavid du Colombier default: 17*208510e1SDavid du Colombier vtSetError("fossil authRead: auth protocol not finished"); 185e96a66cSDavid du Colombier return -1; 195e96a66cSDavid du Colombier case ARdone: 2081cf8742SDavid du Colombier if((ai = auth_getinfo(rpc)) == nil){ 2181cf8742SDavid du Colombier vtSetError("%r"); 225e96a66cSDavid du Colombier break; 2381cf8742SDavid du Colombier } 245e96a66cSDavid du Colombier if(ai->cuid == nil || *ai->cuid == '\0'){ 2581cf8742SDavid du Colombier vtSetError("auth with no cuid"); 265e96a66cSDavid du Colombier auth_freeAI(ai); 275e96a66cSDavid du Colombier break; 285e96a66cSDavid du Colombier } 295e96a66cSDavid du Colombier assert(afid->cuname == nil); 305e96a66cSDavid du Colombier afid->cuname = vtStrDup(ai->cuid); 315e96a66cSDavid du Colombier auth_freeAI(ai); 325e96a66cSDavid du Colombier if(Dflag) 335e96a66cSDavid du Colombier fprint(2, "authRead cuname %s\n", afid->cuname); 345e96a66cSDavid du Colombier assert(afid->uid == nil); 3581cf8742SDavid du Colombier if((afid->uid = uidByUname(afid->cuname)) == nil){ 3681cf8742SDavid du Colombier vtSetError("unknown user %#q", afid->cuname); 375e96a66cSDavid du Colombier break; 3881cf8742SDavid du Colombier } 395e96a66cSDavid du Colombier return 0; 405e96a66cSDavid du Colombier case ARok: 4181cf8742SDavid du Colombier if(count < rpc->narg){ 4281cf8742SDavid du Colombier vtSetError("not enough data in auth read"); 435e96a66cSDavid du Colombier break; 4481cf8742SDavid du Colombier } 455e96a66cSDavid du Colombier memmove(data, rpc->arg, rpc->narg); 465e96a66cSDavid du Colombier return rpc->narg; 475e96a66cSDavid du Colombier case ARphase: 4881cf8742SDavid du Colombier vtSetError("%r"); 495e96a66cSDavid du Colombier break; 505e96a66cSDavid du Colombier } 515e96a66cSDavid du Colombier return -1; 525e96a66cSDavid du Colombier } 535e96a66cSDavid du Colombier 545e96a66cSDavid du Colombier int 555e96a66cSDavid du Colombier authWrite(Fid* afid, void* data, int count) 565e96a66cSDavid du Colombier { 575e96a66cSDavid du Colombier assert(afid->rpc != nil); 585e96a66cSDavid du Colombier if(auth_rpc(afid->rpc, "write", data, count) != ARok) 595e96a66cSDavid du Colombier return -1; 605e96a66cSDavid du Colombier return count; 615e96a66cSDavid du Colombier } 625e96a66cSDavid du Colombier 635e96a66cSDavid du Colombier int 645e96a66cSDavid du Colombier authCheck(Fcall* t, Fid* fid, Fs* fsys) 655e96a66cSDavid du Colombier { 6634e04225SDavid du Colombier Con *con; 675e96a66cSDavid du Colombier Fid *afid; 685e96a66cSDavid du Colombier uchar buf[1]; 695e96a66cSDavid du Colombier 705e96a66cSDavid du Colombier /* 715e96a66cSDavid du Colombier * Can't lookup with FidWlock here as there may be 725e96a66cSDavid du Colombier * protocol to do. Use a separate lock to protect altering 735e96a66cSDavid du Colombier * the auth information inside afid. 745e96a66cSDavid du Colombier */ 7534e04225SDavid du Colombier con = fid->con; 7661201b97SDavid du Colombier if(t->afid == NOFID){ 775e96a66cSDavid du Colombier /* 785e96a66cSDavid du Colombier * If no authentication is asked for, allow 795e96a66cSDavid du Colombier * "none" provided the connection has already 805e96a66cSDavid du Colombier * been authenticatated. 8161201b97SDavid du Colombier * 825e96a66cSDavid du Colombier * The console is allowed to attach without 835e96a66cSDavid du Colombier * authentication. 845e96a66cSDavid du Colombier */ 8534e04225SDavid du Colombier vtRLock(con->alock); 862cca75a1SDavid du Colombier if(con->isconsole){ 872cca75a1SDavid du Colombier /* anything goes */ 882cca75a1SDavid du Colombier }else if((con->flags&ConNoneAllow) || con->aok){ 89*208510e1SDavid du Colombier static int noneprint; 90*208510e1SDavid du Colombier 91*208510e1SDavid du Colombier if(noneprint++ < 10) 92*208510e1SDavid du Colombier consPrint("attach %s as %s: allowing as none\n", 93*208510e1SDavid du Colombier fsysGetName(fsys), fid->uname); 942cca75a1SDavid du Colombier vtMemFree(fid->uname); 952cca75a1SDavid du Colombier fid->uname = vtStrDup(unamenone); 962cca75a1SDavid du Colombier }else{ 9734e04225SDavid du Colombier vtRUnlock(con->alock); 98*208510e1SDavid du Colombier consPrint("attach %s as %s: connection not authenticated, not console\n", 99*208510e1SDavid du Colombier fsysGetName(fsys), fid->uname); 1002cca75a1SDavid du Colombier vtSetError("cannot attach as none before authentication"); 1015e96a66cSDavid du Colombier return 0; 10261201b97SDavid du Colombier } 10334e04225SDavid du Colombier vtRUnlock(con->alock); 10461201b97SDavid du Colombier 10561201b97SDavid du Colombier if((fid->uid = uidByUname(fid->uname)) == nil){ 106*208510e1SDavid du Colombier consPrint("attach %s as %s: unknown uname\n", 107*208510e1SDavid du Colombier fsysGetName(fsys), fid->uname); 1082cca75a1SDavid du Colombier vtSetError("unknown user"); 1095e96a66cSDavid du Colombier return 0; 11061201b97SDavid du Colombier } 1115e96a66cSDavid du Colombier return 1; 1125e96a66cSDavid du Colombier } 1135e96a66cSDavid du Colombier 11434e04225SDavid du Colombier if((afid = fidGet(con, t->afid, 0)) == nil){ 11561201b97SDavid du Colombier consPrint("attach %s as %s: bad afid\n", fsysGetName(fsys), fid->uname); 1162cca75a1SDavid du Colombier vtSetError("bad authentication fid"); 11761201b97SDavid du Colombier return 0; 11861201b97SDavid du Colombier } 11961201b97SDavid du Colombier 1205e96a66cSDavid du Colombier /* 1215e96a66cSDavid du Colombier * Check valid afid; 1225e96a66cSDavid du Colombier * check uname and aname match. 1235e96a66cSDavid du Colombier */ 1245e96a66cSDavid du Colombier if(!(afid->qid.type & QTAUTH)){ 125*208510e1SDavid du Colombier consPrint("attach %s as %s: afid not an auth file\n", fsysGetName(fsys), 126*208510e1SDavid du Colombier fid->uname); 1275e96a66cSDavid du Colombier fidPut(afid); 1282cca75a1SDavid du Colombier vtSetError("bad authentication fid"); 1295e96a66cSDavid du Colombier return 0; 1305e96a66cSDavid du Colombier } 1315e96a66cSDavid du Colombier if(strcmp(afid->uname, fid->uname) != 0 || afid->fsys != fsys){ 132*208510e1SDavid du Colombier consPrint("attach %s as %s: afid is for %s as %s\n", fsysGetName(fsys), 133*208510e1SDavid du Colombier fid->uname, fsysGetName(afid->fsys), afid->uname); 1345e96a66cSDavid du Colombier fidPut(afid); 1352cca75a1SDavid du Colombier vtSetError("attach/auth mismatch"); 1365e96a66cSDavid du Colombier return 0; 1375e96a66cSDavid du Colombier } 1385e96a66cSDavid du Colombier 1395e96a66cSDavid du Colombier vtLock(afid->alock); 1405e96a66cSDavid du Colombier if(afid->cuname == nil){ 1415e96a66cSDavid du Colombier if(authRead(afid, buf, 0) != 0 || afid->cuname == nil){ 1425e96a66cSDavid du Colombier vtUnlock(afid->alock); 14381cf8742SDavid du Colombier consPrint("attach %s as %s: %R\n", fsysGetName(fsys), fid->uname); 1445e96a66cSDavid du Colombier fidPut(afid); 145*208510e1SDavid du Colombier vtSetError("fossil authCheck: auth protocol not finished"); 1465e96a66cSDavid du Colombier return 0; 1475e96a66cSDavid du Colombier } 1485e96a66cSDavid du Colombier } 1495e96a66cSDavid du Colombier vtUnlock(afid->alock); 1505e96a66cSDavid du Colombier 1515e96a66cSDavid du Colombier assert(fid->uid == nil); 1525e96a66cSDavid du Colombier if((fid->uid = uidByUname(afid->cuname)) == nil){ 153*208510e1SDavid du Colombier consPrint("attach %s as %s: unknown cuname %s\n", fsysGetName(fsys), 154*208510e1SDavid du Colombier fid->uname, afid->cuname); 1555e96a66cSDavid du Colombier fidPut(afid); 1562cca75a1SDavid du Colombier vtSetError("unknown user"); 1575e96a66cSDavid du Colombier return 0; 1585e96a66cSDavid du Colombier } 1595e96a66cSDavid du Colombier 1605e96a66cSDavid du Colombier vtMemFree(fid->uname); 1615e96a66cSDavid du Colombier fid->uname = vtStrDup(afid->cuname); 1625e96a66cSDavid du Colombier fidPut(afid); 1635e96a66cSDavid du Colombier 1645e96a66cSDavid du Colombier /* 1655e96a66cSDavid du Colombier * Allow "none" once the connection has been authenticated. 1665e96a66cSDavid du Colombier */ 16734e04225SDavid du Colombier vtLock(con->alock); 16834e04225SDavid du Colombier con->aok = 1; 16934e04225SDavid du Colombier vtUnlock(con->alock); 1705e96a66cSDavid du Colombier 1715e96a66cSDavid du Colombier return 1; 1725e96a66cSDavid du Colombier } 173