Blame


1 2277c5d7 2004-03-21 devnull /*
2 2277c5d7 2004-03-21 devnull * p9cr, vnc - one-sided challenge/response authentication
3 2277c5d7 2004-03-21 devnull *
4 2277c5d7 2004-03-21 devnull * Protocol:
5 2277c5d7 2004-03-21 devnull *
6 2277c5d7 2004-03-21 devnull * C -> S: user
7 2277c5d7 2004-03-21 devnull * S -> C: challenge
8 2277c5d7 2004-03-21 devnull * C -> S: response
9 2277c5d7 2004-03-21 devnull * S -> C: ok or bad
10 2277c5d7 2004-03-21 devnull *
11 2277c5d7 2004-03-21 devnull * Note that this is the protocol between factotum and the local
12 2277c5d7 2004-03-21 devnull * program, not between the two factotums. The information
13 2277c5d7 2004-03-21 devnull * exchanged here is wrapped in other protocols by the local
14 2277c5d7 2004-03-21 devnull * programs.
15 2277c5d7 2004-03-21 devnull */
16 2277c5d7 2004-03-21 devnull
17 2277c5d7 2004-03-21 devnull #include "std.h"
18 2277c5d7 2004-03-21 devnull #include "dat.h"
19 2277c5d7 2004-03-21 devnull
20 2277c5d7 2004-03-21 devnull static int
21 2277c5d7 2004-03-21 devnull p9crcheck(Key *k)
22 2277c5d7 2004-03-21 devnull {
23 2277c5d7 2004-03-21 devnull if(!strfindattr(k->attr, "user") || !strfindattr(k->privattr, "!password")){
24 2277c5d7 2004-03-21 devnull werrstr("need user and !password attributes");
25 2277c5d7 2004-03-21 devnull return -1;
26 2277c5d7 2004-03-21 devnull }
27 2277c5d7 2004-03-21 devnull return 0;
28 2277c5d7 2004-03-21 devnull }
29 2277c5d7 2004-03-21 devnull
30 2277c5d7 2004-03-21 devnull static int
31 2277c5d7 2004-03-21 devnull p9crclient(Conv *c)
32 2277c5d7 2004-03-21 devnull {
33 2277c5d7 2004-03-21 devnull char *chal, *pw, *res, *user;
34 2277c5d7 2004-03-21 devnull int astype, nchal, npw, ntry, ret;
35 2277c5d7 2004-03-21 devnull uchar resp[MD5dlen];
36 2277c5d7 2004-03-21 devnull Attr *attr;
37 2277c5d7 2004-03-21 devnull DigestState *ds;
38 2277c5d7 2004-03-21 devnull Key *k;
39 2277c5d7 2004-03-21 devnull
40 2277c5d7 2004-03-21 devnull chal = nil;
41 2277c5d7 2004-03-21 devnull k = nil;
42 2277c5d7 2004-03-21 devnull res = nil;
43 2277c5d7 2004-03-21 devnull ret = -1;
44 2277c5d7 2004-03-21 devnull attr = c->attr;
45 2277c5d7 2004-03-21 devnull
46 2277c5d7 2004-03-21 devnull if(c->proto == &p9cr){
47 2277c5d7 2004-03-21 devnull astype = AuthChal;
48 2277c5d7 2004-03-21 devnull challen = NETCHLEN;
49 2277c5d7 2004-03-21 devnull }else if(c->proto == &vnc){
50 2277c5d7 2004-03-21 devnull astype = AuthVnc;
51 2277c5d7 2004-03-21 devnull challen = MAXCHAL;
52 2277c5d7 2004-03-21 devnull }else{
53 2277c5d7 2004-03-21 devnull werrstr("bad proto");
54 2277c5d7 2004-03-21 devnull goto out;
55 2277c5d7 2004-03-21 devnull }
56 2277c5d7 2004-03-21 devnull
57 2277c5d7 2004-03-21 devnull c->state = "find key";
58 2277c5d7 2004-03-21 devnull k = keyfetch(c, "%A %s", attr, c->proto->keyprompt);
59 2277c5d7 2004-03-21 devnull if(k == nil)
60 2277c5d7 2004-03-21 devnull goto out;
61 2277c5d7 2004-03-21 devnull
62 2277c5d7 2004-03-21 devnull for(ntry=1;; ntry++){
63 2277c5d7 2004-03-21 devnull if(c->attr != attr)
64 2277c5d7 2004-03-21 devnull freeattr(c->attr);
65 2277c5d7 2004-03-21 devnull c->attr = addattrs(copyattr(attr), k->attr);
66 2277c5d7 2004-03-21 devnull if((pw = strfindattr(k->privattr, "!password")) == nil){
67 2277c5d7 2004-03-21 devnull werrstr("key has no !password (cannot happen)");
68 2277c5d7 2004-03-21 devnull goto out;
69 2277c5d7 2004-03-21 devnull }
70 2277c5d7 2004-03-21 devnull npw = strlen(pw);
71 2277c5d7 2004-03-21 devnull
72 2277c5d7 2004-03-21 devnull if((user = strfindattr(k->attr, "user")) == nil){
73 2277c5d7 2004-03-21 devnull werrstr("key has no user (cannot happen)");
74 2277c5d7 2004-03-21 devnull goto out;
75 2277c5d7 2004-03-21 devnull }
76 2277c5d7 2004-03-21 devnull
77 2277c5d7 2004-03-21 devnull if(convprint(c, "%s", user) < 0)
78 2277c5d7 2004-03-21 devnull goto out;
79 2277c5d7 2004-03-21 devnull
80 2277c5d7 2004-03-21 devnull if(convreadm(c, &chal) < 0)
81 2277c5d7 2004-03-21 devnull goto out;
82 2277c5d7 2004-03-21 devnull
83 2277c5d7 2004-03-21 devnull if((nresp = (*response)(chal, resp)) < 0)
84 2277c5d7 2004-03-21 devnull goto out;
85 2277c5d7 2004-03-21 devnull
86 2277c5d7 2004-03-21 devnull if(convwrite(c, resp, nresp) < 0)
87 2277c5d7 2004-03-21 devnull goto out;
88 2277c5d7 2004-03-21 devnull
89 2277c5d7 2004-03-21 devnull if(convreadm(c, &res) < 0)
90 2277c5d7 2004-03-21 devnull goto out;
91 2277c5d7 2004-03-21 devnull
92 2277c5d7 2004-03-21 devnull if(strcmp(res, "ok") == 0)
93 2277c5d7 2004-03-21 devnull break;
94 2277c5d7 2004-03-21 devnull
95 2277c5d7 2004-03-21 devnull if((k = keyreplace(c, k, "%s", res)) == nil){
96 2277c5d7 2004-03-21 devnull c->state = "auth failed";
97 2277c5d7 2004-03-21 devnull werrstr("%s", res);
98 2277c5d7 2004-03-21 devnull goto out;
99 2277c5d7 2004-03-21 devnull }
100 2277c5d7 2004-03-21 devnull }
101 2277c5d7 2004-03-21 devnull
102 2277c5d7 2004-03-21 devnull werrstr("succeeded");
103 2277c5d7 2004-03-21 devnull ret = 0;
104 2277c5d7 2004-03-21 devnull
105 2277c5d7 2004-03-21 devnull out:
106 2277c5d7 2004-03-21 devnull keyclose(k);
107 2277c5d7 2004-03-21 devnull free(chal);
108 2277c5d7 2004-03-21 devnull if(c->attr != attr)
109 2277c5d7 2004-03-21 devnull freeattr(attr);
110 2277c5d7 2004-03-21 devnull return ret;
111 2277c5d7 2004-03-21 devnull }
112 2277c5d7 2004-03-21 devnull
113 2277c5d7 2004-03-21 devnull static int
114 2277c5d7 2004-03-21 devnull p9crserver(Conv *c)
115 2277c5d7 2004-03-21 devnull {
116 2277c5d7 2004-03-21 devnull char chal[APOPCHALLEN], *user, *resp;
117 2277c5d7 2004-03-21 devnull ServerState s;
118 2277c5d7 2004-03-21 devnull int astype, ret;
119 2277c5d7 2004-03-21 devnull Attr *a;
120 2277c5d7 2004-03-21 devnull
121 2277c5d7 2004-03-21 devnull ret = -1;
122 2277c5d7 2004-03-21 devnull user = nil;
123 2277c5d7 2004-03-21 devnull resp = nil;
124 2277c5d7 2004-03-21 devnull memset(&s, 0, sizeof s);
125 2277c5d7 2004-03-21 devnull s.asfd = -1;
126 2277c5d7 2004-03-21 devnull
127 2277c5d7 2004-03-21 devnull if(c->proto == &apop)
128 2277c5d7 2004-03-21 devnull astype = AuthApop;
129 2277c5d7 2004-03-21 devnull else if(c->proto == &cram)
130 2277c5d7 2004-03-21 devnull astype = AuthCram;
131 2277c5d7 2004-03-21 devnull else{
132 2277c5d7 2004-03-21 devnull werrstr("bad proto");
133 2277c5d7 2004-03-21 devnull goto out;
134 2277c5d7 2004-03-21 devnull }
135 2277c5d7 2004-03-21 devnull
136 2277c5d7 2004-03-21 devnull c->state = "find key";
137 2277c5d7 2004-03-21 devnull if((s.k = plan9authkey(c->attr)) == nil)
138 2277c5d7 2004-03-21 devnull goto out;
139 2277c5d7 2004-03-21 devnull
140 2277c5d7 2004-03-21 devnull a = copyattr(s.k->attr);
141 2277c5d7 2004-03-21 devnull a = delattr(a, "proto");
142 2277c5d7 2004-03-21 devnull c->attr = addattrs(c->attr, a);
143 2277c5d7 2004-03-21 devnull freeattr(a);
144 2277c5d7 2004-03-21 devnull
145 2277c5d7 2004-03-21 devnull c->state = "authdial";
146 2277c5d7 2004-03-21 devnull s.hostid = strfindattr(s.k->attr, "user");
147 2277c5d7 2004-03-21 devnull s.dom = strfindattr(s.k->attr, "dom");
148 2277c5d7 2004-03-21 devnull if((s.asfd = xioauthdial(nil, s.dom)) < 0){
149 2277c5d7 2004-03-21 devnull werrstr("authdial %s: %r", s.dom);
150 2277c5d7 2004-03-21 devnull goto out;
151 2277c5d7 2004-03-21 devnull }
152 2277c5d7 2004-03-21 devnull
153 2277c5d7 2004-03-21 devnull c->state = "authchal";
154 2277c5d7 2004-03-21 devnull if(p9crchal(&s, astype, chal) < 0)
155 2277c5d7 2004-03-21 devnull goto out;
156 2277c5d7 2004-03-21 devnull
157 2277c5d7 2004-03-21 devnull c->state = "write challenge";
158 2277c5d7 2004-03-21 devnull if(convprint(c, "%s", chal) < 0)
159 2277c5d7 2004-03-21 devnull goto out;
160 2277c5d7 2004-03-21 devnull
161 2277c5d7 2004-03-21 devnull for(;;){
162 2277c5d7 2004-03-21 devnull c->state = "read user";
163 2277c5d7 2004-03-21 devnull if(convreadm(c, &user) < 0)
164 2277c5d7 2004-03-21 devnull goto out;
165 2277c5d7 2004-03-21 devnull
166 2277c5d7 2004-03-21 devnull c->state = "read response";
167 2277c5d7 2004-03-21 devnull if(convreadm(c, &resp) < 0)
168 2277c5d7 2004-03-21 devnull goto out;
169 2277c5d7 2004-03-21 devnull
170 2277c5d7 2004-03-21 devnull c->state = "authwrite";
171 2277c5d7 2004-03-21 devnull switch(apopresp(&s, user, resp)){
172 2277c5d7 2004-03-21 devnull case -1:
173 2277c5d7 2004-03-21 devnull goto out;
174 2277c5d7 2004-03-21 devnull case 0:
175 2277c5d7 2004-03-21 devnull c->state = "write status";
176 2277c5d7 2004-03-21 devnull if(convprint(c, "bad authentication failed") < 0)
177 2277c5d7 2004-03-21 devnull goto out;
178 2277c5d7 2004-03-21 devnull break;
179 2277c5d7 2004-03-21 devnull case 1:
180 2277c5d7 2004-03-21 devnull c->state = "write status";
181 2277c5d7 2004-03-21 devnull if(convprint(c, "ok") < 0)
182 2277c5d7 2004-03-21 devnull goto out;
183 2277c5d7 2004-03-21 devnull goto ok;
184 2277c5d7 2004-03-21 devnull }
185 2277c5d7 2004-03-21 devnull free(user);
186 2277c5d7 2004-03-21 devnull free(resp);
187 2277c5d7 2004-03-21 devnull user = nil;
188 2277c5d7 2004-03-21 devnull resp = nil;
189 2277c5d7 2004-03-21 devnull }
190 2277c5d7 2004-03-21 devnull
191 2277c5d7 2004-03-21 devnull ok:
192 2277c5d7 2004-03-21 devnull ret = 0;
193 2277c5d7 2004-03-21 devnull c->attr = addcap(c->attr, c->sysuser, &s.t);
194 2277c5d7 2004-03-21 devnull
195 2277c5d7 2004-03-21 devnull out:
196 2277c5d7 2004-03-21 devnull keyclose(s.k);
197 2277c5d7 2004-03-21 devnull free(user);
198 2277c5d7 2004-03-21 devnull free(resp);
199 2277c5d7 2004-03-21 devnull // xioclose(s.asfd);
200 2277c5d7 2004-03-21 devnull return ret;
201 2277c5d7 2004-03-21 devnull }
202 2277c5d7 2004-03-21 devnull
203 2277c5d7 2004-03-21 devnull enum
204 2277c5d7 2004-03-21 devnull {
205 2277c5d7 2004-03-21 devnull MAXCHAL = 64,
206 2277c5d7 2004-03-21 devnull };
207 2277c5d7 2004-03-21 devnull
208 2277c5d7 2004-03-21 devnull typedef struct State State;
209 2277c5d7 2004-03-21 devnull struct State
210 2277c5d7 2004-03-21 devnull {
211 2277c5d7 2004-03-21 devnull Key *key;
212 2277c5d7 2004-03-21 devnull int astype;
213 2277c5d7 2004-03-21 devnull int asfd;
214 2277c5d7 2004-03-21 devnull Ticket t;
215 2277c5d7 2004-03-21 devnull Ticketreq tr;
216 2277c5d7 2004-03-21 devnull char chal[MAXCHAL];
217 2277c5d7 2004-03-21 devnull int challen;
218 2277c5d7 2004-03-21 devnull char resp[MAXCHAL];
219 2277c5d7 2004-03-21 devnull int resplen;
220 2277c5d7 2004-03-21 devnull };
221 2277c5d7 2004-03-21 devnull
222 2277c5d7 2004-03-21 devnull enum
223 2277c5d7 2004-03-21 devnull {
224 2277c5d7 2004-03-21 devnull CNeedChal,
225 2277c5d7 2004-03-21 devnull CHaveResp,
226 2277c5d7 2004-03-21 devnull
227 2277c5d7 2004-03-21 devnull SHaveChal,
228 2277c5d7 2004-03-21 devnull SNeedResp,
229 2277c5d7 2004-03-21 devnull
230 2277c5d7 2004-03-21 devnull Maxphase,
231 2277c5d7 2004-03-21 devnull };
232 2277c5d7 2004-03-21 devnull
233 2277c5d7 2004-03-21 devnull static char *phasenames[Maxphase] =
234 2277c5d7 2004-03-21 devnull {
235 2277c5d7 2004-03-21 devnull [CNeedChal] "CNeedChal",
236 2277c5d7 2004-03-21 devnull [CHaveResp] "CHaveResp",
237 2277c5d7 2004-03-21 devnull
238 2277c5d7 2004-03-21 devnull [SHaveChal] "SHaveChal",
239 2277c5d7 2004-03-21 devnull [SNeedResp] "SNeedResp",
240 2277c5d7 2004-03-21 devnull };
241 2277c5d7 2004-03-21 devnull
242 2277c5d7 2004-03-21 devnull static void
243 2277c5d7 2004-03-21 devnull p9crclose(Fsstate *fss)
244 2277c5d7 2004-03-21 devnull {
245 2277c5d7 2004-03-21 devnull State *s;
246 2277c5d7 2004-03-21 devnull
247 2277c5d7 2004-03-21 devnull s = fss->ps;
248 2277c5d7 2004-03-21 devnull if(s->asfd >= 0){
249 2277c5d7 2004-03-21 devnull close(s->asfd);
250 2277c5d7 2004-03-21 devnull s->asfd = -1;
251 2277c5d7 2004-03-21 devnull }
252 2277c5d7 2004-03-21 devnull free(s);
253 2277c5d7 2004-03-21 devnull }
254 2277c5d7 2004-03-21 devnull
255 2277c5d7 2004-03-21 devnull static int getchal(State*, Fsstate*);
256 2277c5d7 2004-03-21 devnull
257 2277c5d7 2004-03-21 devnull static int
258 2277c5d7 2004-03-21 devnull p9crinit(Proto *p, Fsstate *fss)
259 2277c5d7 2004-03-21 devnull {
260 2277c5d7 2004-03-21 devnull int iscli, ret;
261 2277c5d7 2004-03-21 devnull char *user;
262 2277c5d7 2004-03-21 devnull State *s;
263 2277c5d7 2004-03-21 devnull Attr *attr;
264 2277c5d7 2004-03-21 devnull
265 2277c5d7 2004-03-21 devnull if((iscli = isclient(_str_findattr(fss->attr, "role"))) < 0)
266 2277c5d7 2004-03-21 devnull return failure(fss, nil);
267 2277c5d7 2004-03-21 devnull
268 2277c5d7 2004-03-21 devnull s = emalloc(sizeof(*s));
269 2277c5d7 2004-03-21 devnull s->asfd = -1;
270 2277c5d7 2004-03-21 devnull if(p == &p9cr){
271 2277c5d7 2004-03-21 devnull s->astype = AuthChal;
272 2277c5d7 2004-03-21 devnull s->challen = NETCHLEN;
273 2277c5d7 2004-03-21 devnull }else if(p == &vnc){
274 2277c5d7 2004-03-21 devnull s->astype = AuthVNC;
275 2277c5d7 2004-03-21 devnull s->challen = Maxchal;
276 2277c5d7 2004-03-21 devnull }else
277 2277c5d7 2004-03-21 devnull abort();
278 2277c5d7 2004-03-21 devnull
279 2277c5d7 2004-03-21 devnull if(iscli){
280 2277c5d7 2004-03-21 devnull fss->phase = CNeedChal;
281 2277c5d7 2004-03-21 devnull if(p == &p9cr)
282 2277c5d7 2004-03-21 devnull attr = setattr(_copyattr(fss->attr), "proto=p9sk1");
283 2277c5d7 2004-03-21 devnull else
284 2277c5d7 2004-03-21 devnull attr = nil;
285 2277c5d7 2004-03-21 devnull ret = findkey(&s->key, fss, Kuser, 0, attr ? attr : fss->attr,
286 2277c5d7 2004-03-21 devnull "role=client %s", p->keyprompt);
287 2277c5d7 2004-03-21 devnull _freeattr(attr);
288 2277c5d7 2004-03-21 devnull if(ret != RpcOk){
289 2277c5d7 2004-03-21 devnull free(s);
290 2277c5d7 2004-03-21 devnull return ret;
291 2277c5d7 2004-03-21 devnull }
292 2277c5d7 2004-03-21 devnull fss->ps = s;
293 2277c5d7 2004-03-21 devnull }else{
294 2277c5d7 2004-03-21 devnull if((ret = findp9authkey(&s->key, fss)) != RpcOk){
295 2277c5d7 2004-03-21 devnull free(s);
296 2277c5d7 2004-03-21 devnull return ret;
297 2277c5d7 2004-03-21 devnull }
298 2277c5d7 2004-03-21 devnull if((user = _str_findattr(fss->attr, "user")) == nil){
299 2277c5d7 2004-03-21 devnull free(s);
300 2277c5d7 2004-03-21 devnull return failure(fss, "no user name specified in start msg");
301 2277c5d7 2004-03-21 devnull }
302 2277c5d7 2004-03-21 devnull if(strlen(user) >= sizeof s->tr.uid){
303 2277c5d7 2004-03-21 devnull free(s);
304 2277c5d7 2004-03-21 devnull return failure(fss, "user name too long");
305 2277c5d7 2004-03-21 devnull }
306 2277c5d7 2004-03-21 devnull fss->ps = s;
307 2277c5d7 2004-03-21 devnull strcpy(s->tr.uid, user);
308 2277c5d7 2004-03-21 devnull ret = getchal(s, fss);
309 2277c5d7 2004-03-21 devnull if(ret != RpcOk){
310 2277c5d7 2004-03-21 devnull p9crclose(fss); /* frees s */
311 2277c5d7 2004-03-21 devnull fss->ps = nil;
312 2277c5d7 2004-03-21 devnull }
313 2277c5d7 2004-03-21 devnull }
314 2277c5d7 2004-03-21 devnull fss->phasename = phasenames;
315 2277c5d7 2004-03-21 devnull fss->maxphase = Maxphase;
316 2277c5d7 2004-03-21 devnull return ret;
317 2277c5d7 2004-03-21 devnull }
318 2277c5d7 2004-03-21 devnull
319 2277c5d7 2004-03-21 devnull static int
320 2277c5d7 2004-03-21 devnull p9crread(Fsstate *fss, void *va, uint *n)
321 2277c5d7 2004-03-21 devnull {
322 2277c5d7 2004-03-21 devnull int m;
323 2277c5d7 2004-03-21 devnull State *s;
324 2277c5d7 2004-03-21 devnull
325 2277c5d7 2004-03-21 devnull s = fss->ps;
326 2277c5d7 2004-03-21 devnull switch(fss->phase){
327 2277c5d7 2004-03-21 devnull default:
328 2277c5d7 2004-03-21 devnull return phaseerror(fss, "read");
329 2277c5d7 2004-03-21 devnull
330 2277c5d7 2004-03-21 devnull case CHaveResp:
331 2277c5d7 2004-03-21 devnull if(s->resplen < *n)
332 2277c5d7 2004-03-21 devnull *n = s->resplen;
333 2277c5d7 2004-03-21 devnull memmove(va, s->resp, *n);
334 2277c5d7 2004-03-21 devnull fss->phase = Established;
335 2277c5d7 2004-03-21 devnull return RpcOk;
336 2277c5d7 2004-03-21 devnull
337 2277c5d7 2004-03-21 devnull case SHaveChal:
338 2277c5d7 2004-03-21 devnull if(s->astype == AuthChal)
339 2277c5d7 2004-03-21 devnull m = strlen(s->chal); /* ascii string */
340 2277c5d7 2004-03-21 devnull else
341 2277c5d7 2004-03-21 devnull m = s->challen; /* fixed length binary */
342 2277c5d7 2004-03-21 devnull if(m > *n)
343 2277c5d7 2004-03-21 devnull return toosmall(fss, m);
344 2277c5d7 2004-03-21 devnull *n = m;
345 2277c5d7 2004-03-21 devnull memmove(va, s->chal, m);
346 2277c5d7 2004-03-21 devnull fss->phase = SNeedResp;
347 2277c5d7 2004-03-21 devnull return RpcOk;
348 2277c5d7 2004-03-21 devnull }
349 2277c5d7 2004-03-21 devnull }
350 2277c5d7 2004-03-21 devnull
351 2277c5d7 2004-03-21 devnull static int
352 2277c5d7 2004-03-21 devnull p9response(Fsstate *fss, State *s)
353 2277c5d7 2004-03-21 devnull {
354 2277c5d7 2004-03-21 devnull char key[DESKEYLEN];
355 2277c5d7 2004-03-21 devnull uchar buf[8];
356 2277c5d7 2004-03-21 devnull ulong chal;
357 2277c5d7 2004-03-21 devnull char *pw;
358 2277c5d7 2004-03-21 devnull
359 2277c5d7 2004-03-21 devnull pw = _str_findattr(s->key->privattr, "!password");
360 2277c5d7 2004-03-21 devnull if(pw == nil)
361 2277c5d7 2004-03-21 devnull return failure(fss, "vncresponse cannot happen");
362 2277c5d7 2004-03-21 devnull passtokey(key, pw);
363 2277c5d7 2004-03-21 devnull memset(buf, 0, 8);
364 2277c5d7 2004-03-21 devnull sprint((char*)buf, "%d", atoi(s->chal));
365 2277c5d7 2004-03-21 devnull if(encrypt(key, buf, 8) < 0)
366 2277c5d7 2004-03-21 devnull return failure(fss, "can't encrypt response");
367 2277c5d7 2004-03-21 devnull chal = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3];
368 2277c5d7 2004-03-21 devnull s->resplen = snprint(s->resp, sizeof s->resp, "%.8lux", chal);
369 2277c5d7 2004-03-21 devnull return RpcOk;
370 2277c5d7 2004-03-21 devnull }
371 2277c5d7 2004-03-21 devnull
372 2277c5d7 2004-03-21 devnull static uchar tab[256];
373 2277c5d7 2004-03-21 devnull
374 2277c5d7 2004-03-21 devnull /* VNC reverses the bits of each byte before using as a des key */
375 2277c5d7 2004-03-21 devnull static void
376 2277c5d7 2004-03-21 devnull mktab(void)
377 2277c5d7 2004-03-21 devnull {
378 2277c5d7 2004-03-21 devnull int i, j, k;
379 2277c5d7 2004-03-21 devnull static int once;
380 2277c5d7 2004-03-21 devnull
381 2277c5d7 2004-03-21 devnull if(once)
382 2277c5d7 2004-03-21 devnull return;
383 2277c5d7 2004-03-21 devnull once = 1;
384 2277c5d7 2004-03-21 devnull
385 2277c5d7 2004-03-21 devnull for(i=0; i<256; i++) {
386 2277c5d7 2004-03-21 devnull j=i;
387 2277c5d7 2004-03-21 devnull tab[i] = 0;
388 2277c5d7 2004-03-21 devnull for(k=0; k<8; k++) {
389 2277c5d7 2004-03-21 devnull tab[i] = (tab[i]<<1) | (j&1);
390 2277c5d7 2004-03-21 devnull j >>= 1;
391 2277c5d7 2004-03-21 devnull }
392 2277c5d7 2004-03-21 devnull }
393 2277c5d7 2004-03-21 devnull }
394 2277c5d7 2004-03-21 devnull
395 2277c5d7 2004-03-21 devnull static int
396 2277c5d7 2004-03-21 devnull vncaddkey(Key *k)
397 2277c5d7 2004-03-21 devnull {
398 2277c5d7 2004-03-21 devnull uchar *p;
399 2277c5d7 2004-03-21 devnull char *s;
400 2277c5d7 2004-03-21 devnull
401 2277c5d7 2004-03-21 devnull k->priv = emalloc(8+1);
402 2277c5d7 2004-03-21 devnull if(s = _str_findattr(k->privattr, "!password")){
403 2277c5d7 2004-03-21 devnull mktab();
404 2277c5d7 2004-03-21 devnull memset(k->priv, 0, 8+1);
405 2277c5d7 2004-03-21 devnull strncpy((char*)k->priv, s, 8);
406 2277c5d7 2004-03-21 devnull for(p=k->priv; *p; p++)
407 2277c5d7 2004-03-21 devnull *p = tab[*p];
408 2277c5d7 2004-03-21 devnull }else{
409 2277c5d7 2004-03-21 devnull werrstr("no key data");
410 2277c5d7 2004-03-21 devnull return -1;
411 2277c5d7 2004-03-21 devnull }
412 2277c5d7 2004-03-21 devnull return replacekey(k);
413 2277c5d7 2004-03-21 devnull }
414 2277c5d7 2004-03-21 devnull
415 2277c5d7 2004-03-21 devnull static void
416 2277c5d7 2004-03-21 devnull vncclosekey(Key *k)
417 2277c5d7 2004-03-21 devnull {
418 2277c5d7 2004-03-21 devnull free(k->priv);
419 2277c5d7 2004-03-21 devnull }
420 2277c5d7 2004-03-21 devnull
421 2277c5d7 2004-03-21 devnull static int
422 2277c5d7 2004-03-21 devnull vncresponse(Fsstate*, State *s)
423 2277c5d7 2004-03-21 devnull {
424 2277c5d7 2004-03-21 devnull DESstate des;
425 2277c5d7 2004-03-21 devnull
426 2277c5d7 2004-03-21 devnull memmove(s->resp, s->chal, sizeof s->chal);
427 2277c5d7 2004-03-21 devnull setupDESstate(&des, s->key->priv, nil);
428 2277c5d7 2004-03-21 devnull desECBencrypt((uchar*)s->resp, s->challen, &des);
429 2277c5d7 2004-03-21 devnull s->resplen = s->challen;
430 2277c5d7 2004-03-21 devnull return RpcOk;
431 2277c5d7 2004-03-21 devnull }
432 2277c5d7 2004-03-21 devnull
433 2277c5d7 2004-03-21 devnull static int
434 2277c5d7 2004-03-21 devnull p9crwrite(Fsstate *fss, void *va, uint n)
435 2277c5d7 2004-03-21 devnull {
436 2277c5d7 2004-03-21 devnull char tbuf[TICKETLEN+AUTHENTLEN];
437 2277c5d7 2004-03-21 devnull State *s;
438 2277c5d7 2004-03-21 devnull char *data = va;
439 2277c5d7 2004-03-21 devnull Authenticator a;
440 2277c5d7 2004-03-21 devnull char resp[Maxchal];
441 2277c5d7 2004-03-21 devnull int ret;
442 2277c5d7 2004-03-21 devnull
443 2277c5d7 2004-03-21 devnull s = fss->ps;
444 2277c5d7 2004-03-21 devnull switch(fss->phase){
445 2277c5d7 2004-03-21 devnull default:
446 2277c5d7 2004-03-21 devnull return phaseerror(fss, "write");
447 2277c5d7 2004-03-21 devnull
448 2277c5d7 2004-03-21 devnull case CNeedChal:
449 2277c5d7 2004-03-21 devnull if(n >= sizeof(s->chal))
450 2277c5d7 2004-03-21 devnull return failure(fss, Ebadarg);
451 2277c5d7 2004-03-21 devnull memset(s->chal, 0, sizeof s->chal);
452 2277c5d7 2004-03-21 devnull memmove(s->chal, data, n);
453 2277c5d7 2004-03-21 devnull s->challen = n;
454 2277c5d7 2004-03-21 devnull
455 2277c5d7 2004-03-21 devnull if(s->astype == AuthChal)
456 2277c5d7 2004-03-21 devnull ret = p9response(fss, s);
457 2277c5d7 2004-03-21 devnull else
458 2277c5d7 2004-03-21 devnull ret = vncresponse(fss, s);
459 2277c5d7 2004-03-21 devnull if(ret != RpcOk)
460 2277c5d7 2004-03-21 devnull return ret;
461 2277c5d7 2004-03-21 devnull fss->phase = CHaveResp;
462 2277c5d7 2004-03-21 devnull return RpcOk;
463 2277c5d7 2004-03-21 devnull
464 2277c5d7 2004-03-21 devnull case SNeedResp:
465 2277c5d7 2004-03-21 devnull /* send response to auth server and get ticket */
466 2277c5d7 2004-03-21 devnull if(n > sizeof(resp))
467 2277c5d7 2004-03-21 devnull return failure(fss, Ebadarg);
468 2277c5d7 2004-03-21 devnull memset(resp, 0, sizeof resp);
469 2277c5d7 2004-03-21 devnull memmove(resp, data, n);
470 2277c5d7 2004-03-21 devnull if(write(s->asfd, resp, s->challen) != s->challen)
471 2277c5d7 2004-03-21 devnull return failure(fss, Easproto);
472 2277c5d7 2004-03-21 devnull
473 2277c5d7 2004-03-21 devnull /* get ticket plus authenticator from auth server */
474 2277c5d7 2004-03-21 devnull if(_asrdresp(s->asfd, tbuf, TICKETLEN+AUTHENTLEN) < 0)
475 2277c5d7 2004-03-21 devnull return failure(fss, nil);
476 2277c5d7 2004-03-21 devnull
477 2277c5d7 2004-03-21 devnull /* check ticket */
478 2277c5d7 2004-03-21 devnull convM2T(tbuf, &s->t, s->key->priv);
479 2277c5d7 2004-03-21 devnull if(s->t.num != AuthTs
480 2277c5d7 2004-03-21 devnull || memcmp(s->t.chal, s->tr.chal, sizeof(s->t.chal)) != 0)
481 2277c5d7 2004-03-21 devnull return failure(fss, Easproto);
482 2277c5d7 2004-03-21 devnull convM2A(tbuf+TICKETLEN, &a, s->t.key);
483 2277c5d7 2004-03-21 devnull if(a.num != AuthAc
484 2277c5d7 2004-03-21 devnull || memcmp(a.chal, s->tr.chal, sizeof(a.chal)) != 0
485 2277c5d7 2004-03-21 devnull || a.id != 0)
486 2277c5d7 2004-03-21 devnull return failure(fss, Easproto);
487 2277c5d7 2004-03-21 devnull
488 2277c5d7 2004-03-21 devnull fss->haveai = 1;
489 2277c5d7 2004-03-21 devnull fss->ai.cuid = s->t.cuid;
490 2277c5d7 2004-03-21 devnull fss->ai.suid = s->t.suid;
491 2277c5d7 2004-03-21 devnull fss->ai.nsecret = 0;
492 2277c5d7 2004-03-21 devnull fss->ai.secret = nil;
493 2277c5d7 2004-03-21 devnull fss->phase = Established;
494 2277c5d7 2004-03-21 devnull return RpcOk;
495 2277c5d7 2004-03-21 devnull }
496 2277c5d7 2004-03-21 devnull }
497 2277c5d7 2004-03-21 devnull
498 2277c5d7 2004-03-21 devnull static int
499 2277c5d7 2004-03-21 devnull getchal(State *s, Fsstate *fss)
500 2277c5d7 2004-03-21 devnull {
501 2277c5d7 2004-03-21 devnull char trbuf[TICKREQLEN];
502 2277c5d7 2004-03-21 devnull int n;
503 2277c5d7 2004-03-21 devnull
504 2277c5d7 2004-03-21 devnull safecpy(s->tr.hostid, _str_findattr(s->key->attr, "user"), sizeof(s->tr.hostid));
505 2277c5d7 2004-03-21 devnull safecpy(s->tr.authdom, _str_findattr(s->key->attr, "dom"), sizeof(s->tr.authdom));
506 2277c5d7 2004-03-21 devnull s->tr.type = s->astype;
507 2277c5d7 2004-03-21 devnull convTR2M(&s->tr, trbuf);
508 2277c5d7 2004-03-21 devnull
509 2277c5d7 2004-03-21 devnull /* get challenge from auth server */
510 2277c5d7 2004-03-21 devnull s->asfd = _authdial(nil, _str_findattr(s->key->attr, "dom"));
511 2277c5d7 2004-03-21 devnull if(s->asfd < 0)
512 2277c5d7 2004-03-21 devnull return failure(fss, Easproto);
513 2277c5d7 2004-03-21 devnull if(write(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN)
514 2277c5d7 2004-03-21 devnull return failure(fss, Easproto);
515 2277c5d7 2004-03-21 devnull n = _asrdresp(s->asfd, s->chal, s->challen);
516 2277c5d7 2004-03-21 devnull if(n <= 0){
517 2277c5d7 2004-03-21 devnull if(n == 0)
518 2277c5d7 2004-03-21 devnull werrstr("_asrdresp short read");
519 2277c5d7 2004-03-21 devnull return failure(fss, nil);
520 2277c5d7 2004-03-21 devnull }
521 2277c5d7 2004-03-21 devnull s->challen = n;
522 2277c5d7 2004-03-21 devnull fss->phase = SHaveChal;
523 2277c5d7 2004-03-21 devnull return RpcOk;
524 2277c5d7 2004-03-21 devnull }
525 2277c5d7 2004-03-21 devnull
526 2277c5d7 2004-03-21 devnull Proto p9cr =
527 2277c5d7 2004-03-21 devnull {
528 2277c5d7 2004-03-21 devnull .name= "p9cr",
529 2277c5d7 2004-03-21 devnull .init= p9crinit,
530 2277c5d7 2004-03-21 devnull .write= p9crwrite,
531 2277c5d7 2004-03-21 devnull .read= p9crread,
532 2277c5d7 2004-03-21 devnull .close= p9crclose,
533 2277c5d7 2004-03-21 devnull .keyprompt= "user? !password?",
534 2277c5d7 2004-03-21 devnull };
535 2277c5d7 2004-03-21 devnull
536 2277c5d7 2004-03-21 devnull Proto vnc =
537 2277c5d7 2004-03-21 devnull {
538 2277c5d7 2004-03-21 devnull .name= "vnc",
539 2277c5d7 2004-03-21 devnull .init= p9crinit,
540 2277c5d7 2004-03-21 devnull .write= p9crwrite,
541 2277c5d7 2004-03-21 devnull .read= p9crread,
542 2277c5d7 2004-03-21 devnull .close= p9crclose,
543 2277c5d7 2004-03-21 devnull .keyprompt= "!password?",
544 2277c5d7 2004-03-21 devnull .addkey= vncaddkey,
545 2277c5d7 2004-03-21 devnull };