xref: /plan9-contrib/sys/src/cmd/fossil/9auth.c (revision 5e96a66c77eb9140492ca53f857cbbf108e128ed)
1*5e96a66cSDavid du Colombier #include "stdinc.h"
2*5e96a66cSDavid du Colombier 
3*5e96a66cSDavid du Colombier #include "9.h"
4*5e96a66cSDavid du Colombier 
5*5e96a66cSDavid du Colombier int
6*5e96a66cSDavid du Colombier authRead(Fid* afid, void* data, int count)
7*5e96a66cSDavid du Colombier {
8*5e96a66cSDavid du Colombier 	AuthInfo *ai;
9*5e96a66cSDavid du Colombier 	AuthRpc *rpc;
10*5e96a66cSDavid du Colombier 
11*5e96a66cSDavid du Colombier 	if((rpc = afid->rpc) == nil)
12*5e96a66cSDavid du Colombier 		return -1;
13*5e96a66cSDavid du Colombier 
14*5e96a66cSDavid du Colombier 	switch(auth_rpc(rpc, "read", nil, 0)){
15*5e96a66cSDavid du Colombier 	default:
16*5e96a66cSDavid du Colombier 		return -1;
17*5e96a66cSDavid du Colombier 	case ARdone:
18*5e96a66cSDavid du Colombier 		if((ai = auth_getinfo(rpc)) == nil)
19*5e96a66cSDavid du Colombier 			break;
20*5e96a66cSDavid du Colombier 		if(ai->cuid == nil || *ai->cuid == '\0'){
21*5e96a66cSDavid du Colombier 			auth_freeAI(ai);
22*5e96a66cSDavid du Colombier 			break;
23*5e96a66cSDavid du Colombier 		}
24*5e96a66cSDavid du Colombier 		assert(afid->cuname == nil);
25*5e96a66cSDavid du Colombier 		afid->cuname = vtStrDup(ai->cuid);
26*5e96a66cSDavid du Colombier 		auth_freeAI(ai);
27*5e96a66cSDavid du Colombier 		if(Dflag)
28*5e96a66cSDavid du Colombier 			fprint(2, "authRead cuname %s\n", afid->cuname);
29*5e96a66cSDavid du Colombier 		assert(afid->uid == nil);
30*5e96a66cSDavid du Colombier 		if((afid->uid = uidByUname(afid->cuname)) == nil)
31*5e96a66cSDavid du Colombier 			break;
32*5e96a66cSDavid du Colombier 		return 0;
33*5e96a66cSDavid du Colombier 	case ARok:
34*5e96a66cSDavid du Colombier 		if(count < rpc->narg)
35*5e96a66cSDavid du Colombier 			break;
36*5e96a66cSDavid du Colombier 		memmove(data, rpc->arg, rpc->narg);
37*5e96a66cSDavid du Colombier 		return rpc->narg;
38*5e96a66cSDavid du Colombier 	case ARphase:
39*5e96a66cSDavid du Colombier 		break;
40*5e96a66cSDavid du Colombier 	}
41*5e96a66cSDavid du Colombier 	return -1;
42*5e96a66cSDavid du Colombier }
43*5e96a66cSDavid du Colombier 
44*5e96a66cSDavid du Colombier int
45*5e96a66cSDavid du Colombier authWrite(Fid* afid, void* data, int count)
46*5e96a66cSDavid du Colombier {
47*5e96a66cSDavid du Colombier 	assert(afid->rpc != nil);
48*5e96a66cSDavid du Colombier 	if(auth_rpc(afid->rpc, "write", data, count) != ARok)
49*5e96a66cSDavid du Colombier 		return -1;
50*5e96a66cSDavid du Colombier 	return count;
51*5e96a66cSDavid du Colombier }
52*5e96a66cSDavid du Colombier 
53*5e96a66cSDavid du Colombier int
54*5e96a66cSDavid du Colombier authCheck(Fcall* t, Fid* fid, Fs* fsys)
55*5e96a66cSDavid du Colombier {
56*5e96a66cSDavid du Colombier 	Fid *afid;
57*5e96a66cSDavid du Colombier 	uchar buf[1];
58*5e96a66cSDavid du Colombier 
59*5e96a66cSDavid du Colombier 	/*
60*5e96a66cSDavid du Colombier 	 * Can't lookup with FidWlock here as there may be
61*5e96a66cSDavid du Colombier 	 * protocol to do. Use a separate lock to protect altering
62*5e96a66cSDavid du Colombier 	 * the auth information inside afid.
63*5e96a66cSDavid du Colombier 	 */
64*5e96a66cSDavid du Colombier 	if((afid = fidGet(fid->con, t->afid, 0)) == nil){
65*5e96a66cSDavid du Colombier 		/*
66*5e96a66cSDavid du Colombier 		 * If no authentication is asked for, allow
67*5e96a66cSDavid du Colombier 		 * "none" provided the connection has already
68*5e96a66cSDavid du Colombier 		 * been authenticatated.
69*5e96a66cSDavid du Colombier 		 */
70*5e96a66cSDavid du Colombier 		if(strcmp(fid->uname, unamenone) == 0 && fid->con->aok){
71*5e96a66cSDavid du Colombier 			if((fid->uid = uidByUname(fid->uname)) == nil)
72*5e96a66cSDavid du Colombier 				return 0;
73*5e96a66cSDavid du Colombier 			return 1;
74*5e96a66cSDavid du Colombier 		}
75*5e96a66cSDavid du Colombier 
76*5e96a66cSDavid du Colombier 		/*
77*5e96a66cSDavid du Colombier 		 * The console is allowed to attach without
78*5e96a66cSDavid du Colombier 		 * authentication.
79*5e96a66cSDavid du Colombier 		 */
80*5e96a66cSDavid du Colombier 		if(!fid->con->isconsole)
81*5e96a66cSDavid du Colombier 			return 0;
82*5e96a66cSDavid du Colombier 		if((fid->uid = uidByUname(fid->uname)) == nil)
83*5e96a66cSDavid du Colombier 			return 0;
84*5e96a66cSDavid du Colombier 		return 1;
85*5e96a66cSDavid du Colombier 	}
86*5e96a66cSDavid du Colombier 
87*5e96a66cSDavid du Colombier 	/*
88*5e96a66cSDavid du Colombier 	 * Check valid afid;
89*5e96a66cSDavid du Colombier 	 * check uname and aname match.
90*5e96a66cSDavid du Colombier 	 */
91*5e96a66cSDavid du Colombier 	if(!(afid->qid.type & QTAUTH)){
92*5e96a66cSDavid du Colombier 		fidPut(afid);
93*5e96a66cSDavid du Colombier 		return 0;
94*5e96a66cSDavid du Colombier 	}
95*5e96a66cSDavid du Colombier 	if(strcmp(afid->uname, fid->uname) != 0 || afid->fsys != fsys){
96*5e96a66cSDavid du Colombier 		fidPut(afid);
97*5e96a66cSDavid du Colombier 		return 0;
98*5e96a66cSDavid du Colombier 	}
99*5e96a66cSDavid du Colombier 
100*5e96a66cSDavid du Colombier 	vtLock(afid->alock);
101*5e96a66cSDavid du Colombier 	if(afid->cuname == nil){
102*5e96a66cSDavid du Colombier 		if(authRead(afid, buf, 0) != 0 || afid->cuname == nil){
103*5e96a66cSDavid du Colombier 			vtUnlock(afid->alock);
104*5e96a66cSDavid du Colombier 			fidPut(afid);
105*5e96a66cSDavid du Colombier 			return 0;
106*5e96a66cSDavid du Colombier 		}
107*5e96a66cSDavid du Colombier 	}
108*5e96a66cSDavid du Colombier 	vtUnlock(afid->alock);
109*5e96a66cSDavid du Colombier 
110*5e96a66cSDavid du Colombier 	assert(fid->uid == nil);
111*5e96a66cSDavid du Colombier 	if((fid->uid = uidByUname(afid->cuname)) == nil){
112*5e96a66cSDavid du Colombier 		fidPut(afid);
113*5e96a66cSDavid du Colombier 		return 0;
114*5e96a66cSDavid du Colombier 	}
115*5e96a66cSDavid du Colombier 
116*5e96a66cSDavid du Colombier 	vtMemFree(fid->uname);
117*5e96a66cSDavid du Colombier 	fid->uname = vtStrDup(afid->cuname);
118*5e96a66cSDavid du Colombier 	fidPut(afid);
119*5e96a66cSDavid du Colombier 
120*5e96a66cSDavid du Colombier 	/*
121*5e96a66cSDavid du Colombier 	 * Allow "none" once the connection has been authenticated.
122*5e96a66cSDavid du Colombier 	 */
123*5e96a66cSDavid du Colombier 	fid->con->aok = 1;
124*5e96a66cSDavid du Colombier 
125*5e96a66cSDavid du Colombier 	return 1;
126*5e96a66cSDavid du Colombier }
127