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