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