eap.c revision 1.1.1.4 1 /*
2 * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
3 *
4 * Copyright (c) 2001 by Sun Microsystems, Inc.
5 * All rights reserved.
6 *
7 * Non-exclusive rights to redistribute, modify, translate, and use
8 * this software in source and binary forms, in whole or in part, is
9 * hereby granted, provided that the above copyright notice is
10 * duplicated in any source form, and that neither the name of the
11 * copyright holder nor the author is used to endorse or promote
12 * products derived from this software.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 *
18 * Original version by James Carlson
19 *
20 * This implementation of EAP supports MD5-Challenge and SRP-SHA1
21 * authentication styles. Note that support of MD5-Challenge is a
22 * requirement of RFC 2284, and that it's essentially just a
23 * reimplementation of regular RFC 1994 CHAP using EAP messages.
24 *
25 * As an authenticator ("server"), there are multiple phases for each
26 * style. In the first phase of each style, the unauthenticated peer
27 * name is queried using the EAP Identity request type. If the
28 * "remotename" option is used, then this phase is skipped, because
29 * the peer's name is presumed to be known.
30 *
31 * For MD5-Challenge, there are two phases, and the second phase
32 * consists of sending the challenge itself and handling the
33 * associated response.
34 *
35 * For SRP-SHA1, there are four phases. The second sends 's', 'N',
36 * and 'g'. The reply contains 'A'. The third sends 'B', and the
37 * reply contains 'M1'. The forth sends the 'M2' value.
38 *
39 * As an authenticatee ("client"), there's just a single phase --
40 * responding to the queries generated by the peer. EAP is an
41 * authenticator-driven protocol.
42 *
43 * Based on draft-ietf-pppext-eap-srp-03.txt.
44 */
45
46 /*
47 * Modification by Beniamino Galvani, Mar 2005
48 * Implemented EAP-TLS authentication
49 */
50
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <unistd.h>
55 #include <pwd.h>
56 #include <sys/types.h>
57 #include <sys/stat.h>
58 #include <fcntl.h>
59 #include <assert.h>
60 #include <errno.h>
61
62 #include "pppd.h"
63 #include "pathnames.h"
64 #include "md5.h"
65 #include "eap.h"
66
67 #ifdef CHAPMS
68 #include "chap_ms.h"
69 #endif
70
71 #ifdef USE_SRP
72 #include <t_pwd.h>
73 #include <t_server.h>
74 #include <t_client.h>
75 #include "pppcrypt.h"
76 #endif /* USE_SRP */
77
78 #ifndef SHA_DIGESTSIZE
79 #define SHA_DIGESTSIZE 20
80 #endif
81
82 #ifdef USE_EAPTLS
83 #include "eap-tls.h"
84 #endif /* USE_EAPTLS */
85 #ifdef CHAPMS
86 #include "magic.h"
87 #include "chap_ms.h"
88 #include "chap-new.h"
89 #endif /* CHAPMS */
90
91 eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
92 #ifdef USE_SRP
93 static char *pn_secret = NULL; /* Pseudonym generating secret */
94 #endif
95
96 /*
97 * Command-line options.
98 */
99 static option_t eap_option_list[] = {
100 { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
101 "Set retransmit timeout for EAP Requests (server)" },
102 { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
103 "Set max number of EAP Requests sent (server)" },
104 { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
105 "Set time limit for peer EAP authentication" },
106 { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
107 "Set max number of EAP Requests allows (client)" },
108 { "eap-interval", o_int, &eap_states[0].es_rechallenge,
109 "Set interval for EAP rechallenge" },
110 #ifdef USE_SRP
111 { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
112 "Set interval for SRP lightweight rechallenge" },
113 { "srp-pn-secret", o_string, &pn_secret,
114 "Long term pseudonym generation secret" },
115 { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
116 "Use pseudonym if offered one by server", 1 },
117 #endif
118 { NULL }
119 };
120
121 /*
122 * Protocol entry points.
123 */
124 static void eap_init (int unit);
125 static void eap_input (int unit, u_char *inp, int inlen);
126 static void eap_protrej (int unit);
127 static void eap_lowerup (int unit);
128 static void eap_lowerdown (int unit);
129 static int eap_printpkt (u_char *inp, int inlen,
130 void (*)(void *arg, char *fmt, ...), void *arg);
131
132 struct protent eap_protent = {
133 PPP_EAP, /* protocol number */
134 eap_init, /* initialization procedure */
135 eap_input, /* process a received packet */
136 eap_protrej, /* process a received protocol-reject */
137 eap_lowerup, /* lower layer has gone up */
138 eap_lowerdown, /* lower layer has gone down */
139 NULL, /* open the protocol */
140 NULL, /* close the protocol */
141 eap_printpkt, /* print a packet in readable form */
142 NULL, /* process a received data packet */
143 1, /* protocol enabled */
144 "EAP", /* text name of protocol */
145 NULL, /* text name of corresponding data protocol */
146 eap_option_list, /* list of command-line options */
147 NULL, /* check requested options; assign defaults */
148 NULL, /* configure interface for demand-dial */
149 NULL /* say whether to bring up link for this pkt */
150 };
151
152 #ifdef USE_SRP
153 /*
154 * A well-known 2048 bit modulus.
155 */
156 static const u_char wkmodulus[] = {
157 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
158 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
159 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
160 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
161 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
162 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
163 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
164 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
165 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
166 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
167 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
168 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
169 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
170 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
171 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
172 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
173 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
174 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
175 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
176 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
177 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
178 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
179 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
180 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
181 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
182 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
183 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
184 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
185 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
186 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
187 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
188 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
189 };
190 #endif /* USE_SRP */
191
192 /* Local forward declarations. */
193 static void eap_server_timeout (void *arg);
194
195 /*
196 * Convert EAP state code to printable string for debug.
197 */
198 static const char *
199 eap_state_name(enum eap_state_code esc)
200 {
201 static const char *state_names[] = { EAP_STATES };
202
203 return (state_names[(int)esc]);
204 }
205
206 /*
207 * eap_init - Initialize state for an EAP user. This is currently
208 * called once by main() during start-up.
209 */
210 static void
211 eap_init(int unit)
212 {
213 eap_state *esp = &eap_states[unit];
214
215 BZERO(esp, sizeof (*esp));
216 esp->es_unit = unit;
217 esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
218 esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
219 esp->es_server.ea_id = (u_char)(drand48() * 0x100);
220 esp->es_client.ea_timeout = EAP_DEFREQTIME;
221 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
222 #ifdef USE_EAPTLS
223 esp->es_client.ea_using_eaptls = 0;
224 #endif /* USE_EAPTLS */
225 #ifdef CHAPMS
226 esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
227 #endif
228 }
229
230 /*
231 * eap_client_timeout - Give up waiting for the peer to send any
232 * Request messages.
233 */
234 static void
235 eap_client_timeout(void *arg)
236 {
237 eap_state *esp = (eap_state *) arg;
238
239 if (!eap_client_active(esp))
240 return;
241
242 error("EAP: timeout waiting for Request from peer");
243 auth_withpeer_fail(esp->es_unit, PPP_EAP);
244 esp->es_client.ea_state = eapBadAuth;
245 }
246
247 /*
248 * eap_authwithpeer - Authenticate to our peer (behave as client).
249 *
250 * Start client state and wait for requests. This is called only
251 * after eap_lowerup.
252 */
253 void
254 eap_authwithpeer(int unit, char *localname)
255 {
256 eap_state *esp = &eap_states[unit];
257
258 /* Save the peer name we're given */
259 esp->es_client.ea_name = localname;
260 esp->es_client.ea_namelen = strlen(localname);
261
262 esp->es_client.ea_state = eapListen;
263
264 /*
265 * Start a timer so that if the other end just goes
266 * silent, we don't sit here waiting forever.
267 */
268 if (esp->es_client.ea_timeout > 0)
269 TIMEOUT(eap_client_timeout, (void *)esp,
270 esp->es_client.ea_timeout);
271 }
272
273 /*
274 * Format a standard EAP Failure message and send it to the peer.
275 * (Server operation)
276 */
277 static void
278 eap_send_failure(eap_state *esp)
279 {
280 u_char *outp;
281
282 outp = outpacket_buf;
283
284 MAKEHEADER(outp, PPP_EAP);
285
286 PUTCHAR(EAP_FAILURE, outp);
287 esp->es_server.ea_id++;
288 PUTCHAR(esp->es_server.ea_id, outp);
289 PUTSHORT(EAP_HEADERLEN, outp);
290
291 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
292
293 esp->es_server.ea_state = eapBadAuth;
294 auth_peer_fail(esp->es_unit, PPP_EAP);
295 }
296
297 /*
298 * Format a standard EAP Success message and send it to the peer.
299 * (Server operation)
300 */
301 static void
302 eap_send_success(eap_state *esp)
303 {
304 u_char *outp;
305
306 outp = outpacket_buf;
307
308 MAKEHEADER(outp, PPP_EAP);
309
310 PUTCHAR(EAP_SUCCESS, outp);
311 esp->es_server.ea_id++;
312 PUTCHAR(esp->es_server.ea_id, outp);
313 PUTSHORT(EAP_HEADERLEN, outp);
314
315 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
316
317 auth_peer_success(esp->es_unit, PPP_EAP, 0,
318 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
319 }
320
321 #ifdef USE_SRP
322 /*
323 * Set DES key according to pseudonym-generating secret and current
324 * date.
325 */
326 static bool
327 pncrypt_setkey(int timeoffs)
328 {
329 struct tm *tp;
330 char tbuf[9];
331 SHA1_CTX ctxt;
332 u_char dig[SHA_DIGESTSIZE];
333 time_t reftime;
334
335 if (pn_secret == NULL)
336 return (0);
337 reftime = time(NULL) + timeoffs;
338 tp = localtime(&reftime);
339 SHA1Init(&ctxt);
340 SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
341 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
342 SHA1Update(&ctxt, tbuf, strlen(tbuf));
343 SHA1Final(dig, &ctxt);
344 return (DesSetkey(dig));
345 }
346
347 static char base64[] =
348 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
349
350 struct b64state {
351 u_int32_t bs_bits;
352 int bs_offs;
353 };
354
355 static int
356 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
357 {
358 int outlen = 0;
359
360 while (inlen > 0) {
361 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
362 inlen--;
363 bs->bs_offs += 8;
364 if (bs->bs_offs >= 24) {
365 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
366 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
367 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
368 *outp++ = base64[bs->bs_bits & 0x3F];
369 outlen += 4;
370 bs->bs_offs = 0;
371 bs->bs_bits = 0;
372 }
373 }
374 return (outlen);
375 }
376
377 static int
378 b64flush(struct b64state *bs, u_char *outp)
379 {
380 int outlen = 0;
381
382 if (bs->bs_offs == 8) {
383 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
384 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
385 outlen = 2;
386 } else if (bs->bs_offs == 16) {
387 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
388 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
389 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
390 outlen = 3;
391 }
392 bs->bs_offs = 0;
393 bs->bs_bits = 0;
394 return (outlen);
395 }
396
397 static int
398 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
399 {
400 int outlen = 0;
401 char *cp;
402
403 while (inlen > 0) {
404 if ((cp = strchr(base64, *inp++)) == NULL)
405 break;
406 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
407 inlen--;
408 bs->bs_offs += 6;
409 if (bs->bs_offs >= 8) {
410 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
411 outlen++;
412 bs->bs_offs -= 8;
413 }
414 }
415 return (outlen);
416 }
417 #endif /* USE_SRP */
418
419 /*
420 * Assume that current waiting server state is complete and figure
421 * next state to use based on available authentication data. 'status'
422 * indicates if there was an error in handling the last query. It is
423 * 0 for success and non-zero for failure.
424 */
425 static void
426 eap_figure_next_state(eap_state *esp, int status)
427 {
428 #ifdef USE_SRP
429 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
430 struct t_pw tpw;
431 struct t_confent *tce, mytce;
432 char *cp, *cp2;
433 struct t_server *ts;
434 int id, i, plen, toffs;
435 u_char vals[2];
436 struct b64state bs;
437 #endif /* USE_SRP */
438 #ifdef USE_EAPTLS
439 struct eaptls_session *ets;
440 int secret_len;
441 char secret[MAXWORDLEN];
442 #endif /* USE_EAPTLS */
443
444 esp->es_server.ea_timeout = esp->es_savedtime;
445 #ifdef USE_EAPTLS
446 esp->es_server.ea_prev_state = esp->es_server.ea_state;
447 #endif /* USE_EAPTLS */
448 switch (esp->es_server.ea_state) {
449 case eapBadAuth:
450 return;
451
452 case eapIdentify:
453 #ifdef USE_SRP
454 /* Discard any previous session. */
455 ts = (struct t_server *)esp->es_server.ea_session;
456 if (ts != NULL) {
457 t_serverclose(ts);
458 esp->es_server.ea_session = NULL;
459 esp->es_server.ea_skey = NULL;
460 }
461 #endif /* USE_SRP */
462 if (status != 0) {
463 esp->es_server.ea_state = eapBadAuth;
464 break;
465 }
466 #ifdef USE_SRP
467 /* If we've got a pseudonym, try to decode to real name. */
468 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
469 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
470 SRP_PSEUDO_LEN) == 0 &&
471 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
472 sizeof (secbuf)) {
473 BZERO(&bs, sizeof (bs));
474 plen = b64dec(&bs,
475 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
476 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
477 secbuf);
478 toffs = 0;
479 for (i = 0; i < 5; i++) {
480 pncrypt_setkey(toffs);
481 toffs -= 86400;
482 if (!DesDecrypt(secbuf, clear)) {
483 dbglog("no DES here; cannot decode "
484 "pseudonym");
485 return;
486 }
487 id = *(unsigned char *)clear;
488 if (id + 1 <= plen && id + 9 > plen)
489 break;
490 }
491 if (plen % 8 == 0 && i < 5) {
492 /*
493 * Note that this is always shorter than the
494 * original stored string, so there's no need
495 * to realloc.
496 */
497 if ((i = plen = *(unsigned char *)clear) > 7)
498 i = 7;
499 esp->es_server.ea_peerlen = plen;
500 dp = (unsigned char *)esp->es_server.ea_peer;
501 BCOPY(clear + 1, dp, i);
502 plen -= i;
503 dp += i;
504 sp = secbuf + 8;
505 while (plen > 0) {
506 (void) DesDecrypt(sp, dp);
507 sp += 8;
508 dp += 8;
509 plen -= 8;
510 }
511 esp->es_server.ea_peer[
512 esp->es_server.ea_peerlen] = '\0';
513 dbglog("decoded pseudonym to \"%.*q\"",
514 esp->es_server.ea_peerlen,
515 esp->es_server.ea_peer);
516 } else {
517 dbglog("failed to decode real name");
518 /* Stay in eapIdentfy state; requery */
519 break;
520 }
521 }
522 /* Look up user in secrets database. */
523 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
524 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
525 /* Set up default in case SRP entry is bad */
526 esp->es_server.ea_state = eapMD5Chall;
527 /* Get t_confent based on index in srp-secrets */
528 id = strtol((char *)secbuf, &cp, 10);
529 if (*cp++ != ':' || id < 0)
530 break;
531 if (id == 0) {
532 mytce.index = 0;
533 mytce.modulus.data = (u_char *)wkmodulus;
534 mytce.modulus.len = sizeof (wkmodulus);
535 mytce.generator.data = (u_char *)"\002";
536 mytce.generator.len = 1;
537 tce = &mytce;
538 } else if ((tce = gettcid(id)) != NULL) {
539 /*
540 * Client will have to verify this modulus/
541 * generator combination, and that will take
542 * a while. Lengthen the timeout here.
543 */
544 if (esp->es_server.ea_timeout > 0 &&
545 esp->es_server.ea_timeout < 30)
546 esp->es_server.ea_timeout = 30;
547 } else {
548 break;
549 }
550 if ((cp2 = strchr(cp, ':')) == NULL)
551 break;
552 *cp2++ = '\0';
553 tpw.pebuf.name = esp->es_server.ea_peer;
554 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
555 cp);
556 tpw.pebuf.password.data = tpw.pwbuf;
557 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
558 cp2);
559 tpw.pebuf.salt.data = tpw.saltbuf;
560 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
561 break;
562 esp->es_server.ea_session = (void *)ts;
563 esp->es_server.ea_state = eapSRP1;
564 vals[0] = esp->es_server.ea_id + 1;
565 vals[1] = EAPT_SRP;
566 t_serveraddexdata(ts, vals, 2);
567 /* Generate B; must call before t_servergetkey() */
568 t_servergenexp(ts);
569 break;
570 }
571 #endif /* USE_SRP */
572 #ifdef USE_EAPTLS
573 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
574 esp->es_server.ea_name, secret, &secret_len, 1)) {
575
576 esp->es_server.ea_state = eapTlsStart;
577 break;
578 }
579 #endif /* USE_EAPTLS */
580
581 esp->es_server.ea_state = eapMD5Chall;
582 break;
583
584 #ifdef USE_EAPTLS
585 case eapTlsStart:
586 /* Initialize ssl session */
587 if(!eaptls_init_ssl_server(esp)) {
588 esp->es_server.ea_state = eapBadAuth;
589 break;
590 }
591
592 esp->es_server.ea_state = eapTlsRecv;
593 break;
594
595 case eapTlsRecv:
596 ets = (struct eaptls_session *) esp->es_server.ea_session;
597
598 if(ets->alert_sent) {
599 esp->es_server.ea_state = eapTlsSendAlert;
600 break;
601 }
602
603 if (status) {
604 esp->es_server.ea_state = eapBadAuth;
605 break;
606 }
607 ets = (struct eaptls_session *) esp->es_server.ea_session;
608
609 if(ets->frag)
610 esp->es_server.ea_state = eapTlsSendAck;
611 else
612 esp->es_server.ea_state = eapTlsSend;
613 break;
614
615 case eapTlsSend:
616 ets = (struct eaptls_session *) esp->es_server.ea_session;
617
618 if(ets->frag)
619 esp->es_server.ea_state = eapTlsRecvAck;
620 else
621 if(SSL_is_init_finished(ets->ssl))
622 esp->es_server.ea_state = eapTlsRecvClient;
623 else
624 /* JJK Add "TLS empty record" message here ??? */
625 esp->es_server.ea_state = eapTlsRecv;
626 break;
627
628 case eapTlsSendAck:
629 esp->es_server.ea_state = eapTlsRecv;
630 break;
631
632 case eapTlsRecvAck:
633 if (status)
634 {
635 esp->es_server.ea_state = eapBadAuth;
636 break;
637 }
638
639 esp->es_server.ea_state = eapTlsSend;
640 break;
641
642 case eapTlsSendAlert:
643 esp->es_server.ea_state = eapTlsRecvAlertAck;
644 break;
645 #endif /* USE_EAPTLS */
646
647 case eapSRP1:
648 #ifdef USE_SRP
649 ts = (struct t_server *)esp->es_server.ea_session;
650 if (ts != NULL && status != 0) {
651 t_serverclose(ts);
652 esp->es_server.ea_session = NULL;
653 esp->es_server.ea_skey = NULL;
654 }
655 #endif /* USE_SRP */
656 if (status == 1) {
657 esp->es_server.ea_state = eapMD5Chall;
658 } else if (status != 0 || esp->es_server.ea_session == NULL) {
659 esp->es_server.ea_state = eapBadAuth;
660 } else {
661 esp->es_server.ea_state = eapSRP2;
662 }
663 break;
664
665 case eapSRP2:
666 #ifdef USE_SRP
667 ts = (struct t_server *)esp->es_server.ea_session;
668 if (ts != NULL && status != 0) {
669 t_serverclose(ts);
670 esp->es_server.ea_session = NULL;
671 esp->es_server.ea_skey = NULL;
672 }
673 #endif /* USE_SRP */
674 if (status != 0 || esp->es_server.ea_session == NULL) {
675 esp->es_server.ea_state = eapBadAuth;
676 } else {
677 esp->es_server.ea_state = eapSRP3;
678 }
679 break;
680
681 case eapSRP3:
682 case eapSRP4:
683 #ifdef USE_SRP
684 ts = (struct t_server *)esp->es_server.ea_session;
685 if (ts != NULL && status != 0) {
686 t_serverclose(ts);
687 esp->es_server.ea_session = NULL;
688 esp->es_server.ea_skey = NULL;
689 }
690 #endif /* USE_SRP */
691 if (status != 0 || esp->es_server.ea_session == NULL) {
692 esp->es_server.ea_state = eapBadAuth;
693 } else {
694 esp->es_server.ea_state = eapOpen;
695 }
696 break;
697
698 #ifdef CHAPMS
699 case eapMSCHAPv2Chall:
700 #endif
701 case eapMD5Chall:
702 if (status != 0) {
703 esp->es_server.ea_state = eapBadAuth;
704 } else {
705 esp->es_server.ea_state = eapOpen;
706 }
707 break;
708
709 default:
710 esp->es_server.ea_state = eapBadAuth;
711 break;
712 }
713 if (esp->es_server.ea_state == eapBadAuth)
714 eap_send_failure(esp);
715
716 #ifdef USE_EAPTLS
717 dbglog("EAP id=0x%2x '%s' -> '%s'", esp->es_server.ea_id, eap_state_name(esp->es_server.ea_prev_state), eap_state_name(esp->es_server.ea_state));
718 #endif /* USE_EAPTLS */
719 }
720
721 #if CHAPMS
722 static int
723 eap_chapms2_verify_response(int id, char *name,
724 unsigned char *secret, int secret_len,
725 unsigned char *challenge, unsigned char *response,
726 char *message, int message_space)
727 {
728 unsigned char md[MS_CHAP2_RESPONSE_LEN];
729 char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
730 int challenge_len, response_len;
731
732 challenge_len = *challenge++; /* skip length, is 16 */
733 response_len = *response++;
734 if (response_len != MS_CHAP2_RESPONSE_LEN)
735 goto bad; /* not even the right length */
736
737 /* Generate the expected response and our mutual auth. */
738 ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name,
739 (char *)secret, secret_len, md,
740 (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
741
742 /* compare MDs and send the appropriate status */
743 /*
744 * Per RFC 2759, success message must be formatted as
745 * "S=<auth_string> M=<message>"
746 * where
747 * <auth_string> is the Authenticator Response (mutual auth)
748 * <message> is a text message
749 *
750 * However, some versions of Windows (win98 tested) do not know
751 * about the M=<message> part (required per RFC 2759) and flag
752 * it as an error (reported incorrectly as an encryption error
753 * to the user). Since the RFC requires it, and it can be
754 * useful information, we supply it if the peer is a conforming
755 * system. Luckily (?), win98 sets the Flags field to 0x04
756 * (contrary to RFC requirements) so we can use that to
757 * distinguish between conforming and non-conforming systems.
758 *
759 * Special thanks to Alex Swiridov <say (at) real.kharkov.ua> for
760 * help debugging this.
761 */
762 if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
763 MS_CHAP2_NTRESP_LEN) == 0) {
764 if (response[MS_CHAP2_FLAGS])
765 slprintf(message, message_space, "S=%s", saresponse);
766 else
767 slprintf(message, message_space, "S=%s M=%s",
768 saresponse, "Access granted");
769 return 1;
770 }
771
772 bad:
773 /*
774 * Failure message must be formatted as
775 * "E=e R=r C=c V=v M=m"
776 * where
777 * e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE)
778 * r = retry (we use 1, ok to retry)
779 * c = challenge to use for next response, we reuse previous
780 * v = Change Password version supported, we use 0
781 * m = text message
782 *
783 * The M=m part is only for MS-CHAPv2. Neither win2k nor
784 * win98 (others untested) display the message to the user anyway.
785 * They also both ignore the E=e code.
786 *
787 * Note that it's safe to reuse the same challenge as we don't
788 * actually accept another response based on the error message
789 * (and no clients try to resend a response anyway).
790 *
791 * Basically, this whole bit is useless code, even the small
792 * implementation here is only because of overspecification.
793 */
794 slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
795 challenge_len, challenge, "Access denied");
796 return 0;
797 }
798
799 static struct chap_digest_type eap_chapms2_digest = {
800 CHAP_MICROSOFT_V2, /* code */
801 NULL, /* chapms2_generate_challenge, */
802 eap_chapms2_verify_response,
803 NULL, /* chapms2_make_response, */
804 NULL, /* chapms2_check_success, */
805 NULL, /* chapms_handle_failure, */
806 };
807
808 /*
809 * eap_chap_verify_response - check whether the peer's response matches
810 * what we think it should be. Returns 1 if it does (authentication
811 * succeeded), or 0 if it doesn't.
812 */
813 static int
814 eap_chap_verify_response(char *name, char *ourname, int id,
815 struct chap_digest_type *digest,
816 unsigned char *challenge, unsigned char *response,
817 char *message, int message_space)
818 {
819 int ok;
820 unsigned char secret[MAXSECRETLEN];
821 int secret_len;
822
823 /* Get the secret that the peer is supposed to know */
824 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
825 error("No CHAP secret found for authenticating %q", name);
826 return 0;
827 }
828
829 ok = digest->verify_response(id, name, secret, secret_len, challenge,
830 response, message, message_space);
831 memset(secret, 0, sizeof(secret));
832
833 return ok;
834 }
835
836 /*
837 * Format and send an CHAPV2-Success/Failure EAP Request message.
838 */
839 static void
840 eap_chapms2_send_request(eap_state *esp, u_char id,
841 u_char opcode, u_char chapid,
842 char *message, int message_len)
843 {
844 u_char *outp;
845 int msglen;
846
847 outp = outpacket_buf;
848
849 MAKEHEADER(outp, PPP_EAP);
850
851 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
852 msglen += message_len;
853
854 PUTCHAR(EAP_REQUEST, outp);
855 PUTCHAR(id, outp);
856 PUTSHORT(msglen, outp);
857 PUTCHAR(EAPT_MSCHAPV2, outp);
858 PUTCHAR(opcode, outp);
859 PUTCHAR(chapid, outp);
860 /* MS len */
861 PUTSHORT(msglen - 5, outp);
862 BCOPY(message, outp, message_len);
863
864 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
865
866 if (opcode == CHAP_SUCCESS) {
867 auth_peer_success(esp->es_unit, PPP_EAP, 0,
868 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
869 }
870 else {
871 esp->es_server.ea_state = eapBadAuth;
872 auth_peer_fail(esp->es_unit, PPP_EAP);
873 }
874 }
875 #endif /* CHAPMS */
876
877 /*
878 * Format an EAP Request message and send it to the peer. Message
879 * type depends on current state. (Server operation)
880 */
881 static void
882 eap_send_request(eap_state *esp)
883 {
884 u_char *outp;
885 u_char *lenloc;
886 u_char *ptr;
887 int outlen;
888 int challen;
889 char *str;
890 #ifdef USE_SRP
891 struct t_server *ts;
892 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
893 int i, j;
894 struct b64state b64;
895 SHA1_CTX ctxt;
896 #endif /* USE_SRP */
897
898 /* Handle both initial auth and restart */
899 if (esp->es_server.ea_state < eapIdentify &&
900 esp->es_server.ea_state != eapInitial) {
901 esp->es_server.ea_state = eapIdentify;
902 if (explicit_remote) {
903 /*
904 * If we already know the peer's
905 * unauthenticated name, then there's no
906 * reason to ask. Go to next state instead.
907 */
908 esp->es_server.ea_peer = remote_name;
909 esp->es_server.ea_peerlen = strlen(remote_name);
910 eap_figure_next_state(esp, 0);
911 }
912 }
913
914 if (esp->es_server.ea_maxrequests > 0 &&
915 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
916 if (esp->es_server.ea_responses > 0)
917 error("EAP: too many Requests sent");
918 else
919 error("EAP: no response to Requests");
920 eap_send_failure(esp);
921 return;
922 }
923
924 outp = outpacket_buf;
925
926 MAKEHEADER(outp, PPP_EAP);
927
928 PUTCHAR(EAP_REQUEST, outp);
929 PUTCHAR(esp->es_server.ea_id, outp);
930 lenloc = outp;
931 INCPTR(2, outp);
932
933 switch (esp->es_server.ea_state) {
934 case eapIdentify:
935 PUTCHAR(EAPT_IDENTITY, outp);
936 str = "Name";
937 challen = strlen(str);
938 BCOPY(str, outp, challen);
939 INCPTR(challen, outp);
940 break;
941
942 case eapMD5Chall:
943 PUTCHAR(EAPT_MD5CHAP, outp);
944 /*
945 * pick a random challenge length between
946 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
947 */
948 challen = (drand48() *
949 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
950 MIN_CHALLENGE_LENGTH;
951 PUTCHAR(challen, outp);
952 esp->es_challen = challen;
953 ptr = esp->es_challenge;
954 while (--challen >= 0)
955 *ptr++ = (u_char) (drand48() * 0x100);
956 BCOPY(esp->es_challenge, outp, esp->es_challen);
957 INCPTR(esp->es_challen, outp);
958 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
959 INCPTR(esp->es_server.ea_namelen, outp);
960 break;
961
962 #ifdef CHAPMS
963 case eapMSCHAPv2Chall:
964 challen = 0x10;
965 esp->es_challen = challen;
966 esp->es_challenge[0] = challen;
967 random_bytes(&esp->es_challenge[1], challen);
968
969 PUTCHAR(EAPT_MSCHAPV2, outp);
970 PUTCHAR(CHAP_CHALLENGE, outp);
971 PUTCHAR(esp->es_server.ea_id, outp);
972 /* MS len */
973 PUTSHORT(5 + challen +
974 esp->es_server.ea_namelen,
975 outp);
976 /* challen + challenge */
977 BCOPY(esp->es_challenge, outp, challen+1);
978 INCPTR(challen+1, outp);
979 BCOPY(esp->es_server.ea_name,
980 outp,
981 esp->es_server.ea_namelen);
982 INCPTR(esp->es_server.ea_namelen, outp);
983 break;
984 #endif /* CHAPMS */
985
986 #ifdef USE_EAPTLS
987 case eapTlsStart:
988 PUTCHAR(EAPT_TLS, outp);
989 PUTCHAR(EAP_TLS_FLAGS_START, outp);
990 eap_figure_next_state(esp, 0);
991 break;
992
993 case eapTlsSend:
994 eaptls_send(esp->es_server.ea_session, &outp);
995 eap_figure_next_state(esp, 0);
996 break;
997
998 case eapTlsSendAck:
999 PUTCHAR(EAPT_TLS, outp);
1000 PUTCHAR(0, outp);
1001 eap_figure_next_state(esp, 0);
1002 break;
1003
1004 case eapTlsSendAlert:
1005 eaptls_send(esp->es_server.ea_session, &outp);
1006 eap_figure_next_state(esp, 0);
1007 break;
1008 #endif /* USE_EAPTLS */
1009
1010 #ifdef USE_SRP
1011 case eapSRP1:
1012 PUTCHAR(EAPT_SRP, outp);
1013 PUTCHAR(EAPSRP_CHALLENGE, outp);
1014
1015 PUTCHAR(esp->es_server.ea_namelen, outp);
1016 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
1017 INCPTR(esp->es_server.ea_namelen, outp);
1018
1019 ts = (struct t_server *)esp->es_server.ea_session;
1020 assert(ts != NULL);
1021 PUTCHAR(ts->s.len, outp);
1022 BCOPY(ts->s.data, outp, ts->s.len);
1023 INCPTR(ts->s.len, outp);
1024
1025 if (ts->g.len == 1 && ts->g.data[0] == 2) {
1026 PUTCHAR(0, outp);
1027 } else {
1028 PUTCHAR(ts->g.len, outp);
1029 BCOPY(ts->g.data, outp, ts->g.len);
1030 INCPTR(ts->g.len, outp);
1031 }
1032
1033 if (ts->n.len != sizeof (wkmodulus) ||
1034 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
1035 BCOPY(ts->n.data, outp, ts->n.len);
1036 INCPTR(ts->n.len, outp);
1037 }
1038 break;
1039
1040 case eapSRP2:
1041 PUTCHAR(EAPT_SRP, outp);
1042 PUTCHAR(EAPSRP_SKEY, outp);
1043
1044 ts = (struct t_server *)esp->es_server.ea_session;
1045 assert(ts != NULL);
1046 BCOPY(ts->B.data, outp, ts->B.len);
1047 INCPTR(ts->B.len, outp);
1048 break;
1049
1050 case eapSRP3:
1051 PUTCHAR(EAPT_SRP, outp);
1052 PUTCHAR(EAPSRP_SVALIDATOR, outp);
1053 PUTLONG(SRPVAL_EBIT, outp);
1054 ts = (struct t_server *)esp->es_server.ea_session;
1055 assert(ts != NULL);
1056 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
1057 INCPTR(SHA_DIGESTSIZE, outp);
1058
1059 if (pncrypt_setkey(0)) {
1060 /* Generate pseudonym */
1061 optr = outp;
1062 cp = (unsigned char *)esp->es_server.ea_peer;
1063 if ((j = i = esp->es_server.ea_peerlen) > 7)
1064 j = 7;
1065 clear[0] = i;
1066 BCOPY(cp, clear + 1, j);
1067 i -= j;
1068 cp += j;
1069 if (!DesEncrypt(clear, cipher)) {
1070 dbglog("no DES here; not generating pseudonym");
1071 break;
1072 }
1073 BZERO(&b64, sizeof (b64));
1074 outp++; /* space for pseudonym length */
1075 outp += b64enc(&b64, cipher, 8, outp);
1076 while (i >= 8) {
1077 (void) DesEncrypt(cp, cipher);
1078 outp += b64enc(&b64, cipher, 8, outp);
1079 cp += 8;
1080 i -= 8;
1081 }
1082 if (i > 0) {
1083 BCOPY(cp, clear, i);
1084 cp += i;
1085 while (i < 8) {
1086 *cp++ = drand48() * 0x100;
1087 i++;
1088 }
1089 (void) DesEncrypt(clear, cipher);
1090 outp += b64enc(&b64, cipher, 8, outp);
1091 }
1092 outp += b64flush(&b64, outp);
1093
1094 /* Set length and pad out to next 20 octet boundary */
1095 i = outp - optr - 1;
1096 *optr = i;
1097 i %= SHA_DIGESTSIZE;
1098 if (i != 0) {
1099 while (i < SHA_DIGESTSIZE) {
1100 *outp++ = drand48() * 0x100;
1101 i++;
1102 }
1103 }
1104
1105 /* Obscure the pseudonym with SHA1 hash */
1106 SHA1Init(&ctxt);
1107 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1108 SHA1Update(&ctxt, esp->es_server.ea_skey,
1109 SESSION_KEY_LEN);
1110 SHA1Update(&ctxt, esp->es_server.ea_peer,
1111 esp->es_server.ea_peerlen);
1112 while (optr < outp) {
1113 SHA1Final(dig, &ctxt);
1114 cp = dig;
1115 while (cp < dig + SHA_DIGESTSIZE)
1116 *optr++ ^= *cp++;
1117 SHA1Init(&ctxt);
1118 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1119 SHA1Update(&ctxt, esp->es_server.ea_skey,
1120 SESSION_KEY_LEN);
1121 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
1122 SHA_DIGESTSIZE);
1123 }
1124 }
1125 break;
1126
1127 case eapSRP4:
1128 PUTCHAR(EAPT_SRP, outp);
1129 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1130 challen = MIN_CHALLENGE_LENGTH +
1131 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1132 esp->es_challen = challen;
1133 ptr = esp->es_challenge;
1134 while (--challen >= 0)
1135 *ptr++ = drand48() * 0x100;
1136 BCOPY(esp->es_challenge, outp, esp->es_challen);
1137 INCPTR(esp->es_challen, outp);
1138 break;
1139 #endif /* USE_SRP */
1140
1141 default:
1142 return;
1143 }
1144
1145 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1146 PUTSHORT(outlen, lenloc);
1147
1148 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1149
1150 esp->es_server.ea_requests++;
1151
1152 if (esp->es_server.ea_timeout > 0)
1153 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1154 }
1155
1156 /*
1157 * eap_authpeer - Authenticate our peer (behave as server).
1158 *
1159 * Start server state and send first request. This is called only
1160 * after eap_lowerup.
1161 */
1162 void
1163 eap_authpeer(int unit, char *localname)
1164 {
1165 eap_state *esp = &eap_states[unit];
1166
1167 /* Save the name we're given. */
1168 esp->es_server.ea_name = localname;
1169 esp->es_server.ea_namelen = strlen(localname);
1170
1171 esp->es_savedtime = esp->es_server.ea_timeout;
1172
1173 /* Lower layer up yet? */
1174 if (esp->es_server.ea_state == eapInitial ||
1175 esp->es_server.ea_state == eapPending) {
1176 esp->es_server.ea_state = eapPending;
1177 return;
1178 }
1179
1180 esp->es_server.ea_state = eapPending;
1181
1182 /* ID number not updated here intentionally; hashed into M1 */
1183 eap_send_request(esp);
1184 }
1185
1186 /*
1187 * eap_server_timeout - Retransmission timer for sending Requests
1188 * expired.
1189 */
1190 static void
1191 eap_server_timeout(void *arg)
1192 {
1193 #ifdef USE_EAPTLS
1194 u_char *outp;
1195 u_char *lenloc;
1196 int outlen;
1197 #endif /* USE_EAPTLS */
1198
1199 eap_state *esp = (eap_state *) arg;
1200
1201 if (!eap_server_active(esp))
1202 return;
1203
1204 #ifdef USE_EAPTLS
1205 switch(esp->es_server.ea_prev_state) {
1206
1207 /*
1208 * In eap-tls the state changes after a request, so we return to
1209 * previous state ...
1210 */
1211 case(eapTlsStart):
1212 case(eapTlsSendAck):
1213 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1214 break;
1215
1216 /*
1217 * ... or resend the stored data
1218 */
1219 case(eapTlsSend):
1220 case(eapTlsSendAlert):
1221 outp = outpacket_buf;
1222 MAKEHEADER(outp, PPP_EAP);
1223 PUTCHAR(EAP_REQUEST, outp);
1224 PUTCHAR(esp->es_server.ea_id, outp);
1225 lenloc = outp;
1226 INCPTR(2, outp);
1227
1228 eaptls_retransmit(esp->es_server.ea_session, &outp);
1229
1230 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1231 PUTSHORT(outlen, lenloc);
1232 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1233 esp->es_server.ea_requests++;
1234
1235 if (esp->es_server.ea_timeout > 0)
1236 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1237
1238 return;
1239 default:
1240 break;
1241 }
1242 #endif /* USE_EAPTLS */
1243
1244 /* EAP ID number must not change on timeout. */
1245 eap_send_request(esp);
1246 }
1247
1248 /*
1249 * When it's time to send rechallenge the peer, this timeout is
1250 * called. Once the rechallenge is successful, the response handler
1251 * will restart the timer. If it fails, then the link is dropped.
1252 */
1253 static void
1254 eap_rechallenge(void *arg)
1255 {
1256 eap_state *esp = (eap_state *)arg;
1257
1258 if (esp->es_server.ea_state != eapOpen &&
1259 esp->es_server.ea_state != eapSRP4)
1260 return;
1261
1262 esp->es_server.ea_requests = 0;
1263 esp->es_server.ea_state = eapIdentify;
1264 eap_figure_next_state(esp, 0);
1265 esp->es_server.ea_id++;
1266 eap_send_request(esp);
1267 }
1268
1269 static void
1270 srp_lwrechallenge(void *arg)
1271 {
1272 eap_state *esp = (eap_state *)arg;
1273
1274 if (esp->es_server.ea_state != eapOpen ||
1275 esp->es_server.ea_type != EAPT_SRP)
1276 return;
1277
1278 esp->es_server.ea_requests = 0;
1279 esp->es_server.ea_state = eapSRP4;
1280 esp->es_server.ea_id++;
1281 eap_send_request(esp);
1282 }
1283
1284 /*
1285 * eap_lowerup - The lower layer is now up.
1286 *
1287 * This is called before either eap_authpeer or eap_authwithpeer. See
1288 * link_established() in auth.c. All that's necessary here is to
1289 * return to closed state so that those two routines will do the right
1290 * thing.
1291 */
1292 static void
1293 eap_lowerup(int unit)
1294 {
1295 eap_state *esp = &eap_states[unit];
1296
1297 /* Discard any (possibly authenticated) peer name. */
1298 if (esp->es_server.ea_peer != NULL &&
1299 esp->es_server.ea_peer != remote_name)
1300 free(esp->es_server.ea_peer);
1301 esp->es_server.ea_peer = NULL;
1302 if (esp->es_client.ea_peer != NULL)
1303 free(esp->es_client.ea_peer);
1304 esp->es_client.ea_peer = NULL;
1305
1306 esp->es_client.ea_state = eapClosed;
1307 esp->es_server.ea_state = eapClosed;
1308 }
1309
1310 /*
1311 * eap_lowerdown - The lower layer is now down.
1312 *
1313 * Cancel all timeouts and return to initial state.
1314 */
1315 static void
1316 eap_lowerdown(int unit)
1317 {
1318 eap_state *esp = &eap_states[unit];
1319
1320 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1321 UNTIMEOUT(eap_client_timeout, (void *)esp);
1322 }
1323 if (eap_server_active(esp)) {
1324 if (esp->es_server.ea_timeout > 0) {
1325 UNTIMEOUT(eap_server_timeout, (void *)esp);
1326 }
1327 } else {
1328 if ((esp->es_server.ea_state == eapOpen ||
1329 esp->es_server.ea_state == eapSRP4) &&
1330 esp->es_rechallenge > 0) {
1331 UNTIMEOUT(eap_rechallenge, (void *)esp);
1332 }
1333 if (esp->es_server.ea_state == eapOpen &&
1334 esp->es_lwrechallenge > 0) {
1335 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1336 }
1337 }
1338
1339 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1340 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1341 }
1342
1343 /*
1344 * eap_protrej - Peer doesn't speak this protocol.
1345 *
1346 * This shouldn't happen. If it does, it represents authentication
1347 * failure.
1348 */
1349 static void
1350 eap_protrej(int unit)
1351 {
1352 eap_state *esp = &eap_states[unit];
1353
1354 if (eap_client_active(esp)) {
1355 error("EAP authentication failed due to Protocol-Reject");
1356 auth_withpeer_fail(unit, PPP_EAP);
1357 }
1358 if (eap_server_active(esp)) {
1359 error("EAP authentication of peer failed on Protocol-Reject");
1360 auth_peer_fail(unit, PPP_EAP);
1361 }
1362 eap_lowerdown(unit);
1363 }
1364
1365 /*
1366 * Format and send a regular EAP Response message.
1367 */
1368 static void
1369 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1370 u_char *str, int lenstr)
1371 {
1372 u_char *outp;
1373 int msglen;
1374
1375 outp = outpacket_buf;
1376
1377 MAKEHEADER(outp, PPP_EAP);
1378
1379 PUTCHAR(EAP_RESPONSE, outp);
1380 PUTCHAR(id, outp);
1381 esp->es_client.ea_id = id;
1382 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1383 PUTSHORT(msglen, outp);
1384 PUTCHAR(typenum, outp);
1385 if (lenstr > 0) {
1386 BCOPY(str, outp, lenstr);
1387 }
1388
1389 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1390 }
1391
1392 /*
1393 * Format and send an MD5-Challenge EAP Response message.
1394 */
1395 static void
1396 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1397 char *name, int namelen)
1398 {
1399 u_char *outp;
1400 int msglen;
1401
1402 outp = outpacket_buf;
1403
1404 MAKEHEADER(outp, PPP_EAP);
1405
1406 PUTCHAR(EAP_RESPONSE, outp);
1407 PUTCHAR(id, outp);
1408 esp->es_client.ea_id = id;
1409 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
1410 namelen;
1411 PUTSHORT(msglen, outp);
1412 PUTCHAR(EAPT_MD5CHAP, outp);
1413 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1414 BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
1415 INCPTR(MD5_SIGNATURE_SIZE, outp);
1416 if (namelen > 0) {
1417 BCOPY(name, outp, namelen);
1418 }
1419
1420 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1421 }
1422
1423 #ifdef USE_SRP
1424 /*
1425 * Format and send a SRP EAP Response message.
1426 */
1427 static void
1428 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1429 u_char *str, int lenstr)
1430 {
1431 u_char *outp;
1432 int msglen;
1433
1434 outp = outpacket_buf;
1435
1436 MAKEHEADER(outp, PPP_EAP);
1437
1438 PUTCHAR(EAP_RESPONSE, outp);
1439 PUTCHAR(id, outp);
1440 esp->es_client.ea_id = id;
1441 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1442 PUTSHORT(msglen, outp);
1443 PUTCHAR(EAPT_SRP, outp);
1444 PUTCHAR(subtypenum, outp);
1445 if (lenstr > 0) {
1446 BCOPY(str, outp, lenstr);
1447 }
1448
1449 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1450 }
1451
1452 /*
1453 * Format and send a SRP EAP Client Validator Response message.
1454 */
1455 static void
1456 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1457 {
1458 u_char *outp;
1459 int msglen;
1460
1461 outp = outpacket_buf;
1462
1463 MAKEHEADER(outp, PPP_EAP);
1464
1465 PUTCHAR(EAP_RESPONSE, outp);
1466 PUTCHAR(id, outp);
1467 esp->es_client.ea_id = id;
1468 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1469 SHA_DIGESTSIZE;
1470 PUTSHORT(msglen, outp);
1471 PUTCHAR(EAPT_SRP, outp);
1472 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1473 PUTLONG(flags, outp);
1474 BCOPY(str, outp, SHA_DIGESTSIZE);
1475
1476 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1477 }
1478 #endif /* USE_SRP */
1479
1480 #ifdef USE_EAPTLS
1481 /*
1482 * Send an EAP-TLS response message with tls data
1483 */
1484 static void
1485 eap_tls_response(eap_state *esp, u_char id)
1486 {
1487 u_char *outp;
1488 int outlen;
1489 u_char *lenloc;
1490
1491 outp = outpacket_buf;
1492
1493 MAKEHEADER(outp, PPP_EAP);
1494
1495 PUTCHAR(EAP_RESPONSE, outp);
1496 PUTCHAR(id, outp);
1497
1498 lenloc = outp;
1499 INCPTR(2, outp);
1500
1501 /*
1502 If the id in the request is unchanged, we must retransmit
1503 the old data
1504 */
1505 if(id == esp->es_client.ea_id)
1506 eaptls_retransmit(esp->es_client.ea_session, &outp);
1507 else
1508 eaptls_send(esp->es_client.ea_session, &outp);
1509
1510 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1511 PUTSHORT(outlen, lenloc);
1512
1513 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1514
1515 esp->es_client.ea_id = id;
1516 }
1517
1518 /*
1519 * Send an EAP-TLS ack
1520 */
1521 static void
1522 eap_tls_sendack(eap_state *esp, u_char id)
1523 {
1524 u_char *outp;
1525 int outlen;
1526 u_char *lenloc;
1527
1528 outp = outpacket_buf;
1529
1530 MAKEHEADER(outp, PPP_EAP);
1531
1532 PUTCHAR(EAP_RESPONSE, outp);
1533 PUTCHAR(id, outp);
1534 esp->es_client.ea_id = id;
1535
1536 lenloc = outp;
1537 INCPTR(2, outp);
1538
1539 PUTCHAR(EAPT_TLS, outp);
1540 PUTCHAR(0, outp);
1541
1542 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1543 PUTSHORT(outlen, lenloc);
1544
1545 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1546 }
1547 #endif /* USE_EAPTLS */
1548
1549 static void
1550 eap_send_nak(eap_state *esp, u_char id, u_char type)
1551 {
1552 u_char *outp;
1553 int msglen;
1554
1555 outp = outpacket_buf;
1556
1557 MAKEHEADER(outp, PPP_EAP);
1558
1559 PUTCHAR(EAP_RESPONSE, outp);
1560 PUTCHAR(id, outp);
1561 esp->es_client.ea_id = id;
1562 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1563 PUTSHORT(msglen, outp);
1564 PUTCHAR(EAPT_NAK, outp);
1565 PUTCHAR(type, outp);
1566
1567 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1568 }
1569
1570 #ifdef USE_SRP
1571 static char *
1572 name_of_pn_file(void)
1573 {
1574 char *user, *path, *file;
1575 struct passwd *pw;
1576 size_t pl;
1577 static bool pnlogged = 0;
1578
1579 pw = getpwuid(getuid());
1580 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1581 errno = EINVAL;
1582 return (NULL);
1583 }
1584 file = _PATH_PSEUDONYM;
1585 pl = strlen(user) + strlen(file) + 2;
1586 path = malloc(pl);
1587 if (path == NULL)
1588 return (NULL);
1589 (void) slprintf(path, pl, "%s/%s", user, file);
1590 if (!pnlogged) {
1591 dbglog("pseudonym file: %s", path);
1592 pnlogged = 1;
1593 }
1594 return (path);
1595 }
1596
1597 static int
1598 open_pn_file(mode_t modebits)
1599 {
1600 char *path;
1601 int fd, err;
1602
1603 if ((path = name_of_pn_file()) == NULL)
1604 return (-1);
1605 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1606 err = errno;
1607 free(path);
1608 errno = err;
1609 return (fd);
1610 }
1611
1612 static void
1613 remove_pn_file(void)
1614 {
1615 char *path;
1616
1617 if ((path = name_of_pn_file()) != NULL) {
1618 (void) unlink(path);
1619 (void) free(path);
1620 }
1621 }
1622
1623 static void
1624 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1625 {
1626 u_char val;
1627 u_char *datp, *digp;
1628 SHA1_CTX ctxt;
1629 u_char dig[SHA_DIGESTSIZE];
1630 int dsize, fd, olen = len;
1631
1632 /*
1633 * Do the decoding by working backwards. This eliminates the need
1634 * to save the decoded output in a separate buffer.
1635 */
1636 val = id;
1637 while (len > 0) {
1638 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1639 dsize = SHA_DIGESTSIZE;
1640 len -= dsize;
1641 datp = inp + len;
1642 SHA1Init(&ctxt);
1643 SHA1Update(&ctxt, &val, 1);
1644 SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
1645 if (len > 0) {
1646 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1647 } else {
1648 SHA1Update(&ctxt, esp->es_client.ea_name,
1649 esp->es_client.ea_namelen);
1650 }
1651 SHA1Final(dig, &ctxt);
1652 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1653 *datp++ ^= *digp;
1654 }
1655
1656 /* Now check that the result is sane */
1657 if (olen <= 0 || *inp + 1 > olen) {
1658 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1659 return;
1660 }
1661
1662 /* Save it away */
1663 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1664 if (fd < 0) {
1665 dbglog("EAP: error saving pseudonym: %m");
1666 return;
1667 }
1668 len = write(fd, inp + 1, *inp);
1669 if (close(fd) != -1 && len == *inp) {
1670 dbglog("EAP: saved pseudonym");
1671 esp->es_usedpseudo = 0;
1672 } else {
1673 dbglog("EAP: failed to save pseudonym");
1674 remove_pn_file();
1675 }
1676 }
1677 #endif /* USE_SRP */
1678
1679 #if CHAPMS
1680 /*
1681 * Format and send an CHAPV2-Challenge EAP Response message.
1682 */
1683 static void
1684 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
1685 {
1686 u_char *outp;
1687 int msglen;
1688
1689 outp = outpacket_buf;
1690
1691 MAKEHEADER(outp, PPP_EAP);
1692
1693 PUTCHAR(EAP_RESPONSE, outp);
1694 PUTCHAR(id, outp);
1695 esp->es_client.ea_id = id;
1696 msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
1697 PUTSHORT(msglen, outp);
1698 PUTCHAR(EAPT_MSCHAPV2, outp);
1699 PUTCHAR(CHAP_RESPONSE, outp);
1700 PUTCHAR(chapid, outp);
1701 PUTCHAR(0, outp);
1702 /* len */
1703 PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
1704 BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
1705 INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
1706 BCOPY(user, outp, user_len);
1707
1708 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1709 }
1710 #endif
1711
1712 /*
1713 * eap_request - Receive EAP Request message (client mode).
1714 */
1715 static void
1716 eap_request(eap_state *esp, u_char *inp, int id, int len)
1717 {
1718 u_char typenum;
1719 u_char vallen;
1720 int secret_len;
1721 char secret[MAXWORDLEN];
1722 char rhostname[256];
1723 MD5_CTX mdContext;
1724 u_char hash[MD5_SIGNATURE_SIZE];
1725 #ifdef USE_EAPTLS
1726 u_char flags;
1727 struct eaptls_session *ets = esp->es_client.ea_session;
1728 #endif /* USE_EAPTLS */
1729
1730 #ifdef USE_SRP
1731 struct t_client *tc;
1732 struct t_num sval, gval, Nval, *Ap, Bval;
1733 u_char vals[2];
1734 SHA1_CTX ctxt;
1735 u_char dig[SHA_DIGESTSIZE];
1736 int fd;
1737 #endif /* USE_SRP */
1738
1739 /*
1740 * Ignore requests if we're not open
1741 */
1742 if (esp->es_client.ea_state <= eapClosed)
1743 return;
1744
1745 /*
1746 * Note: we update es_client.ea_id *only if* a Response
1747 * message is being generated. Otherwise, we leave it the
1748 * same for duplicate detection purposes.
1749 */
1750
1751 esp->es_client.ea_requests++;
1752 if (esp->es_client.ea_maxrequests != 0 &&
1753 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1754 info("EAP: received too many Request messages");
1755 if (esp->es_client.ea_timeout > 0) {
1756 UNTIMEOUT(eap_client_timeout, (void *)esp);
1757 }
1758 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1759 return;
1760 }
1761
1762 if (len <= 0) {
1763 error("EAP: empty Request message discarded");
1764 return;
1765 }
1766
1767 GETCHAR(typenum, inp);
1768 len--;
1769
1770 switch (typenum) {
1771 case EAPT_IDENTITY:
1772 if (len > 0)
1773 info("EAP: Identity prompt \"%.*q\"", len, inp);
1774 #ifdef USE_SRP
1775 if (esp->es_usepseudo &&
1776 (esp->es_usedpseudo == 0 ||
1777 (esp->es_usedpseudo == 1 &&
1778 id == esp->es_client.ea_id))) {
1779 esp->es_usedpseudo = 1;
1780 /* Try to get a pseudonym */
1781 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1782 strcpy(rhostname, SRP_PSEUDO_ID);
1783 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1784 sizeof (rhostname) - SRP_PSEUDO_LEN);
1785 /* XXX NAI unsupported */
1786 if (len > 0) {
1787 eap_send_response(esp, id, typenum,
1788 rhostname, len + SRP_PSEUDO_LEN);
1789 }
1790 (void) close(fd);
1791 if (len > 0)
1792 break;
1793 }
1794 }
1795 /* Stop using pseudonym now. */
1796 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1797 remove_pn_file();
1798 esp->es_usedpseudo = 2;
1799 }
1800 #endif /* USE_SRP */
1801 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1802 esp->es_client.ea_namelen);
1803 break;
1804
1805 case EAPT_NOTIFICATION:
1806 if (len > 0)
1807 info("EAP: Notification \"%.*q\"", len, inp);
1808 eap_send_response(esp, id, typenum, NULL, 0);
1809 break;
1810
1811 case EAPT_NAK:
1812 /*
1813 * Avoid the temptation to send Response Nak in reply
1814 * to Request Nak here. It can only lead to trouble.
1815 */
1816 warn("EAP: unexpected Nak in Request; ignored");
1817 /* Return because we're waiting for something real. */
1818 return;
1819
1820 case EAPT_MD5CHAP:
1821 if (len < 1) {
1822 error("EAP: received MD5-Challenge with no data");
1823 /* Bogus request; wait for something real. */
1824 return;
1825 }
1826 GETCHAR(vallen, inp);
1827 len--;
1828 if (vallen < 8 || vallen > len) {
1829 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1830 vallen, len);
1831 /* Try something better. */
1832 eap_send_nak(esp, id, EAPT_SRP);
1833 break;
1834 }
1835
1836 /* Not so likely to happen. */
1837 if (len - vallen >= sizeof (rhostname)) {
1838 dbglog("EAP: trimming really long peer name down");
1839 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1840 rhostname[sizeof (rhostname) - 1] = '\0';
1841 } else {
1842 BCOPY(inp + vallen, rhostname, len - vallen);
1843 rhostname[len - vallen] = '\0';
1844 }
1845
1846 /* In case the remote doesn't give us his name. */
1847 if (explicit_remote ||
1848 (remote_name[0] != '\0' && vallen == len))
1849 strlcpy(rhostname, remote_name, sizeof (rhostname));
1850
1851 /*
1852 * Get the secret for authenticating ourselves with
1853 * the specified host.
1854 */
1855 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1856 rhostname, secret, &secret_len, 0)) {
1857 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1858 eap_send_nak(esp, id, EAPT_SRP);
1859 break;
1860 }
1861 MD5_Init(&mdContext);
1862 typenum = id;
1863 MD5_Update(&mdContext, &typenum, 1);
1864 MD5_Update(&mdContext, (u_char *)secret, secret_len);
1865 BZERO(secret, sizeof (secret));
1866 MD5_Update(&mdContext, inp, vallen);
1867 MD5_Final(hash, &mdContext);
1868 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1869 esp->es_client.ea_namelen);
1870 break;
1871
1872 #ifdef USE_EAPTLS
1873 case EAPT_TLS:
1874
1875 switch(esp->es_client.ea_state) {
1876
1877 case eapListen:
1878
1879 if (len < 1) {
1880 error("EAP: received EAP-TLS Listen packet with no data");
1881 /* Bogus request; wait for something real. */
1882 return;
1883 }
1884 GETCHAR(flags, inp);
1885 if(flags & EAP_TLS_FLAGS_START){
1886
1887 esp->es_client.ea_using_eaptls = 1;
1888
1889 if (explicit_remote){
1890 esp->es_client.ea_peer = strdup(remote_name);
1891 esp->es_client.ea_peerlen = strlen(remote_name);
1892 } else
1893 esp->es_client.ea_peer = NULL;
1894
1895 /* Init ssl session */
1896 if(!eaptls_init_ssl_client(esp)) {
1897 dbglog("cannot init ssl");
1898 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1899 esp->es_client.ea_using_eaptls = 0;
1900 break;
1901 }
1902
1903 ets = esp->es_client.ea_session;
1904 eap_tls_response(esp, id);
1905 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1906 break;
1907 }
1908
1909 /* The server has sent a bad start packet. */
1910 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1911 break;
1912
1913 case eapTlsRecvAck:
1914 eap_tls_response(esp, id);
1915 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1916 break;
1917
1918 case eapTlsRecv:
1919 if (len < 1) {
1920 error("EAP: discarding EAP-TLS Receive packet with no data");
1921 /* Bogus request; wait for something real. */
1922 return;
1923 }
1924 eaptls_receive(ets, inp, len);
1925
1926 if(ets->frag) {
1927 eap_tls_sendack(esp, id);
1928 esp->es_client.ea_state = eapTlsRecv;
1929 break;
1930 }
1931
1932 if(ets->alert_recv) {
1933 eap_tls_sendack(esp, id);
1934 esp->es_client.ea_state = eapTlsRecvFailure;
1935 break;
1936 }
1937
1938 /* Check if TLS handshake is finished */
1939 if(eaptls_is_init_finished(ets)) {
1940 #ifdef MPPE
1941 eaptls_gen_mppe_keys(ets, 1);
1942 #endif
1943 eaptls_free_session(ets);
1944 eap_tls_sendack(esp, id);
1945 esp->es_client.ea_state = eapTlsRecvSuccess;
1946 break;
1947 }
1948
1949 eap_tls_response(esp,id);
1950 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1951 break;
1952
1953 default:
1954 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1955 esp->es_client.ea_using_eaptls = 0;
1956 break;
1957 }
1958
1959 break;
1960 #endif /* USE_EAPTLS */
1961
1962 #ifdef USE_SRP
1963 case EAPT_SRP:
1964 if (len < 1) {
1965 error("EAP: received empty SRP Request");
1966 /* Bogus request; wait for something real. */
1967 return;
1968 }
1969
1970 /* Get subtype */
1971 GETCHAR(vallen, inp);
1972 len--;
1973 switch (vallen) {
1974 case EAPSRP_CHALLENGE:
1975 tc = NULL;
1976 if (esp->es_client.ea_session != NULL) {
1977 tc = (struct t_client *)esp->es_client.
1978 ea_session;
1979 /*
1980 * If this is a new challenge, then start
1981 * over with a new client session context.
1982 * Otherwise, just resend last response.
1983 */
1984 if (id != esp->es_client.ea_id) {
1985 t_clientclose(tc);
1986 esp->es_client.ea_session = NULL;
1987 tc = NULL;
1988 }
1989 }
1990 /* No session key just yet */
1991 esp->es_client.ea_skey = NULL;
1992 if (tc == NULL) {
1993 GETCHAR(vallen, inp);
1994 len--;
1995 if (vallen >= len) {
1996 error("EAP: badly-formed SRP Challenge"
1997 " (name)");
1998 /* Ignore badly-formed messages */
1999 return;
2000 }
2001 BCOPY(inp, rhostname, vallen);
2002 rhostname[vallen] = '\0';
2003 INCPTR(vallen, inp);
2004 len -= vallen;
2005
2006 /*
2007 * In case the remote doesn't give us his name,
2008 * use configured name.
2009 */
2010 if (explicit_remote ||
2011 (remote_name[0] != '\0' && vallen == 0)) {
2012 strlcpy(rhostname, remote_name,
2013 sizeof (rhostname));
2014 }
2015
2016 if (esp->es_client.ea_peer != NULL)
2017 free(esp->es_client.ea_peer);
2018 esp->es_client.ea_peer = strdup(rhostname);
2019 esp->es_client.ea_peerlen = strlen(rhostname);
2020
2021 GETCHAR(vallen, inp);
2022 len--;
2023 if (vallen >= len) {
2024 error("EAP: badly-formed SRP Challenge"
2025 " (s)");
2026 /* Ignore badly-formed messages */
2027 return;
2028 }
2029 sval.data = inp;
2030 sval.len = vallen;
2031 INCPTR(vallen, inp);
2032 len -= vallen;
2033
2034 GETCHAR(vallen, inp);
2035 len--;
2036 if (vallen > len) {
2037 error("EAP: badly-formed SRP Challenge"
2038 " (g)");
2039 /* Ignore badly-formed messages */
2040 return;
2041 }
2042 /* If no generator present, then use value 2 */
2043 if (vallen == 0) {
2044 gval.data = (u_char *)"\002";
2045 gval.len = 1;
2046 } else {
2047 gval.data = inp;
2048 gval.len = vallen;
2049 }
2050 INCPTR(vallen, inp);
2051 len -= vallen;
2052
2053 /*
2054 * If no modulus present, then use well-known
2055 * value.
2056 */
2057 if (len == 0) {
2058 Nval.data = (u_char *)wkmodulus;
2059 Nval.len = sizeof (wkmodulus);
2060 } else {
2061 Nval.data = inp;
2062 Nval.len = len;
2063 }
2064 tc = t_clientopen(esp->es_client.ea_name,
2065 &Nval, &gval, &sval);
2066 if (tc == NULL) {
2067 eap_send_nak(esp, id, EAPT_MD5CHAP);
2068 break;
2069 }
2070 esp->es_client.ea_session = (void *)tc;
2071
2072 /* Add Challenge ID & type to verifier */
2073 vals[0] = id;
2074 vals[1] = EAPT_SRP;
2075 t_clientaddexdata(tc, vals, 2);
2076 }
2077 Ap = t_clientgenexp(tc);
2078 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
2079 Ap->len);
2080 break;
2081
2082 case EAPSRP_SKEY:
2083 tc = (struct t_client *)esp->es_client.ea_session;
2084 if (tc == NULL) {
2085 warn("EAP: peer sent Subtype 2 without 1");
2086 eap_send_nak(esp, id, EAPT_MD5CHAP);
2087 break;
2088 }
2089 if (esp->es_client.ea_skey != NULL) {
2090 /*
2091 * ID number should not change here. Warn
2092 * if it does (but otherwise ignore).
2093 */
2094 if (id != esp->es_client.ea_id) {
2095 warn("EAP: ID changed from %d to %d "
2096 "in SRP Subtype 2 rexmit",
2097 esp->es_client.ea_id, id);
2098 }
2099 } else {
2100 if (get_srp_secret(esp->es_unit,
2101 esp->es_client.ea_name,
2102 esp->es_client.ea_peer, secret, 0) == 0) {
2103 /*
2104 * Can't work with this peer because
2105 * the secret is missing. Just give
2106 * up.
2107 */
2108 eap_send_nak(esp, id, EAPT_MD5CHAP);
2109 break;
2110 }
2111 Bval.data = inp;
2112 Bval.len = len;
2113 t_clientpasswd(tc, secret);
2114 BZERO(secret, sizeof (secret));
2115 esp->es_client.ea_skey =
2116 t_clientgetkey(tc, &Bval);
2117 if (esp->es_client.ea_skey == NULL) {
2118 /* Server is rogue; stop now */
2119 error("EAP: SRP server is rogue");
2120 goto client_failure;
2121 }
2122 }
2123 eap_srpval_response(esp, id, SRPVAL_EBIT,
2124 t_clientresponse(tc));
2125 break;
2126
2127 case EAPSRP_SVALIDATOR:
2128 tc = (struct t_client *)esp->es_client.ea_session;
2129 if (tc == NULL || esp->es_client.ea_skey == NULL) {
2130 warn("EAP: peer sent Subtype 3 without 1/2");
2131 eap_send_nak(esp, id, EAPT_MD5CHAP);
2132 break;
2133 }
2134 /*
2135 * If we're already open, then this ought to be a
2136 * duplicate. Otherwise, check that the server is
2137 * who we think it is.
2138 */
2139 if (esp->es_client.ea_state == eapOpen) {
2140 if (id != esp->es_client.ea_id) {
2141 warn("EAP: ID changed from %d to %d "
2142 "in SRP Subtype 3 rexmit",
2143 esp->es_client.ea_id, id);
2144 }
2145 } else {
2146 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
2147 if (len < 0 || t_clientverify(tc, inp +
2148 sizeof (u_int32_t)) != 0) {
2149 error("EAP: SRP server verification "
2150 "failed");
2151 goto client_failure;
2152 }
2153 GETLONG(esp->es_client.ea_keyflags, inp);
2154 /* Save pseudonym if user wants it. */
2155 if (len > 0 && esp->es_usepseudo) {
2156 INCPTR(SHA_DIGESTSIZE, inp);
2157 write_pseudonym(esp, inp, len, id);
2158 }
2159 }
2160 /*
2161 * We've verified our peer. We're now mostly done,
2162 * except for waiting on the regular EAP Success
2163 * message.
2164 */
2165 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2166 break;
2167
2168 case EAPSRP_LWRECHALLENGE:
2169 if (len < 4) {
2170 warn("EAP: malformed Lightweight rechallenge");
2171 return;
2172 }
2173 SHA1Init(&ctxt);
2174 vals[0] = id;
2175 SHA1Update(&ctxt, vals, 1);
2176 SHA1Update(&ctxt, esp->es_client.ea_skey,
2177 SESSION_KEY_LEN);
2178 SHA1Update(&ctxt, inp, len);
2179 SHA1Update(&ctxt, esp->es_client.ea_name,
2180 esp->es_client.ea_namelen);
2181 SHA1Final(dig, &ctxt);
2182 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2183 SHA_DIGESTSIZE);
2184 break;
2185
2186 default:
2187 error("EAP: unknown SRP Subtype %d", vallen);
2188 eap_send_nak(esp, id, EAPT_MD5CHAP);
2189 break;
2190 }
2191 break;
2192 #endif /* USE_SRP */
2193
2194 #ifdef CHAPMS
2195 case EAPT_MSCHAPV2:
2196 if (len < 4) {
2197 error("EAP: received invalid MSCHAPv2 packet, too short");
2198 return;
2199 }
2200 unsigned char opcode;
2201 GETCHAR(opcode, inp);
2202 unsigned char chapid; /* Chapv2-ID */
2203 GETCHAR(chapid, inp);
2204 short mssize;
2205 GETSHORT(mssize, inp);
2206
2207 /* Validate the mssize field */
2208 if (len != mssize) {
2209 error("EAP: received invalid MSCHAPv2 packet, invalid length");
2210 return;
2211 }
2212 len -= 4;
2213
2214 /* If MSCHAPv2 digest was not found, NAK the packet */
2215 if (!esp->es_client.digest) {
2216 error("EAP MSCHAPv2 not supported");
2217 eap_send_nak(esp, id, EAPT_SRP);
2218 return;
2219 }
2220
2221 switch (opcode) {
2222 case CHAP_CHALLENGE: {
2223
2224 /* make_response() expects: VLEN + VALUE */
2225 u_char *challenge = inp;
2226
2227 unsigned char vsize;
2228 GETCHAR(vsize, inp);
2229 len -= 1;
2230
2231 /* Validate the VALUE field */
2232 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2233 error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
2234 return;
2235 }
2236
2237 /* Increment past the VALUE field */
2238 INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
2239 len -= MS_CHAP2_PEER_CHAL_LEN;
2240
2241 /* Extract the hostname */
2242 rhostname[0] = '\0';
2243 if (len > 0) {
2244 if (len >= sizeof (rhostname)) {
2245 dbglog("EAP: trimming really long peer name down");
2246 len = sizeof(rhostname) - 1;
2247 }
2248 BCOPY(inp, rhostname, len);
2249 rhostname[len] = '\0';
2250 }
2251
2252 /* In case the remote doesn't give us his name. */
2253 if (explicit_remote || (remote_name[0] != '\0' && len == 0))
2254 strlcpy(rhostname, remote_name, sizeof(rhostname));
2255
2256 /* Get the secret for authenticating ourselves with the specified host. */
2257 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
2258 rhostname, secret, &secret_len, 0)) {
2259 dbglog("EAP: no CHAP secret for auth to %q", rhostname);
2260 eap_send_nak(esp, id, EAPT_SRP);
2261 break;
2262 }
2263
2264 /* Create the MSCHAPv2 response (and add to cache) */
2265 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2266 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2267 challenge, secret, secret_len, NULL);
2268
2269 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2270 break;
2271 }
2272 case CHAP_SUCCESS: {
2273
2274 /* Check response for mutual authentication */
2275 u_char status = CHAP_FAILURE;
2276 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2277 info("Chap authentication succeeded! %.*v", len, inp);
2278 status = CHAP_SUCCESS;
2279 }
2280 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2281 break;
2282 }
2283 case CHAP_FAILURE: {
2284
2285 /* Process the failure string, and log appropriate information */
2286 esp->es_client.digest->handle_failure(inp, len);
2287
2288 u_char status = CHAP_FAILURE;
2289 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2290 goto client_failure; /* force termination */
2291 }
2292 default:
2293
2294 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2295 eap_send_nak(esp, id, EAPT_SRP);
2296 }
2297
2298 break;
2299 #endif /* CHAPMS */
2300
2301 default:
2302 info("EAP: unknown authentication type %d; Naking", typenum);
2303 eap_send_nak(esp, id, EAPT_SRP);
2304 break;
2305 }
2306
2307 if (esp->es_client.ea_timeout > 0) {
2308 UNTIMEOUT(eap_client_timeout, (void *)esp);
2309 TIMEOUT(eap_client_timeout, (void *)esp,
2310 esp->es_client.ea_timeout);
2311 }
2312 return;
2313
2314 client_failure:
2315 esp->es_client.ea_state = eapBadAuth;
2316 if (esp->es_client.ea_timeout > 0) {
2317 UNTIMEOUT(eap_client_timeout, (void *)esp);
2318 }
2319 esp->es_client.ea_session = NULL;
2320 #ifdef USE_SRP
2321 t_clientclose(tc);
2322 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2323 #endif /* USE_SRP */
2324 }
2325
2326 /*
2327 * eap_response - Receive EAP Response message (server mode).
2328 */
2329 static void
2330 eap_response(eap_state *esp, u_char *inp, int id, int len)
2331 {
2332 u_char typenum;
2333 u_char vallen;
2334 int secret_len;
2335 char secret[MAXSECRETLEN];
2336 char rhostname[256];
2337 MD5_CTX mdContext;
2338 u_char hash[MD5_SIGNATURE_SIZE];
2339 #ifdef USE_SRP
2340 struct t_server *ts;
2341 struct t_num A;
2342 SHA1_CTX ctxt;
2343 u_char dig[SHA_DIGESTSIZE];
2344 SHA1_CTX ctxt;
2345 u_char dig[SHA_DIGESTSIZE];
2346 #endif /* USE_SRP */
2347
2348 #ifdef USE_EAPTLS
2349 struct eaptls_session *ets;
2350 u_char flags;
2351 #endif /* USE_EAPTLS */
2352 #ifdef CHAPMS
2353 u_char opcode;
2354 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2355 unsigned char *, unsigned char *, char *, int);
2356 char response_message[256];
2357 #endif /* CHAPMS */
2358
2359 /*
2360 * Ignore responses if we're not open
2361 */
2362 if (esp->es_server.ea_state <= eapClosed)
2363 return;
2364
2365 if (esp->es_server.ea_id != id) {
2366 dbglog("EAP: discarding Response %d; expected ID %d", id,
2367 esp->es_server.ea_id);
2368 return;
2369 }
2370
2371 esp->es_server.ea_responses++;
2372
2373 if (len <= 0) {
2374 error("EAP: empty Response message discarded");
2375 return;
2376 }
2377
2378 GETCHAR(typenum, inp);
2379 len--;
2380
2381 switch (typenum) {
2382 case EAPT_IDENTITY:
2383 if (esp->es_server.ea_state != eapIdentify) {
2384 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2385 inp);
2386 break;
2387 }
2388 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2389 if (esp->es_server.ea_peer != NULL &&
2390 esp->es_server.ea_peer != remote_name)
2391 free(esp->es_server.ea_peer);
2392 esp->es_server.ea_peer = malloc(len + 1);
2393 if (esp->es_server.ea_peer == NULL) {
2394 esp->es_server.ea_peerlen = 0;
2395 eap_figure_next_state(esp, 1);
2396 break;
2397 }
2398 BCOPY(inp, esp->es_server.ea_peer, len);
2399 esp->es_server.ea_peer[len] = '\0';
2400 esp->es_server.ea_peerlen = len;
2401 eap_figure_next_state(esp, 0);
2402 break;
2403
2404 #ifdef USE_EAPTLS
2405 case EAPT_TLS:
2406 switch(esp->es_server.ea_state) {
2407
2408 case eapTlsRecv:
2409
2410 ets = (struct eaptls_session *) esp->es_server.ea_session;
2411
2412 eap_figure_next_state(esp,
2413 eaptls_receive(esp->es_server.ea_session, inp, len));
2414
2415 if(ets->alert_recv) {
2416 eap_send_failure(esp);
2417 break;
2418 }
2419 break;
2420
2421 case eapTlsRecvAck:
2422 if(len > 1) {
2423 dbglog("EAP-TLS ACK with extra data");
2424 }
2425 eap_figure_next_state(esp, 0);
2426 break;
2427
2428 case eapTlsRecvClient:
2429 /* Receive authentication response from client */
2430 if (len > 0) {
2431 GETCHAR(flags, inp);
2432
2433 if(len == 1 && !flags) { /* Ack = ok */
2434 #ifdef MPPE
2435 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2436 #endif
2437 eap_send_success(esp);
2438 }
2439 else { /* failure */
2440 warn("Server authentication failed");
2441 eap_send_failure(esp);
2442 }
2443 }
2444 else
2445 warn("Bogus EAP-TLS packet received from client");
2446
2447 eaptls_free_session(esp->es_server.ea_session);
2448
2449 break;
2450
2451 case eapTlsRecvAlertAck:
2452 eap_send_failure(esp);
2453 break;
2454
2455 default:
2456 eap_figure_next_state(esp, 1);
2457 break;
2458 }
2459 break;
2460 #endif /* USE_EAPTLS */
2461
2462 case EAPT_NOTIFICATION:
2463 dbglog("EAP unexpected Notification; response discarded");
2464 break;
2465
2466 case EAPT_NAK:
2467 if (len < 1) {
2468 info("EAP: Nak Response with no suggested protocol");
2469 eap_figure_next_state(esp, 1);
2470 break;
2471 }
2472
2473 GETCHAR(vallen, inp);
2474 len--;
2475
2476 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2477 /* Peer cannot Nak Identify Request */
2478 eap_figure_next_state(esp, 1);
2479 break;
2480 }
2481
2482 switch (vallen) {
2483 case EAPT_SRP:
2484 /* Run through SRP validator selection again. */
2485 esp->es_server.ea_state = eapIdentify;
2486 eap_figure_next_state(esp, 0);
2487 break;
2488
2489 case EAPT_MD5CHAP:
2490 esp->es_server.ea_state = eapMD5Chall;
2491 break;
2492
2493 #ifdef USE_EAPTLS
2494 /* Send EAP-TLS start packet */
2495 case EAPT_TLS:
2496 esp->es_server.ea_state = eapTlsStart;
2497 break;
2498 #endif /* USE_EAPTLS */
2499
2500 #ifdef CHAPMS
2501 case EAPT_MSCHAPV2:
2502 info("EAP: peer proposes MSCHAPv2");
2503 esp->es_server.ea_state = eapMSCHAPv2Chall;
2504 break;
2505 #endif /* CHAPMS */
2506
2507 default:
2508 dbglog("EAP: peer requesting unknown Type %d", vallen);
2509 switch (esp->es_server.ea_state) {
2510 case eapSRP1:
2511 case eapSRP2:
2512 case eapSRP3:
2513 esp->es_server.ea_state = eapMD5Chall;
2514 break;
2515 case eapMD5Chall:
2516 case eapSRP4:
2517 esp->es_server.ea_state = eapIdentify;
2518 eap_figure_next_state(esp, 0);
2519 break;
2520 default:
2521 break;
2522 }
2523 break;
2524 }
2525 break;
2526
2527 case EAPT_MD5CHAP:
2528 if (esp->es_server.ea_state != eapMD5Chall) {
2529 error("EAP: unexpected MD5-Response");
2530 eap_figure_next_state(esp, 1);
2531 break;
2532 }
2533 if (len < 1) {
2534 error("EAP: received MD5-Response with no data");
2535 eap_figure_next_state(esp, 1);
2536 break;
2537 }
2538 GETCHAR(vallen, inp);
2539 len--;
2540 if (vallen != 16 || vallen > len) {
2541 error("EAP: MD5-Response with bad length %d", vallen);
2542 eap_figure_next_state(esp, 1);
2543 break;
2544 }
2545
2546 /* Not so likely to happen. */
2547 if (len - vallen >= sizeof (rhostname)) {
2548 dbglog("EAP: trimming really long peer name down");
2549 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2550 rhostname[sizeof (rhostname) - 1] = '\0';
2551 } else {
2552 BCOPY(inp + vallen, rhostname, len - vallen);
2553 rhostname[len - vallen] = '\0';
2554 }
2555
2556 /* In case the remote doesn't give us his name. */
2557 if (explicit_remote ||
2558 (remote_name[0] != '\0' && vallen == len))
2559 strlcpy(rhostname, remote_name, sizeof (rhostname));
2560
2561 /*
2562 * Get the secret for authenticating the specified
2563 * host.
2564 */
2565 if (!get_secret(esp->es_unit, rhostname,
2566 esp->es_server.ea_name, secret, &secret_len, 1)) {
2567 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2568 eap_send_failure(esp);
2569 break;
2570 }
2571 MD5_Init(&mdContext);
2572 MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
2573 MD5_Update(&mdContext, (u_char *)secret, secret_len);
2574 BZERO(secret, sizeof (secret));
2575 MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
2576 MD5_Final(hash, &mdContext);
2577 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
2578 eap_send_failure(esp);
2579 break;
2580 }
2581 esp->es_server.ea_type = EAPT_MD5CHAP;
2582 eap_send_success(esp);
2583 eap_figure_next_state(esp, 0);
2584 if (esp->es_rechallenge != 0)
2585 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2586 break;
2587
2588 #ifdef CHAPMS
2589 case EAPT_MSCHAPV2:
2590 if (len < 1) {
2591 error("EAP: received MSCHAPv2 with no data");
2592 eap_figure_next_state(esp, 1);
2593 break;
2594 }
2595 GETCHAR(opcode, inp);
2596 len--;
2597
2598 switch (opcode) {
2599 case CHAP_RESPONSE:
2600 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2601 error("EAP: unexpected MSCHAPv2-Response");
2602 eap_figure_next_state(esp, 1);
2603 break;
2604 }
2605 /* skip MS ID + len */
2606 INCPTR(3, inp);
2607 GETCHAR(vallen, inp);
2608 len -= 4;
2609
2610 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2611 error("EAP: Invalid MSCHAPv2-Response "
2612 "length %d", vallen);
2613 eap_figure_next_state(esp, 1);
2614 break;
2615 }
2616
2617 /* Not so likely to happen. */
2618 if (len - vallen >= sizeof (rhostname)) {
2619 dbglog("EAP: trimming really long peer name down");
2620 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2621 rhostname[sizeof (rhostname) - 1] = '\0';
2622 } else {
2623 BCOPY(inp + vallen, rhostname, len - vallen);
2624 rhostname[len - vallen] = '\0';
2625 }
2626
2627 /* In case the remote doesn't give us his name. */
2628 if (explicit_remote ||
2629 (remote_name[0] != '\0' && vallen == len))
2630 strlcpy(rhostname, remote_name, sizeof (rhostname));
2631
2632 if (chap_verify_hook)
2633 chap_verifier = chap_verify_hook;
2634 else
2635 chap_verifier = eap_chap_verify_response;
2636
2637 esp->es_server.ea_id += 1;
2638 if ((*chap_verifier)(rhostname,
2639 esp->es_server.ea_name,
2640 id,
2641 &eap_chapms2_digest,
2642 esp->es_challenge,
2643 inp - 1,
2644 response_message,
2645 sizeof(response_message)))
2646 {
2647 info("EAP: MSCHAPv2 success for peer %q",
2648 rhostname);
2649 esp->es_server.ea_type = EAPT_MSCHAPV2;
2650 eap_chapms2_send_request(esp,
2651 esp->es_server.ea_id,
2652 CHAP_SUCCESS,
2653 esp->es_server.ea_id,
2654 response_message,
2655 strlen(response_message));
2656 eap_figure_next_state(esp, 0);
2657 if (esp->es_rechallenge != 0)
2658 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2659 }
2660 else {
2661 warn("EAP: MSCHAPv2 failure for peer %q",
2662 rhostname);
2663 eap_chapms2_send_request(esp,
2664 esp->es_server.ea_id,
2665 CHAP_FAILURE,
2666 esp->es_server.ea_id,
2667 response_message,
2668 strlen(response_message));
2669 }
2670 break;
2671 case CHAP_SUCCESS:
2672 info("EAP: MSCHAPv2 success confirmed");
2673 break;
2674 case CHAP_FAILURE:
2675 info("EAP: MSCHAPv2 failure confirmed");
2676 break;
2677 default:
2678 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2679 eap_send_nak(esp, id, EAPT_SRP);
2680 }
2681
2682 break;
2683 #endif /* CHAPMS */
2684
2685 #ifdef USE_SRP
2686 case EAPT_SRP:
2687 if (len < 1) {
2688 error("EAP: empty SRP Response");
2689 eap_figure_next_state(esp, 1);
2690 break;
2691 }
2692 GETCHAR(typenum, inp);
2693 len--;
2694 switch (typenum) {
2695 case EAPSRP_CKEY:
2696 if (esp->es_server.ea_state != eapSRP1) {
2697 error("EAP: unexpected SRP Subtype 1 Response");
2698 eap_figure_next_state(esp, 1);
2699 break;
2700 }
2701 A.data = inp;
2702 A.len = len;
2703 ts = (struct t_server *)esp->es_server.ea_session;
2704 assert(ts != NULL);
2705 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2706 if (esp->es_server.ea_skey == NULL) {
2707 /* Client's A value is bogus; terminate now */
2708 error("EAP: bogus A value from client");
2709 eap_send_failure(esp);
2710 } else {
2711 eap_figure_next_state(esp, 0);
2712 }
2713 break;
2714
2715 case EAPSRP_CVALIDATOR:
2716 if (esp->es_server.ea_state != eapSRP2) {
2717 error("EAP: unexpected SRP Subtype 2 Response");
2718 eap_figure_next_state(esp, 1);
2719 break;
2720 }
2721 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
2722 error("EAP: M1 length %d < %d", len,
2723 sizeof (u_int32_t) + SHA_DIGESTSIZE);
2724 eap_figure_next_state(esp, 1);
2725 break;
2726 }
2727 GETLONG(esp->es_server.ea_keyflags, inp);
2728 ts = (struct t_server *)esp->es_server.ea_session;
2729 assert(ts != NULL);
2730 if (t_serververify(ts, inp)) {
2731 info("EAP: unable to validate client identity");
2732 eap_send_failure(esp);
2733 break;
2734 }
2735 eap_figure_next_state(esp, 0);
2736 break;
2737
2738 case EAPSRP_ACK:
2739 if (esp->es_server.ea_state != eapSRP3) {
2740 error("EAP: unexpected SRP Subtype 3 Response");
2741 eap_send_failure(esp);
2742 break;
2743 }
2744 esp->es_server.ea_type = EAPT_SRP;
2745 eap_send_success(esp);
2746 eap_figure_next_state(esp, 0);
2747 if (esp->es_rechallenge != 0)
2748 TIMEOUT(eap_rechallenge, esp,
2749 esp->es_rechallenge);
2750 if (esp->es_lwrechallenge != 0)
2751 TIMEOUT(srp_lwrechallenge, esp,
2752 esp->es_lwrechallenge);
2753 break;
2754
2755 case EAPSRP_LWRECHALLENGE:
2756 if (esp->es_server.ea_state != eapSRP4) {
2757 info("EAP: unexpected SRP Subtype 4 Response");
2758 return;
2759 }
2760 if (len != SHA_DIGESTSIZE) {
2761 error("EAP: bad Lightweight rechallenge "
2762 "response");
2763 return;
2764 }
2765 SHA1Init(&ctxt);
2766 vallen = id;
2767 SHA1Update(&ctxt, &vallen, 1);
2768 SHA1Update(&ctxt, esp->es_server.ea_skey,
2769 SESSION_KEY_LEN);
2770 SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
2771 SHA1Update(&ctxt, esp->es_server.ea_peer,
2772 esp->es_server.ea_peerlen);
2773 SHA1Final(dig, &ctxt);
2774 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
2775 error("EAP: failed Lightweight rechallenge");
2776 eap_send_failure(esp);
2777 break;
2778 }
2779 esp->es_server.ea_state = eapOpen;
2780 if (esp->es_lwrechallenge != 0)
2781 TIMEOUT(srp_lwrechallenge, esp,
2782 esp->es_lwrechallenge);
2783 break;
2784 }
2785 break;
2786 #endif /* USE_SRP */
2787
2788 default:
2789 /* This can't happen. */
2790 error("EAP: unknown Response type %d; ignored", typenum);
2791 return;
2792 }
2793
2794 if (esp->es_server.ea_timeout > 0) {
2795 UNTIMEOUT(eap_server_timeout, (void *)esp);
2796 }
2797
2798 if (esp->es_server.ea_state != eapBadAuth &&
2799 esp->es_server.ea_state != eapOpen) {
2800 esp->es_server.ea_id++;
2801 eap_send_request(esp);
2802 }
2803 }
2804
2805 /*
2806 * eap_success - Receive EAP Success message (client mode).
2807 */
2808 static void
2809 eap_success(eap_state *esp, u_char *inp, int id, int len)
2810 {
2811 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2812 #ifdef USE_EAPTLS
2813 && esp->es_client.ea_state != eapTlsRecvSuccess
2814 #endif /* USE_EAPTLS */
2815 ) {
2816 dbglog("EAP unexpected success message in state %s (%d)",
2817 eap_state_name(esp->es_client.ea_state),
2818 esp->es_client.ea_state);
2819 return;
2820 }
2821
2822 #ifdef USE_EAPTLS
2823 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2824 eapTlsRecvSuccess) {
2825 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2826 eap_state_name(esp->es_client.ea_state),
2827 esp->es_client.ea_state);
2828 return;
2829 }
2830 #endif /* USE_EAPTLS */
2831
2832 if (esp->es_client.ea_timeout > 0) {
2833 UNTIMEOUT(eap_client_timeout, (void *)esp);
2834 }
2835
2836 if (len > 0) {
2837 /* This is odd. The spec doesn't allow for this. */
2838 PRINTMSG(inp, len);
2839 }
2840
2841 esp->es_client.ea_state = eapOpen;
2842 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2843 }
2844
2845 /*
2846 * eap_failure - Receive EAP Failure message (client mode).
2847 */
2848 static void
2849 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2850 {
2851 /*
2852 * Ignore failure messages if we're not open
2853 */
2854 if (esp->es_client.ea_state <= eapClosed)
2855 return;
2856
2857 if (!eap_client_active(esp)) {
2858 dbglog("EAP unexpected failure message in state %s (%d)",
2859 eap_state_name(esp->es_client.ea_state),
2860 esp->es_client.ea_state);
2861 }
2862
2863 if (esp->es_client.ea_timeout > 0) {
2864 UNTIMEOUT(eap_client_timeout, (void *)esp);
2865 }
2866
2867 if (len > 0) {
2868 /* This is odd. The spec doesn't allow for this. */
2869 PRINTMSG(inp, len);
2870 }
2871
2872 esp->es_client.ea_state = eapBadAuth;
2873
2874 error("EAP: peer reports authentication failure");
2875 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2876 }
2877
2878 /*
2879 * eap_input - Handle received EAP message.
2880 */
2881 static void
2882 eap_input(int unit, u_char *inp, int inlen)
2883 {
2884 eap_state *esp = &eap_states[unit];
2885 u_char code, id;
2886 int len;
2887
2888 /*
2889 * Parse header (code, id and length). If packet too short,
2890 * drop it.
2891 */
2892 if (inlen < EAP_HEADERLEN) {
2893 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2894 return;
2895 }
2896 GETCHAR(code, inp);
2897 GETCHAR(id, inp);
2898 GETSHORT(len, inp);
2899 if (len < EAP_HEADERLEN || len > inlen) {
2900 error("EAP: packet has illegal length field %d (%d..%d)", len,
2901 EAP_HEADERLEN, inlen);
2902 return;
2903 }
2904 len -= EAP_HEADERLEN;
2905
2906 /* Dispatch based on message code */
2907 switch (code) {
2908 case EAP_REQUEST:
2909 eap_request(esp, inp, id, len);
2910 break;
2911
2912 case EAP_RESPONSE:
2913 eap_response(esp, inp, id, len);
2914 break;
2915
2916 case EAP_SUCCESS:
2917 eap_success(esp, inp, id, len);
2918 break;
2919
2920 case EAP_FAILURE:
2921 eap_failure(esp, inp, id, len);
2922 break;
2923
2924 default: /* XXX Need code reject */
2925 /* Note: it's not legal to send EAP Nak here. */
2926 warn("EAP: unknown code %d received", code);
2927 break;
2928 }
2929 }
2930
2931 /*
2932 * eap_printpkt - print the contents of an EAP packet.
2933 */
2934 static char *eap_codenames[] = {
2935 "Request", "Response", "Success", "Failure"
2936 };
2937
2938 static char *eap_typenames[] = {
2939 "Identity", "Notification", "Nak", "MD5-Challenge",
2940 "OTP", "Generic-Token", NULL, NULL,
2941 "RSA", "DSS", "KEA", "KEA-Validate",
2942 "TLS", "Defender", "Windows 2000", "Arcot",
2943 "Cisco", "Nokia", "SRP", NULL,
2944 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2945 "MSCHAPv2"
2946 };
2947
2948 static int
2949 eap_printpkt(u_char *inp, int inlen,
2950 void (*printer) (void *, char *, ...), void *arg)
2951 {
2952 int code, id, len, rtype, vallen;
2953 u_char *pstart;
2954 u_int32_t uval;
2955 #ifdef USE_EAPTLS
2956 u_char flags;
2957 #endif /* USE_EAPTLS */
2958 #ifdef CHAPMS
2959 u_char opcode;
2960 #endif /* CHAPMS */
2961
2962 if (inlen < EAP_HEADERLEN)
2963 return (0);
2964 pstart = inp;
2965 GETCHAR(code, inp);
2966 GETCHAR(id, inp);
2967 GETSHORT(len, inp);
2968 if (len < EAP_HEADERLEN || len > inlen)
2969 return (0);
2970
2971 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
2972 printer(arg, " %s", eap_codenames[code-1]);
2973 else
2974 printer(arg, " code=0x%x", code);
2975 printer(arg, " id=0x%x", id);
2976 len -= EAP_HEADERLEN;
2977 switch (code) {
2978 case EAP_REQUEST:
2979 if (len < 1) {
2980 printer(arg, " <missing type>");
2981 break;
2982 }
2983 GETCHAR(rtype, inp);
2984 len--;
2985 if (rtype >= 1 &&
2986 rtype <= sizeof (eap_typenames) / sizeof (char *))
2987 printer(arg, " %s", eap_typenames[rtype-1]);
2988 else
2989 printer(arg, " type=0x%x", rtype);
2990 switch (rtype) {
2991 case EAPT_IDENTITY:
2992 case EAPT_NOTIFICATION:
2993 if (len > 0) {
2994 printer(arg, " <Message ");
2995 print_string((char *)inp, len, printer, arg);
2996 printer(arg, ">");
2997 INCPTR(len, inp);
2998 len = 0;
2999 } else {
3000 printer(arg, " <No message>");
3001 }
3002 break;
3003
3004 case EAPT_MD5CHAP:
3005 if (len <= 0)
3006 break;
3007 GETCHAR(vallen, inp);
3008 len--;
3009 if (vallen > len)
3010 goto truncated;
3011 printer(arg, " <Value%.*B>", vallen, inp);
3012 INCPTR(vallen, inp);
3013 len -= vallen;
3014 if (len > 0) {
3015 printer(arg, " <Name ");
3016 print_string((char *)inp, len, printer, arg);
3017 printer(arg, ">");
3018 INCPTR(len, inp);
3019 len = 0;
3020 } else {
3021 printer(arg, " <No name>");
3022 }
3023 break;
3024
3025 #ifdef CHAPMS
3026 case EAPT_MSCHAPV2:
3027 if (len <= 0)
3028 break;
3029 GETCHAR(opcode, inp);
3030 len--;
3031 switch (opcode) {
3032 case CHAP_CHALLENGE:
3033 INCPTR(3, inp);
3034 len -= 3;
3035 GETCHAR(vallen, inp);
3036 len--;
3037 if (vallen > len)
3038 goto truncated;
3039 len -= vallen;
3040 printer(arg, " Challenge <");
3041 for (; vallen > 0; --vallen) {
3042 u_char val;
3043 GETCHAR(val, inp);
3044 printer(arg, "%.2x", val);
3045 }
3046 printer(arg, ">");
3047 if (len > 0) {
3048 printer(arg, ", <Name ");
3049 print_string((char *)inp, len, printer, arg);
3050 printer(arg, ">");
3051 INCPTR(len, inp);
3052 len = 0;
3053 } else {
3054 printer(arg, ", <No name>");
3055 }
3056 break;
3057 case CHAP_SUCCESS:
3058 INCPTR(3, inp);
3059 len -= 3;
3060 printer(arg, " Success <Message ");
3061 print_string((char *)inp, len, printer, arg);
3062 printer(arg, ">");
3063 break;
3064 case CHAP_FAILURE:
3065 INCPTR(3, inp);
3066 len -= 3;
3067 printer(arg, " Failure <Message ");
3068 print_string((char *)inp, len, printer, arg);
3069 printer(arg, ">");
3070 break;
3071 default:
3072 INCPTR(3, inp);
3073 len -= 3;
3074 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3075 break;
3076 }
3077 break;
3078 #endif /* CHAPMS */
3079
3080 #ifdef USE_EAPTLS
3081 case EAPT_TLS:
3082 if (len < 1)
3083 break;
3084 GETCHAR(flags, inp);
3085 len--;
3086
3087 if(flags == 0 && len == 0){
3088 printer(arg, " Ack");
3089 break;
3090 }
3091
3092 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3093 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3094 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3095 break;
3096 #endif /* USE_EAPTLS */
3097
3098 case EAPT_SRP:
3099 if (len < 3)
3100 goto truncated;
3101 GETCHAR(vallen, inp);
3102 len--;
3103 printer(arg, "-%d", vallen);
3104 switch (vallen) {
3105 case EAPSRP_CHALLENGE:
3106 GETCHAR(vallen, inp);
3107 len--;
3108 if (vallen >= len)
3109 goto truncated;
3110 if (vallen > 0) {
3111 printer(arg, " <Name ");
3112 print_string((char *)inp, vallen, printer,
3113 arg);
3114 printer(arg, ">");
3115 } else {
3116 printer(arg, " <No name>");
3117 }
3118 INCPTR(vallen, inp);
3119 len -= vallen;
3120 GETCHAR(vallen, inp);
3121 len--;
3122 if (vallen >= len)
3123 goto truncated;
3124 printer(arg, " <s%.*B>", vallen, inp);
3125 INCPTR(vallen, inp);
3126 len -= vallen;
3127 GETCHAR(vallen, inp);
3128 len--;
3129 if (vallen > len)
3130 goto truncated;
3131 if (vallen == 0) {
3132 printer(arg, " <Default g=2>");
3133 } else {
3134 printer(arg, " <g%.*B>", vallen, inp);
3135 }
3136 INCPTR(vallen, inp);
3137 len -= vallen;
3138 if (len == 0) {
3139 printer(arg, " <Default N>");
3140 } else {
3141 printer(arg, " <N%.*B>", len, inp);
3142 INCPTR(len, inp);
3143 len = 0;
3144 }
3145 break;
3146
3147 case EAPSRP_SKEY:
3148 printer(arg, " <B%.*B>", len, inp);
3149 INCPTR(len, inp);
3150 len = 0;
3151 break;
3152
3153 case EAPSRP_SVALIDATOR:
3154 if (len < sizeof (u_int32_t))
3155 break;
3156 GETLONG(uval, inp);
3157 len -= sizeof (u_int32_t);
3158 if (uval & SRPVAL_EBIT) {
3159 printer(arg, " E");
3160 uval &= ~SRPVAL_EBIT;
3161 }
3162 if (uval != 0) {
3163 printer(arg, " f<%X>", uval);
3164 }
3165 if ((vallen = len) > SHA_DIGESTSIZE)
3166 vallen = SHA_DIGESTSIZE;
3167 printer(arg, " <M2%.*B%s>", len, inp,
3168 len < SHA_DIGESTSIZE ? "?" : "");
3169 INCPTR(vallen, inp);
3170 len -= vallen;
3171 if (len > 0) {
3172 printer(arg, " <PN%.*B>", len, inp);
3173 INCPTR(len, inp);
3174 len = 0;
3175 }
3176 break;
3177
3178 case EAPSRP_LWRECHALLENGE:
3179 printer(arg, " <Challenge%.*B>", len, inp);
3180 INCPTR(len, inp);
3181 len = 0;
3182 break;
3183 }
3184 break;
3185 }
3186 break;
3187
3188 case EAP_RESPONSE:
3189 if (len < 1)
3190 break;
3191 GETCHAR(rtype, inp);
3192 len--;
3193 if (rtype >= 1 &&
3194 rtype <= sizeof (eap_typenames) / sizeof (char *))
3195 printer(arg, " %s", eap_typenames[rtype-1]);
3196 else
3197 printer(arg, " type=0x%x", rtype);
3198 switch (rtype) {
3199 case EAPT_IDENTITY:
3200 if (len > 0) {
3201 printer(arg, " <Name ");
3202 print_string((char *)inp, len, printer, arg);
3203 printer(arg, ">");
3204 INCPTR(len, inp);
3205 len = 0;
3206 }
3207 break;
3208
3209 #ifdef USE_EAPTLS
3210 case EAPT_TLS:
3211 if (len < 1)
3212 break;
3213 GETCHAR(flags, inp);
3214 len--;
3215
3216 if(flags == 0 && len == 0){
3217 printer(arg, " Ack");
3218 break;
3219 }
3220
3221 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3222 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3223 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3224
3225 break;
3226 #endif /* USE_EAPTLS */
3227
3228 case EAPT_NAK:
3229 if (len <= 0) {
3230 printer(arg, " <missing hint>");
3231 break;
3232 }
3233 GETCHAR(rtype, inp);
3234 len--;
3235 printer(arg, " <Suggested-type %02X", rtype);
3236 if (rtype >= 1 &&
3237 rtype <= sizeof (eap_typenames) / sizeof (char *))
3238 printer(arg, " (%s)", eap_typenames[rtype-1]);
3239 printer(arg, ">");
3240 break;
3241
3242 case EAPT_MD5CHAP:
3243 if (len <= 0) {
3244 printer(arg, " <missing length>");
3245 break;
3246 }
3247 GETCHAR(vallen, inp);
3248 len--;
3249 if (vallen > len)
3250 goto truncated;
3251 printer(arg, " <Value%.*B>", vallen, inp);
3252 INCPTR(vallen, inp);
3253 len -= vallen;
3254 if (len > 0) {
3255 printer(arg, " <Name ");
3256 print_string((char *)inp, len, printer, arg);
3257 printer(arg, ">");
3258 INCPTR(len, inp);
3259 len = 0;
3260 } else {
3261 printer(arg, " <No name>");
3262 }
3263 break;
3264
3265 #ifdef CHAPMS
3266 case EAPT_MSCHAPV2:
3267 if (len <= 0)
3268 break;
3269 GETCHAR(opcode, inp);
3270 len--;
3271 switch (opcode) {
3272 case CHAP_RESPONSE:
3273 INCPTR(3, inp);
3274 len -= 3;
3275 GETCHAR(vallen, inp);
3276 len--;
3277 if (vallen > len)
3278 goto truncated;
3279 len -= vallen;
3280 printer(arg, " Response <");
3281 for (; vallen > 0; --vallen) {
3282 u_char val;
3283 GETCHAR(val, inp);
3284 printer(arg, "%.2x", val);
3285 }
3286 printer(arg, ">");
3287 if (len > 0) {
3288 printer(arg, ", <Name ");
3289 print_string((char *)inp, len, printer, arg);
3290 printer(arg, ">");
3291 INCPTR(len, inp);
3292 len = 0;
3293 } else {
3294 printer(arg, ", <No name>");
3295 }
3296 break;
3297 case CHAP_SUCCESS:
3298 printer(arg, " Success");
3299 break;
3300 case CHAP_FAILURE:
3301 printer(arg, " Failure");
3302 break;
3303 default:
3304 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3305 break;
3306 }
3307 break;
3308 #endif /* CHAPMS */
3309
3310 case EAPT_SRP:
3311 if (len < 1)
3312 goto truncated;
3313 GETCHAR(vallen, inp);
3314 len--;
3315 printer(arg, "-%d", vallen);
3316 switch (vallen) {
3317 case EAPSRP_CKEY:
3318 printer(arg, " <A%.*B>", len, inp);
3319 INCPTR(len, inp);
3320 len = 0;
3321 break;
3322
3323 case EAPSRP_CVALIDATOR:
3324 if (len < sizeof (u_int32_t))
3325 break;
3326 GETLONG(uval, inp);
3327 len -= sizeof (u_int32_t);
3328 if (uval & SRPVAL_EBIT) {
3329 printer(arg, " E");
3330 uval &= ~SRPVAL_EBIT;
3331 }
3332 if (uval != 0) {
3333 printer(arg, " f<%X>", uval);
3334 }
3335 printer(arg, " <M1%.*B%s>", len, inp,
3336 len == SHA_DIGESTSIZE ? "" : "?");
3337 INCPTR(len, inp);
3338 len = 0;
3339 break;
3340
3341 case EAPSRP_ACK:
3342 break;
3343
3344 case EAPSRP_LWRECHALLENGE:
3345 printer(arg, " <Response%.*B%s>", len, inp,
3346 len == SHA_DIGESTSIZE ? "" : "?");
3347 if ((vallen = len) > SHA_DIGESTSIZE)
3348 vallen = SHA_DIGESTSIZE;
3349 INCPTR(vallen, inp);
3350 len -= vallen;
3351 break;
3352 }
3353 break;
3354 }
3355 break;
3356
3357 case EAP_SUCCESS: /* No payload expected for these! */
3358 case EAP_FAILURE:
3359 break;
3360
3361 truncated:
3362 printer(arg, " <truncated>");
3363 break;
3364 }
3365
3366 if (len > 8)
3367 printer(arg, "%8B...", inp);
3368 else if (len > 0)
3369 printer(arg, "%.*B", len, inp);
3370 INCPTR(len, inp);
3371
3372 return (inp - pstart);
3373 }
3374