Blame


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