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