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