xref: /plan9/sys/src/lib9p/auth.c (revision 22a127bbfe4dd304949cc596400de973c0138e31)
1*22a127bbSDavid du Colombier #include <u.h>
2*22a127bbSDavid du Colombier #include <libc.h>
3*22a127bbSDavid du Colombier #include <auth.h>
4*22a127bbSDavid du Colombier #include <fcall.h>
5*22a127bbSDavid du Colombier #include <thread.h>
6*22a127bbSDavid du Colombier #include <9p.h>
7*22a127bbSDavid du Colombier 
8*22a127bbSDavid du Colombier typedef struct Afid Afid;
9*22a127bbSDavid du Colombier 
10*22a127bbSDavid du Colombier struct Afid
11*22a127bbSDavid du Colombier {
12*22a127bbSDavid du Colombier 	AuthRpc *rpc;
13*22a127bbSDavid du Colombier 	char *uname;
14*22a127bbSDavid du Colombier 	char *aname;
15*22a127bbSDavid du Colombier 	int authok;
16*22a127bbSDavid du Colombier 	int afd;
17*22a127bbSDavid du Colombier };
18*22a127bbSDavid du Colombier 
19*22a127bbSDavid du Colombier static uvlong authgen = 1ULL<<63;
20*22a127bbSDavid du Colombier 
21*22a127bbSDavid du Colombier void
auth9p(Req * r)22*22a127bbSDavid du Colombier auth9p(Req *r)
23*22a127bbSDavid du Colombier {
24*22a127bbSDavid du Colombier 	char *spec;
25*22a127bbSDavid du Colombier 	Afid *afid;
26*22a127bbSDavid du Colombier 
27*22a127bbSDavid du Colombier 	afid = emalloc9p(sizeof(Afid));
28*22a127bbSDavid du Colombier 	afid->afd = open("/mnt/factotum/rpc", ORDWR);
29*22a127bbSDavid du Colombier 	if(afid->afd < 0)
30*22a127bbSDavid du Colombier 		goto error;
31*22a127bbSDavid du Colombier 
32*22a127bbSDavid du Colombier 	if((afid->rpc = auth_allocrpc(afid->afd)) == nil)
33*22a127bbSDavid du Colombier 		goto error;
34*22a127bbSDavid du Colombier 
35*22a127bbSDavid du Colombier 	if(r->ifcall.uname[0] == 0)
36*22a127bbSDavid du Colombier 		goto error;
37*22a127bbSDavid du Colombier 	afid->uname = estrdup9p(r->ifcall.uname);
38*22a127bbSDavid du Colombier 	afid->aname = estrdup9p(r->ifcall.aname);
39*22a127bbSDavid du Colombier 
40*22a127bbSDavid du Colombier 	spec = r->srv->keyspec;
41*22a127bbSDavid du Colombier 	if(spec == nil)
42*22a127bbSDavid du Colombier 		spec = "proto=p9any role=server";
43*22a127bbSDavid du Colombier 
44*22a127bbSDavid du Colombier 	if(auth_rpc(afid->rpc, "start", spec, strlen(spec)) != ARok)
45*22a127bbSDavid du Colombier 		goto error;
46*22a127bbSDavid du Colombier 
47*22a127bbSDavid du Colombier 	r->afid->qid.type = QTAUTH;
48*22a127bbSDavid du Colombier 	r->afid->qid.path = ++authgen;
49*22a127bbSDavid du Colombier 	r->afid->qid.vers = 0;
50*22a127bbSDavid du Colombier 	r->afid->omode = ORDWR;
51*22a127bbSDavid du Colombier 	r->ofcall.qid = r->afid->qid;
52*22a127bbSDavid du Colombier 	r->afid->aux = afid;
53*22a127bbSDavid du Colombier 	respond(r, nil);
54*22a127bbSDavid du Colombier 	return;
55*22a127bbSDavid du Colombier 
56*22a127bbSDavid du Colombier error:
57*22a127bbSDavid du Colombier 	if(afid->rpc)
58*22a127bbSDavid du Colombier 		auth_freerpc(afid->rpc);
59*22a127bbSDavid du Colombier 	if(afid->uname)
60*22a127bbSDavid du Colombier 		free(afid->uname);
61*22a127bbSDavid du Colombier 	if(afid->aname)
62*22a127bbSDavid du Colombier 		free(afid->aname);
63*22a127bbSDavid du Colombier 	if(afid->afd >= 0)
64*22a127bbSDavid du Colombier 		close(afid->afd);
65*22a127bbSDavid du Colombier 	free(afid);
66*22a127bbSDavid du Colombier 	responderror(r);
67*22a127bbSDavid du Colombier }
68*22a127bbSDavid du Colombier 
69*22a127bbSDavid du Colombier static int
_authread(Afid * afid,void * data,int count)70*22a127bbSDavid du Colombier _authread(Afid *afid, void *data, int count)
71*22a127bbSDavid du Colombier {
72*22a127bbSDavid du Colombier 	AuthInfo *ai;
73*22a127bbSDavid du Colombier 
74*22a127bbSDavid du Colombier 	switch(auth_rpc(afid->rpc, "read", nil, 0)){
75*22a127bbSDavid du Colombier 	case ARdone:
76*22a127bbSDavid du Colombier 		ai = auth_getinfo(afid->rpc);
77*22a127bbSDavid du Colombier 		if(ai == nil)
78*22a127bbSDavid du Colombier 			return -1;
79*22a127bbSDavid du Colombier 		auth_freeAI(ai);
80*22a127bbSDavid du Colombier 		if(chatty9p)
81*22a127bbSDavid du Colombier 			fprint(2, "authenticate %s/%s: ok\n", afid->uname, afid->aname);
82*22a127bbSDavid du Colombier 		afid->authok = 1;
83*22a127bbSDavid du Colombier 		return 0;
84*22a127bbSDavid du Colombier 
85*22a127bbSDavid du Colombier 	case ARok:
86*22a127bbSDavid du Colombier 		if(count < afid->rpc->narg){
87*22a127bbSDavid du Colombier 			werrstr("authread count too small");
88*22a127bbSDavid du Colombier 			return -1;
89*22a127bbSDavid du Colombier 		}
90*22a127bbSDavid du Colombier 		count = afid->rpc->narg;
91*22a127bbSDavid du Colombier 		memmove(data, afid->rpc->arg, count);
92*22a127bbSDavid du Colombier 		return count;
93*22a127bbSDavid du Colombier 
94*22a127bbSDavid du Colombier 	case ARphase:
95*22a127bbSDavid du Colombier 	default:
96*22a127bbSDavid du Colombier 		werrstr("authrpc botch");
97*22a127bbSDavid du Colombier 		return -1;
98*22a127bbSDavid du Colombier 	}
99*22a127bbSDavid du Colombier }
100*22a127bbSDavid du Colombier 
101*22a127bbSDavid du Colombier void
authread(Req * r)102*22a127bbSDavid du Colombier authread(Req *r)
103*22a127bbSDavid du Colombier {
104*22a127bbSDavid du Colombier 	int n;
105*22a127bbSDavid du Colombier 	Afid *afid;
106*22a127bbSDavid du Colombier 	Fid *fid;
107*22a127bbSDavid du Colombier 
108*22a127bbSDavid du Colombier 	fid = r->fid;
109*22a127bbSDavid du Colombier 	afid = fid->aux;
110*22a127bbSDavid du Colombier 	if(afid == nil || r->fid->qid.type != QTAUTH){
111*22a127bbSDavid du Colombier 		respond(r, "not an auth fid");
112*22a127bbSDavid du Colombier 		return;
113*22a127bbSDavid du Colombier 	}
114*22a127bbSDavid du Colombier 	n = _authread(afid, r->ofcall.data, r->ifcall.count);
115*22a127bbSDavid du Colombier 	if(n < 0){
116*22a127bbSDavid du Colombier 		responderror(r);
117*22a127bbSDavid du Colombier 		return;
118*22a127bbSDavid du Colombier 	}
119*22a127bbSDavid du Colombier 	r->ofcall.count = n;
120*22a127bbSDavid du Colombier 	respond(r, nil);
121*22a127bbSDavid du Colombier }
122*22a127bbSDavid du Colombier 
123*22a127bbSDavid du Colombier void
authwrite(Req * r)124*22a127bbSDavid du Colombier authwrite(Req *r)
125*22a127bbSDavid du Colombier {
126*22a127bbSDavid du Colombier 	Afid *afid;
127*22a127bbSDavid du Colombier 	Fid *fid;
128*22a127bbSDavid du Colombier 
129*22a127bbSDavid du Colombier 	fid = r->fid;
130*22a127bbSDavid du Colombier 	afid = fid->aux;
131*22a127bbSDavid du Colombier 	if(afid == nil || r->fid->qid.type != QTAUTH){
132*22a127bbSDavid du Colombier 		respond(r, "not an auth fid");
133*22a127bbSDavid du Colombier 		return;
134*22a127bbSDavid du Colombier 	}
135*22a127bbSDavid du Colombier 	if(auth_rpc(afid->rpc, "write", r->ifcall.data, r->ifcall.count) != ARok){
136*22a127bbSDavid du Colombier 		responderror(r);
137*22a127bbSDavid du Colombier 		return;
138*22a127bbSDavid du Colombier 	}
139*22a127bbSDavid du Colombier 	r->ofcall.count = r->ifcall.count;
140*22a127bbSDavid du Colombier 	respond(r, nil);
141*22a127bbSDavid du Colombier }
142*22a127bbSDavid du Colombier 
143*22a127bbSDavid du Colombier void
authdestroy(Fid * fid)144*22a127bbSDavid du Colombier authdestroy(Fid *fid)
145*22a127bbSDavid du Colombier {
146*22a127bbSDavid du Colombier 	Afid *afid;
147*22a127bbSDavid du Colombier 
148*22a127bbSDavid du Colombier 	if((fid->qid.type & QTAUTH) && (afid = fid->aux) != nil){
149*22a127bbSDavid du Colombier 		if(afid->rpc)
150*22a127bbSDavid du Colombier 			auth_freerpc(afid->rpc);
151*22a127bbSDavid du Colombier 		close(afid->afd);
152*22a127bbSDavid du Colombier 		free(afid->uname);
153*22a127bbSDavid du Colombier 		free(afid->aname);
154*22a127bbSDavid du Colombier 		free(afid);
155*22a127bbSDavid du Colombier 		fid->aux = nil;
156*22a127bbSDavid du Colombier 	}
157*22a127bbSDavid du Colombier }
158*22a127bbSDavid du Colombier 
159*22a127bbSDavid du Colombier int
authattach(Req * r)160*22a127bbSDavid du Colombier authattach(Req *r)
161*22a127bbSDavid du Colombier {
162*22a127bbSDavid du Colombier 	Afid *afid;
163*22a127bbSDavid du Colombier 	char buf[ERRMAX];
164*22a127bbSDavid du Colombier 
165*22a127bbSDavid du Colombier 	if(r->afid == nil){
166*22a127bbSDavid du Colombier 		respond(r, "not authenticated");
167*22a127bbSDavid du Colombier 		return -1;
168*22a127bbSDavid du Colombier 	}
169*22a127bbSDavid du Colombier 
170*22a127bbSDavid du Colombier 	afid = r->afid->aux;
171*22a127bbSDavid du Colombier 	if((r->afid->qid.type&QTAUTH) == 0 || afid == nil){
172*22a127bbSDavid du Colombier 		respond(r, "not an auth fid");
173*22a127bbSDavid du Colombier 		return -1;
174*22a127bbSDavid du Colombier 	}
175*22a127bbSDavid du Colombier 
176*22a127bbSDavid du Colombier 	if(!afid->authok){
177*22a127bbSDavid du Colombier 		if(_authread(afid, buf, 0) < 0){
178*22a127bbSDavid du Colombier 			responderror(r);
179*22a127bbSDavid du Colombier 			return -1;
180*22a127bbSDavid du Colombier 		}
181*22a127bbSDavid du Colombier 	}
182*22a127bbSDavid du Colombier 
183*22a127bbSDavid du Colombier 	if(strcmp(afid->uname, r->ifcall.uname) != 0){
184*22a127bbSDavid du Colombier 		snprint(buf, sizeof buf, "auth uname mismatch: %s vs %s",
185*22a127bbSDavid du Colombier 			afid->uname, r->ifcall.uname);
186*22a127bbSDavid du Colombier 		respond(r, buf);
187*22a127bbSDavid du Colombier 		return -1;
188*22a127bbSDavid du Colombier 	}
189*22a127bbSDavid du Colombier 
190*22a127bbSDavid du Colombier 	if(strcmp(afid->aname, r->ifcall.aname) != 0){
191*22a127bbSDavid du Colombier 		snprint(buf, sizeof buf, "auth aname mismatch: %s vs %s",
192*22a127bbSDavid du Colombier 			afid->aname, r->ifcall.aname);
193*22a127bbSDavid du Colombier 		respond(r, buf);
194*22a127bbSDavid du Colombier 		return -1;
195*22a127bbSDavid du Colombier 	}
196*22a127bbSDavid du Colombier 	return 0;
197*22a127bbSDavid du Colombier }
198*22a127bbSDavid du Colombier 
199