Blame


1 6e527fbc 2005-02-13 devnull /*
2 6e527fbc 2005-02-13 devnull * CHAP, MSCHAP
3 6e527fbc 2005-02-13 devnull *
4 6e527fbc 2005-02-13 devnull * The client does not authenticate the server, hence no CAI
5 6e527fbc 2005-02-13 devnull *
6 6e527fbc 2005-02-13 devnull * Protocol:
7 6e527fbc 2005-02-13 devnull *
8 6e527fbc 2005-02-13 devnull * S -> C: random 8-byte challenge
9 6e527fbc 2005-02-13 devnull * C -> S: user in UTF-8
10 6e527fbc 2005-02-13 devnull * C -> S: Chapreply or MSchapreply structure
11 6e527fbc 2005-02-13 devnull * S -> C: ok or 'bad why'
12 6e527fbc 2005-02-13 devnull *
13 6e527fbc 2005-02-13 devnull * The chap protocol requires the client to give it id=%d, the id of
14 6e527fbc 2005-02-13 devnull * the PPP message containing the challenge, which is used
15 6e527fbc 2005-02-13 devnull * as part of the response. Because the client protocol is message-id
16 6e527fbc 2005-02-13 devnull * specific, there is no point in looping to try multiple keys.
17 6e527fbc 2005-02-13 devnull *
18 6e527fbc 2005-02-13 devnull * The MS chap protocol actually uses two different hashes, an
19 6e527fbc 2005-02-13 devnull * older insecure one called the LM (Lan Manager) hash, and a newer
20 6e527fbc 2005-02-13 devnull * more secure one called the NT hash. By default we send back only
21 6e527fbc 2005-02-13 devnull * the NT hash, because the LM hash can help an eavesdropper run
22 6e527fbc 2005-02-13 devnull * a brute force attack. If the key has an lm attribute, then we send only the
23 6e527fbc 2005-02-13 devnull * LM hash.
24 6e527fbc 2005-02-13 devnull */
25 6e527fbc 2005-02-13 devnull
26 6e527fbc 2005-02-13 devnull #include "std.h"
27 6e527fbc 2005-02-13 devnull #include "dat.h"
28 6e527fbc 2005-02-13 devnull
29 6e527fbc 2005-02-13 devnull extern Proto chap, mschap;
30 6e527fbc 2005-02-13 devnull
31 6e527fbc 2005-02-13 devnull enum {
32 6e527fbc 2005-02-13 devnull ChapChallen = 8,
33 6e527fbc 2005-02-13 devnull
34 6e527fbc 2005-02-13 devnull MShashlen = 16,
35 6e527fbc 2005-02-13 devnull MSchallen = 8,
36 6e527fbc 2005-02-13 devnull MSresplen = 24,
37 6e527fbc 2005-02-13 devnull };
38 6e527fbc 2005-02-13 devnull
39 6e527fbc 2005-02-13 devnull static int
40 6e527fbc 2005-02-13 devnull chapcheck(Key *k)
41 6e527fbc 2005-02-13 devnull {
42 6e527fbc 2005-02-13 devnull if(!strfindattr(k->attr, "user") || !strfindattr(k->privattr, "!password")){
43 6e527fbc 2005-02-13 devnull werrstr("need user and !password attributes");
44 6e527fbc 2005-02-13 devnull return -1;
45 6e527fbc 2005-02-13 devnull }
46 6e527fbc 2005-02-13 devnull return 0;
47 6e527fbc 2005-02-13 devnull }
48 6e527fbc 2005-02-13 devnull
49 6e527fbc 2005-02-13 devnull static void
50 6e527fbc 2005-02-13 devnull nthash(uchar hash[MShashlen], char *passwd)
51 6e527fbc 2005-02-13 devnull {
52 6e527fbc 2005-02-13 devnull uchar buf[512];
53 6e527fbc 2005-02-13 devnull int i;
54 6e527fbc 2005-02-13 devnull
55 6e527fbc 2005-02-13 devnull for(i=0; *passwd && i<sizeof(buf); passwd++) {
56 6e527fbc 2005-02-13 devnull buf[i++] = *passwd;
57 6e527fbc 2005-02-13 devnull buf[i++] = 0;
58 6e527fbc 2005-02-13 devnull }
59 6e527fbc 2005-02-13 devnull
60 6e527fbc 2005-02-13 devnull memset(hash, 0, 16);
61 6e527fbc 2005-02-13 devnull
62 6e527fbc 2005-02-13 devnull md4(buf, i, hash, 0);
63 6e527fbc 2005-02-13 devnull }
64 6e527fbc 2005-02-13 devnull
65 6e527fbc 2005-02-13 devnull static void
66 6e527fbc 2005-02-13 devnull desencrypt(uchar data[8], uchar key[7])
67 6e527fbc 2005-02-13 devnull {
68 6e527fbc 2005-02-13 devnull ulong ekey[32];
69 6e527fbc 2005-02-13 devnull
70 6e527fbc 2005-02-13 devnull key_setup(key, ekey);
71 6e527fbc 2005-02-13 devnull block_cipher(ekey, data, 0);
72 6e527fbc 2005-02-13 devnull }
73 6e527fbc 2005-02-13 devnull
74 6e527fbc 2005-02-13 devnull static void
75 6e527fbc 2005-02-13 devnull lmhash(uchar hash[MShashlen], char *passwd)
76 6e527fbc 2005-02-13 devnull {
77 6e527fbc 2005-02-13 devnull uchar buf[14];
78 6e527fbc 2005-02-13 devnull char *stdtext = "KGS!@#$%";
79 6e527fbc 2005-02-13 devnull int i;
80 6e527fbc 2005-02-13 devnull
81 6e527fbc 2005-02-13 devnull strncpy((char*)buf, passwd, sizeof(buf));
82 6e527fbc 2005-02-13 devnull for(i=0; i<sizeof(buf); i++)
83 6e527fbc 2005-02-13 devnull if(buf[i] >= 'a' && buf[i] <= 'z')
84 6e527fbc 2005-02-13 devnull buf[i] += 'A' - 'a';
85 6e527fbc 2005-02-13 devnull
86 6e527fbc 2005-02-13 devnull memset(hash, 0, 16);
87 6e527fbc 2005-02-13 devnull memcpy(hash, stdtext, 8);
88 6e527fbc 2005-02-13 devnull memcpy(hash+8, stdtext, 8);
89 6e527fbc 2005-02-13 devnull
90 6e527fbc 2005-02-13 devnull desencrypt(hash, buf);
91 6e527fbc 2005-02-13 devnull desencrypt(hash+8, buf+7);
92 6e527fbc 2005-02-13 devnull }
93 6e527fbc 2005-02-13 devnull
94 6e527fbc 2005-02-13 devnull static void
95 6e527fbc 2005-02-13 devnull mschalresp(uchar resp[MSresplen], uchar hash[MShashlen], uchar chal[MSchallen])
96 6e527fbc 2005-02-13 devnull {
97 6e527fbc 2005-02-13 devnull int i;
98 6e527fbc 2005-02-13 devnull uchar buf[21];
99 6e527fbc 2005-02-13 devnull
100 6e527fbc 2005-02-13 devnull memset(buf, 0, sizeof(buf));
101 6e527fbc 2005-02-13 devnull memcpy(buf, hash, MShashlen);
102 6e527fbc 2005-02-13 devnull
103 6e527fbc 2005-02-13 devnull for(i=0; i<3; i++) {
104 6e527fbc 2005-02-13 devnull memmove(resp+i*MSchallen, chal, MSchallen);
105 6e527fbc 2005-02-13 devnull desencrypt(resp+i*MSchallen, buf+i*7);
106 6e527fbc 2005-02-13 devnull }
107 6e527fbc 2005-02-13 devnull }
108 6e527fbc 2005-02-13 devnull
109 6e527fbc 2005-02-13 devnull static int
110 6e527fbc 2005-02-13 devnull chapclient(Conv *c)
111 6e527fbc 2005-02-13 devnull {
112 6e527fbc 2005-02-13 devnull int id, astype, nchal, npw, ret;
113 6e527fbc 2005-02-13 devnull uchar *chal;
114 6e527fbc 2005-02-13 devnull char *s, *pw, *user, *res;
115 6e527fbc 2005-02-13 devnull Attr *attr;
116 6e527fbc 2005-02-13 devnull Key *k;
117 6e527fbc 2005-02-13 devnull Chapreply cr;
118 6e527fbc 2005-02-13 devnull MSchapreply mscr;
119 6e527fbc 2005-02-13 devnull DigestState *ds;
120 6e527fbc 2005-02-13 devnull
121 6e527fbc 2005-02-13 devnull ret = -1;
122 6e527fbc 2005-02-13 devnull chal = nil;
123 6e527fbc 2005-02-13 devnull k = nil;
124 6e527fbc 2005-02-13 devnull attr = c->attr;
125 6e527fbc 2005-02-13 devnull
126 6e527fbc 2005-02-13 devnull if(c->proto == &chap){
127 6e527fbc 2005-02-13 devnull astype = AuthChap;
128 6e527fbc 2005-02-13 devnull s = strfindattr(attr, "id");
129 6e527fbc 2005-02-13 devnull if(s == nil || *s == 0){
130 6e527fbc 2005-02-13 devnull werrstr("need id=n attr in start message");
131 6e527fbc 2005-02-13 devnull goto out;
132 6e527fbc 2005-02-13 devnull }
133 6e527fbc 2005-02-13 devnull id = strtol(s, &s, 10);
134 6e527fbc 2005-02-13 devnull if(*s != 0 || id < 0 || id >= 256){
135 6e527fbc 2005-02-13 devnull werrstr("bad id=n attr in start message");
136 6e527fbc 2005-02-13 devnull goto out;
137 6e527fbc 2005-02-13 devnull }
138 6e527fbc 2005-02-13 devnull cr.id = id;
139 6e527fbc 2005-02-13 devnull }else if(c->proto == &mschap)
140 6e527fbc 2005-02-13 devnull astype = AuthMSchap;
141 6e527fbc 2005-02-13 devnull else{
142 6e527fbc 2005-02-13 devnull werrstr("bad proto");
143 6e527fbc 2005-02-13 devnull goto out;
144 6e527fbc 2005-02-13 devnull }
145 6e527fbc 2005-02-13 devnull
146 6e527fbc 2005-02-13 devnull c->state = "find key";
147 6e527fbc 2005-02-13 devnull k = keyfetch(c, "%A %s", attr, c->proto->keyprompt);
148 6e527fbc 2005-02-13 devnull if(k == nil)
149 6e527fbc 2005-02-13 devnull goto out;
150 6e527fbc 2005-02-13 devnull
151 6e527fbc 2005-02-13 devnull c->attr = addattrs(copyattr(attr), k->attr);
152 6e527fbc 2005-02-13 devnull
153 6e527fbc 2005-02-13 devnull c->state = "read challenge";
154 6e527fbc 2005-02-13 devnull if((nchal = convreadm(c, (char**)(void*)&chal)) < 0)
155 6e527fbc 2005-02-13 devnull goto out;
156 6e527fbc 2005-02-13 devnull if(astype == AuthMSchap && nchal != MSchallen)
157 6e527fbc 2005-02-13 devnull c->state = "write user";
158 6e527fbc 2005-02-13 devnull if((user = strfindattr(k->attr, "user")) == nil){
159 6e527fbc 2005-02-13 devnull werrstr("key has no user (cannot happen?)");
160 6e527fbc 2005-02-13 devnull goto out;
161 6e527fbc 2005-02-13 devnull }
162 6e527fbc 2005-02-13 devnull if(convprint(c, "%s", user) < 0)
163 6e527fbc 2005-02-13 devnull goto out;
164 6e527fbc 2005-02-13 devnull
165 6e527fbc 2005-02-13 devnull c->state = "write response";
166 6e527fbc 2005-02-13 devnull if((pw = strfindattr(k->privattr, "!password")) == nil){
167 6e527fbc 2005-02-13 devnull werrstr("key has no password (cannot happen?)");
168 6e527fbc 2005-02-13 devnull goto out;
169 6e527fbc 2005-02-13 devnull }
170 6e527fbc 2005-02-13 devnull npw = strlen(pw);
171 6e527fbc 2005-02-13 devnull
172 6e527fbc 2005-02-13 devnull if(astype == AuthChap){
173 6e527fbc 2005-02-13 devnull ds = md5(&cr.id, 1, 0, 0);
174 6e527fbc 2005-02-13 devnull md5((uchar*)pw, npw, 0, ds);
175 6e527fbc 2005-02-13 devnull md5(chal, nchal, (uchar*)cr.resp, ds);
176 6e527fbc 2005-02-13 devnull if(convwrite(c, &cr, sizeof cr) < 0)
177 6e527fbc 2005-02-13 devnull goto out;
178 6e527fbc 2005-02-13 devnull }else{
179 6e527fbc 2005-02-13 devnull uchar hash[MShashlen];
180 6e527fbc 2005-02-13 devnull
181 6e527fbc 2005-02-13 devnull memset(&mscr, 0, sizeof mscr);
182 6e527fbc 2005-02-13 devnull if(strfindattr(k->attr, "lm")){
183 6e527fbc 2005-02-13 devnull lmhash(hash, pw);
184 6e527fbc 2005-02-13 devnull mschalresp((uchar*)mscr.LMresp, hash, chal);
185 6e527fbc 2005-02-13 devnull }else{
186 6e527fbc 2005-02-13 devnull nthash(hash, pw);
187 6e527fbc 2005-02-13 devnull mschalresp((uchar*)mscr.NTresp, hash, chal);
188 6e527fbc 2005-02-13 devnull }
189 6e527fbc 2005-02-13 devnull if(convwrite(c, &mscr, sizeof mscr) < 0)
190 6e527fbc 2005-02-13 devnull goto out;
191 6e527fbc 2005-02-13 devnull }
192 6e527fbc 2005-02-13 devnull
193 6e527fbc 2005-02-13 devnull c->state = "read result";
194 6e527fbc 2005-02-13 devnull if(convreadm(c, &res) < 0)
195 6e527fbc 2005-02-13 devnull goto out;
196 6e527fbc 2005-02-13 devnull if(strcmp(res, "ok") == 0){
197 6e527fbc 2005-02-13 devnull ret = 0;
198 6e527fbc 2005-02-13 devnull werrstr("succeeded");
199 6e527fbc 2005-02-13 devnull goto out;
200 6e527fbc 2005-02-13 devnull }
201 6e527fbc 2005-02-13 devnull if(strncmp(res, "bad ", 4) != 0){
202 6e527fbc 2005-02-13 devnull werrstr("bad result: %s", res);
203 6e527fbc 2005-02-13 devnull goto out;
204 6e527fbc 2005-02-13 devnull }
205 6e527fbc 2005-02-13 devnull
206 6e527fbc 2005-02-13 devnull c->state = "replace key";
207 6e527fbc 2005-02-13 devnull keyevict(c, k, "%s", res+4);
208 6e527fbc 2005-02-13 devnull werrstr("%s", res+4);
209 6e527fbc 2005-02-13 devnull
210 6e527fbc 2005-02-13 devnull out:
211 6e527fbc 2005-02-13 devnull free(res);
212 6e527fbc 2005-02-13 devnull keyclose(k);
213 6e527fbc 2005-02-13 devnull free(chal);
214 6e527fbc 2005-02-13 devnull if(c->attr != attr)
215 6e527fbc 2005-02-13 devnull freeattr(attr);
216 6e527fbc 2005-02-13 devnull return ret;
217 6e527fbc 2005-02-13 devnull }
218 6e527fbc 2005-02-13 devnull
219 6e527fbc 2005-02-13 devnull /* shared with auth dialing routines */
220 6e527fbc 2005-02-13 devnull typedef struct ServerState ServerState;
221 6e527fbc 2005-02-13 devnull struct ServerState
222 6e527fbc 2005-02-13 devnull {
223 6e527fbc 2005-02-13 devnull int asfd;
224 6e527fbc 2005-02-13 devnull Key *k;
225 6e527fbc 2005-02-13 devnull Ticketreq tr;
226 6e527fbc 2005-02-13 devnull Ticket t;
227 6e527fbc 2005-02-13 devnull char *dom;
228 6e527fbc 2005-02-13 devnull char *hostid;
229 6e527fbc 2005-02-13 devnull };
230 6e527fbc 2005-02-13 devnull
231 6e527fbc 2005-02-13 devnull static int chapchal(ServerState*, int, char[ChapChallen]);
232 6e527fbc 2005-02-13 devnull static int chapresp(ServerState*, char*, char*);
233 6e527fbc 2005-02-13 devnull
234 6e527fbc 2005-02-13 devnull static int
235 6e527fbc 2005-02-13 devnull chapserver(Conv *c)
236 6e527fbc 2005-02-13 devnull {
237 6e527fbc 2005-02-13 devnull char chal[ChapChallen], *user, *resp;
238 6e527fbc 2005-02-13 devnull ServerState s;
239 6e527fbc 2005-02-13 devnull int astype, ret;
240 6e527fbc 2005-02-13 devnull Attr *a;
241 6e527fbc 2005-02-13 devnull
242 6e527fbc 2005-02-13 devnull ret = -1;
243 6e527fbc 2005-02-13 devnull user = nil;
244 6e527fbc 2005-02-13 devnull resp = nil;
245 6e527fbc 2005-02-13 devnull memset(&s, 0, sizeof s);
246 6e527fbc 2005-02-13 devnull s.asfd = -1;
247 6e527fbc 2005-02-13 devnull
248 6e527fbc 2005-02-13 devnull if(c->proto == &chap)
249 6e527fbc 2005-02-13 devnull astype = AuthChap;
250 6e527fbc 2005-02-13 devnull else if(c->proto == &mschap)
251 6e527fbc 2005-02-13 devnull astype = AuthMSchap;
252 6e527fbc 2005-02-13 devnull else{
253 6e527fbc 2005-02-13 devnull werrstr("bad proto");
254 6e527fbc 2005-02-13 devnull goto out;
255 6e527fbc 2005-02-13 devnull }
256 6e527fbc 2005-02-13 devnull
257 6e527fbc 2005-02-13 devnull c->state = "find key";
258 6e527fbc 2005-02-13 devnull if((s.k = plan9authkey(c->attr)) == nil)
259 6e527fbc 2005-02-13 devnull goto out;
260 6e527fbc 2005-02-13 devnull
261 6e527fbc 2005-02-13 devnull a = copyattr(s.k->attr);
262 6e527fbc 2005-02-13 devnull a = delattr(a, "proto");
263 6e527fbc 2005-02-13 devnull c->attr = addattrs(c->attr, a);
264 6e527fbc 2005-02-13 devnull freeattr(a);
265 6e527fbc 2005-02-13 devnull
266 6e527fbc 2005-02-13 devnull c->state = "authdial";
267 6e527fbc 2005-02-13 devnull s.hostid = strfindattr(s.k->attr, "user");
268 6e527fbc 2005-02-13 devnull s.dom = strfindattr(s.k->attr, "dom");
269 6e527fbc 2005-02-13 devnull if((s.asfd = xioauthdial(nil, s.dom)) < 0){
270 6e527fbc 2005-02-13 devnull werrstr("authdial %s: %r", s.dom);
271 6e527fbc 2005-02-13 devnull goto out;
272 6e527fbc 2005-02-13 devnull }
273 6e527fbc 2005-02-13 devnull
274 6e527fbc 2005-02-13 devnull c->state = "authchal";
275 6e527fbc 2005-02-13 devnull if(chapchal(&s, astype, chal) < 0)
276 6e527fbc 2005-02-13 devnull goto out;
277 6e527fbc 2005-02-13 devnull
278 6e527fbc 2005-02-13 devnull c->state = "write challenge";
279 6e527fbc 2005-02-13 devnull if(convprint(c, "%s", chal) < 0)
280 6e527fbc 2005-02-13 devnull goto out;
281 6e527fbc 2005-02-13 devnull
282 6e527fbc 2005-02-13 devnull c->state = "read user";
283 6e527fbc 2005-02-13 devnull if(convreadm(c, &user) < 0)
284 6e527fbc 2005-02-13 devnull goto out;
285 6e527fbc 2005-02-13 devnull
286 6e527fbc 2005-02-13 devnull c->state = "read response";
287 6e527fbc 2005-02-13 devnull if(convreadm(c, &resp) < 0)
288 6e527fbc 2005-02-13 devnull goto out;
289 6e527fbc 2005-02-13 devnull
290 6e527fbc 2005-02-13 devnull c->state = "authwrite";
291 6e527fbc 2005-02-13 devnull switch(chapresp(&s, user, resp)){
292 6e527fbc 2005-02-13 devnull default:
293 6e527fbc 2005-02-13 devnull fprint(2, "factotum: bad result from chapresp\n");
294 6e527fbc 2005-02-13 devnull goto out;
295 6e527fbc 2005-02-13 devnull case -1:
296 6e527fbc 2005-02-13 devnull goto out;
297 6e527fbc 2005-02-13 devnull case 0:
298 6e527fbc 2005-02-13 devnull c->state = "write status";
299 6e527fbc 2005-02-13 devnull if(convprint(c, "bad authentication failed") < 0)
300 6e527fbc 2005-02-13 devnull goto out;
301 6e527fbc 2005-02-13 devnull goto out;
302 6e527fbc 2005-02-13 devnull
303 6e527fbc 2005-02-13 devnull case 1:
304 6e527fbc 2005-02-13 devnull c->state = "write status";
305 6e527fbc 2005-02-13 devnull if(convprint(c, "ok") < 0)
306 6e527fbc 2005-02-13 devnull goto out;
307 6e527fbc 2005-02-13 devnull goto ok;
308 6e527fbc 2005-02-13 devnull }
309 6e527fbc 2005-02-13 devnull
310 6e527fbc 2005-02-13 devnull ok:
311 6e527fbc 2005-02-13 devnull ret = 0;
312 6e527fbc 2005-02-13 devnull c->attr = addcap(c->attr, c->sysuser, &s.t);
313 6e527fbc 2005-02-13 devnull
314 6e527fbc 2005-02-13 devnull out:
315 6e527fbc 2005-02-13 devnull keyclose(s.k);
316 6e527fbc 2005-02-13 devnull free(user);
317 6e527fbc 2005-02-13 devnull free(resp);
318 6e527fbc 2005-02-13 devnull // xioclose(s.asfd);
319 6e527fbc 2005-02-13 devnull return ret;
320 6e527fbc 2005-02-13 devnull }
321 6e527fbc 2005-02-13 devnull
322 6e527fbc 2005-02-13 devnull static int
323 6e527fbc 2005-02-13 devnull chapchal(ServerState *s, int astype, char chal[ChapChallen])
324 6e527fbc 2005-02-13 devnull {
325 6e527fbc 2005-02-13 devnull char trbuf[TICKREQLEN];
326 6e527fbc 2005-02-13 devnull Ticketreq tr;
327 6e527fbc 2005-02-13 devnull
328 6e527fbc 2005-02-13 devnull memset(&tr, 0, sizeof tr);
329 6e527fbc 2005-02-13 devnull
330 6e527fbc 2005-02-13 devnull tr.type = astype;
331 6e527fbc 2005-02-13 devnull
332 6e527fbc 2005-02-13 devnull if(strlen(s->hostid) >= sizeof tr.hostid){
333 6e527fbc 2005-02-13 devnull werrstr("hostid too long");
334 6e527fbc 2005-02-13 devnull return -1;
335 6e527fbc 2005-02-13 devnull }
336 6e527fbc 2005-02-13 devnull strcpy(tr.hostid, s->hostid);
337 6e527fbc 2005-02-13 devnull
338 6e527fbc 2005-02-13 devnull if(strlen(s->dom) >= sizeof tr.authdom){
339 6e527fbc 2005-02-13 devnull werrstr("domain too long");
340 6e527fbc 2005-02-13 devnull return -1;
341 6e527fbc 2005-02-13 devnull }
342 6e527fbc 2005-02-13 devnull strcpy(tr.authdom, s->dom);
343 6e527fbc 2005-02-13 devnull
344 6e527fbc 2005-02-13 devnull convTR2M(&tr, trbuf);
345 6e527fbc 2005-02-13 devnull if(xiowrite(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN)
346 6e527fbc 2005-02-13 devnull return -1;
347 6e527fbc 2005-02-13 devnull
348 6e527fbc 2005-02-13 devnull if(xioasrdresp(s->asfd, chal, ChapChallen) <= 5)
349 6e527fbc 2005-02-13 devnull return -1;
350 6e527fbc 2005-02-13 devnull
351 6e527fbc 2005-02-13 devnull s->tr = tr;
352 6e527fbc 2005-02-13 devnull return 0;
353 6e527fbc 2005-02-13 devnull }
354 6e527fbc 2005-02-13 devnull
355 6e527fbc 2005-02-13 devnull static int
356 6e527fbc 2005-02-13 devnull chapresp(ServerState *s, char *user, char *resp)
357 6e527fbc 2005-02-13 devnull {
358 6e527fbc 2005-02-13 devnull char tabuf[TICKETLEN+AUTHENTLEN];
359 6e527fbc 2005-02-13 devnull char trbuf[TICKREQLEN];
360 6e527fbc 2005-02-13 devnull int len;
361 6e527fbc 2005-02-13 devnull Authenticator a;
362 6e527fbc 2005-02-13 devnull Ticket t;
363 6e527fbc 2005-02-13 devnull Ticketreq tr;
364 6e527fbc 2005-02-13 devnull
365 6e527fbc 2005-02-13 devnull tr = s->tr;
366 6e527fbc 2005-02-13 devnull if(memrandom(tr.chal, CHALLEN) < 0)
367 6e527fbc 2005-02-13 devnull return -1;
368 6e527fbc 2005-02-13 devnull
369 6e527fbc 2005-02-13 devnull if(strlen(user) >= sizeof tr.uid){
370 6e527fbc 2005-02-13 devnull werrstr("uid too long");
371 6e527fbc 2005-02-13 devnull return -1;
372 6e527fbc 2005-02-13 devnull }
373 6e527fbc 2005-02-13 devnull strcpy(tr.uid, user);
374 6e527fbc 2005-02-13 devnull
375 6e527fbc 2005-02-13 devnull convTR2M(&tr, trbuf);
376 6e527fbc 2005-02-13 devnull if(xiowrite(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN)
377 6e527fbc 2005-02-13 devnull return -1;
378 6e527fbc 2005-02-13 devnull
379 6e527fbc 2005-02-13 devnull len = strlen(resp);
380 6e527fbc 2005-02-13 devnull if(xiowrite(s->asfd, resp, len) != len)
381 6e527fbc 2005-02-13 devnull return -1;
382 6e527fbc 2005-02-13 devnull
383 6e527fbc 2005-02-13 devnull if(xioasrdresp(s->asfd, tabuf, TICKETLEN+AUTHENTLEN) != TICKETLEN+AUTHENTLEN)
384 6e527fbc 2005-02-13 devnull return 0;
385 6e527fbc 2005-02-13 devnull
386 6e527fbc 2005-02-13 devnull convM2T(tabuf, &t, s->k->priv);
387 6e527fbc 2005-02-13 devnull if(t.num != AuthTs
388 6e527fbc 2005-02-13 devnull || memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){
389 6e527fbc 2005-02-13 devnull werrstr("key mismatch with auth server");
390 6e527fbc 2005-02-13 devnull return -1;
391 6e527fbc 2005-02-13 devnull }
392 6e527fbc 2005-02-13 devnull
393 6e527fbc 2005-02-13 devnull convM2A(tabuf+TICKETLEN, &a, t.key);
394 6e527fbc 2005-02-13 devnull if(a.num != AuthAc
395 6e527fbc 2005-02-13 devnull || memcmp(a.chal, tr.chal, sizeof a.chal) != 0
396 6e527fbc 2005-02-13 devnull || a.id != 0){
397 6e527fbc 2005-02-13 devnull werrstr("key2 mismatch with auth server");
398 6e527fbc 2005-02-13 devnull return -1;
399 6e527fbc 2005-02-13 devnull }
400 6e527fbc 2005-02-13 devnull
401 6e527fbc 2005-02-13 devnull s->t = t;
402 6e527fbc 2005-02-13 devnull return 1;
403 6e527fbc 2005-02-13 devnull }
404 6e527fbc 2005-02-13 devnull
405 6e527fbc 2005-02-13 devnull static Role
406 6e527fbc 2005-02-13 devnull chaproles[] =
407 6e527fbc 2005-02-13 devnull {
408 6e527fbc 2005-02-13 devnull "client", chapclient,
409 6e527fbc 2005-02-13 devnull "server", chapserver,
410 6e527fbc 2005-02-13 devnull 0
411 6e527fbc 2005-02-13 devnull };
412 6e527fbc 2005-02-13 devnull
413 6e527fbc 2005-02-13 devnull Proto chap = {
414 6e527fbc 2005-02-13 devnull .name= "chap",
415 6e527fbc 2005-02-13 devnull .roles= chaproles,
416 6e527fbc 2005-02-13 devnull .checkkey= chapcheck,
417 6e527fbc 2005-02-13 devnull .keyprompt= "user? !password?",
418 6e527fbc 2005-02-13 devnull };
419 6e527fbc 2005-02-13 devnull
420 6e527fbc 2005-02-13 devnull Proto mschap = {
421 6e527fbc 2005-02-13 devnull .name= "mschap",
422 6e527fbc 2005-02-13 devnull .roles= chaproles,
423 6e527fbc 2005-02-13 devnull .checkkey= chapcheck,
424 6e527fbc 2005-02-13 devnull .keyprompt= "user? !password?",
425 6e527fbc 2005-02-13 devnull };
426 6e527fbc 2005-02-13 devnull