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