xref: /plan9/sys/src/cmd/fossil/9auth.c (revision 34e0422554c8e8bef66509534d2c44f4660bf678)
15e96a66cSDavid du Colombier #include "stdinc.h"
25e96a66cSDavid du Colombier 
35e96a66cSDavid du Colombier #include "9.h"
45e96a66cSDavid du Colombier 
55e96a66cSDavid du Colombier int
65e96a66cSDavid du Colombier authRead(Fid* afid, void* data, int count)
75e96a66cSDavid du Colombier {
85e96a66cSDavid du Colombier 	AuthInfo *ai;
95e96a66cSDavid du Colombier 	AuthRpc *rpc;
105e96a66cSDavid du Colombier 
115e96a66cSDavid du Colombier 	if((rpc = afid->rpc) == nil)
125e96a66cSDavid du Colombier 		return -1;
135e96a66cSDavid du Colombier 
145e96a66cSDavid du Colombier 	switch(auth_rpc(rpc, "read", nil, 0)){
155e96a66cSDavid du Colombier 	default:
165e96a66cSDavid du Colombier 		return -1;
175e96a66cSDavid du Colombier 	case ARdone:
185e96a66cSDavid du Colombier 		if((ai = auth_getinfo(rpc)) == nil)
195e96a66cSDavid du Colombier 			break;
205e96a66cSDavid du Colombier 		if(ai->cuid == nil || *ai->cuid == '\0'){
215e96a66cSDavid du Colombier 			auth_freeAI(ai);
225e96a66cSDavid du Colombier 			break;
235e96a66cSDavid du Colombier 		}
245e96a66cSDavid du Colombier 		assert(afid->cuname == nil);
255e96a66cSDavid du Colombier 		afid->cuname = vtStrDup(ai->cuid);
265e96a66cSDavid du Colombier 		auth_freeAI(ai);
275e96a66cSDavid du Colombier 		if(Dflag)
285e96a66cSDavid du Colombier 			fprint(2, "authRead cuname %s\n", afid->cuname);
295e96a66cSDavid du Colombier 		assert(afid->uid == nil);
305e96a66cSDavid du Colombier 		if((afid->uid = uidByUname(afid->cuname)) == nil)
315e96a66cSDavid du Colombier 			break;
325e96a66cSDavid du Colombier 		return 0;
335e96a66cSDavid du Colombier 	case ARok:
345e96a66cSDavid du Colombier 		if(count < rpc->narg)
355e96a66cSDavid du Colombier 			break;
365e96a66cSDavid du Colombier 		memmove(data, rpc->arg, rpc->narg);
375e96a66cSDavid du Colombier 		return rpc->narg;
385e96a66cSDavid du Colombier 	case ARphase:
395e96a66cSDavid du Colombier 		break;
405e96a66cSDavid du Colombier 	}
415e96a66cSDavid du Colombier 	return -1;
425e96a66cSDavid du Colombier }
435e96a66cSDavid du Colombier 
445e96a66cSDavid du Colombier int
455e96a66cSDavid du Colombier authWrite(Fid* afid, void* data, int count)
465e96a66cSDavid du Colombier {
475e96a66cSDavid du Colombier 	assert(afid->rpc != nil);
485e96a66cSDavid du Colombier 	if(auth_rpc(afid->rpc, "write", data, count) != ARok)
495e96a66cSDavid du Colombier 		return -1;
505e96a66cSDavid du Colombier 	return count;
515e96a66cSDavid du Colombier }
525e96a66cSDavid du Colombier 
535e96a66cSDavid du Colombier int
545e96a66cSDavid du Colombier authCheck(Fcall* t, Fid* fid, Fs* fsys)
555e96a66cSDavid du Colombier {
56*34e04225SDavid du Colombier 	Con *con;
575e96a66cSDavid du Colombier 	Fid *afid;
585e96a66cSDavid du Colombier 	uchar buf[1];
595e96a66cSDavid du Colombier 
605e96a66cSDavid du Colombier 	/*
615e96a66cSDavid du Colombier 	 * Can't lookup with FidWlock here as there may be
625e96a66cSDavid du Colombier 	 * protocol to do. Use a separate lock to protect altering
635e96a66cSDavid du Colombier 	 * the auth information inside afid.
645e96a66cSDavid du Colombier 	 */
65*34e04225SDavid du Colombier 	con = fid->con;
6661201b97SDavid du Colombier 	if(t->afid == NOFID){
675e96a66cSDavid du Colombier 		/*
685e96a66cSDavid du Colombier 		 * If no authentication is asked for, allow
695e96a66cSDavid du Colombier 		 * "none" provided the connection has already
705e96a66cSDavid du Colombier 		 * been authenticatated.
7161201b97SDavid du Colombier 		 *
725e96a66cSDavid du Colombier 		 * The console is allowed to attach without
735e96a66cSDavid du Colombier 		 * authentication.
745e96a66cSDavid du Colombier 		 */
75*34e04225SDavid du Colombier 		vtRLock(con->alock);
76*34e04225SDavid du Colombier 		if(!con->isconsole &&
77*34e04225SDavid du Colombier 		(strcmp(fid->uname, unamenone) != 0 || !con->aok)){
78*34e04225SDavid du Colombier 			vtRUnlock(con->alock);
7961201b97SDavid du Colombier 			consPrint("attach %s as %s: connection not authenticated, not console\n", fsysGetName(fsys), fid->uname);
805e96a66cSDavid du Colombier 			return 0;
8161201b97SDavid du Colombier 		}
82*34e04225SDavid du Colombier 		vtRUnlock(con->alock);
8361201b97SDavid du Colombier 
8461201b97SDavid du Colombier 		if((fid->uid = uidByUname(fid->uname)) == nil){
8561201b97SDavid du Colombier 			consPrint("attach %s as %s: unknown uname\n", fsysGetName(fsys), fid->uname);
865e96a66cSDavid du Colombier 			return 0;
8761201b97SDavid du Colombier 		}
885e96a66cSDavid du Colombier 		return 1;
895e96a66cSDavid du Colombier 	}
905e96a66cSDavid du Colombier 
91*34e04225SDavid du Colombier 	if((afid = fidGet(con, t->afid, 0)) == nil){
9261201b97SDavid du Colombier 		consPrint("attach %s as %s: bad afid\n", fsysGetName(fsys), fid->uname);
9361201b97SDavid du Colombier 		return 0;
9461201b97SDavid du Colombier 	}
9561201b97SDavid du Colombier 
965e96a66cSDavid du Colombier 	/*
975e96a66cSDavid du Colombier 	 * Check valid afid;
985e96a66cSDavid du Colombier 	 * check uname and aname match.
995e96a66cSDavid du Colombier 	 */
1005e96a66cSDavid du Colombier 	if(!(afid->qid.type & QTAUTH)){
10161201b97SDavid du Colombier 		consPrint("attach %s as %s: afid not an auth file\n", fsysGetName(fsys), fid->uname);
1025e96a66cSDavid du Colombier 		fidPut(afid);
1035e96a66cSDavid du Colombier 		return 0;
1045e96a66cSDavid du Colombier 	}
1055e96a66cSDavid du Colombier 	if(strcmp(afid->uname, fid->uname) != 0 || afid->fsys != fsys){
10661201b97SDavid du Colombier 		consPrint("attach %s as %s: afid is for %s as %s\n", fsysGetName(fsys), fid->uname, fsysGetName(afid->fsys), afid->uname);
1075e96a66cSDavid du Colombier 		fidPut(afid);
1085e96a66cSDavid du Colombier 		return 0;
1095e96a66cSDavid du Colombier 	}
1105e96a66cSDavid du Colombier 
1115e96a66cSDavid du Colombier 	vtLock(afid->alock);
1125e96a66cSDavid du Colombier 	if(afid->cuname == nil){
1135e96a66cSDavid du Colombier 		if(authRead(afid, buf, 0) != 0 || afid->cuname == nil){
1145e96a66cSDavid du Colombier 			vtUnlock(afid->alock);
11561201b97SDavid du Colombier 			consPrint("attach %s as %s: auth protocol not finished\n", fsysGetName(fsys), fid->uname);
1165e96a66cSDavid du Colombier 			fidPut(afid);
1175e96a66cSDavid du Colombier 			return 0;
1185e96a66cSDavid du Colombier 		}
1195e96a66cSDavid du Colombier 	}
1205e96a66cSDavid du Colombier 	vtUnlock(afid->alock);
1215e96a66cSDavid du Colombier 
1225e96a66cSDavid du Colombier 	assert(fid->uid == nil);
1235e96a66cSDavid du Colombier 	if((fid->uid = uidByUname(afid->cuname)) == nil){
12461201b97SDavid du Colombier 		consPrint("attach %s as %s: unknown cuname %s\n", fsysGetName(fsys), fid->uname, afid->cuname);
1255e96a66cSDavid du Colombier 		fidPut(afid);
1265e96a66cSDavid du Colombier 		return 0;
1275e96a66cSDavid du Colombier 	}
1285e96a66cSDavid du Colombier 
1295e96a66cSDavid du Colombier 	vtMemFree(fid->uname);
1305e96a66cSDavid du Colombier 	fid->uname = vtStrDup(afid->cuname);
1315e96a66cSDavid du Colombier 	fidPut(afid);
1325e96a66cSDavid du Colombier 
1335e96a66cSDavid du Colombier 	/*
1345e96a66cSDavid du Colombier 	 * Allow "none" once the connection has been authenticated.
1355e96a66cSDavid du Colombier 	 */
136*34e04225SDavid du Colombier 	vtLock(con->alock);
137*34e04225SDavid du Colombier 	con->aok = 1;
138*34e04225SDavid du Colombier 	vtUnlock(con->alock);
1395e96a66cSDavid du Colombier 
1405e96a66cSDavid du Colombier 	return 1;
1415e96a66cSDavid du Colombier }
142