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#define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" 47 48/* 49 * TODO: 50 */ 51 52#include <stdio.h> 53#include <stdlib.h> 54#include <string.h> 55#include <unistd.h> 56#include <pwd.h> 57#include <sys/types.h> 58#include <sys/stat.h> 59#include <fcntl.h> 60#include <assert.h> 61#include <errno.h> 62 63#include "pppd.h" 64#include "pathnames.h" 65#include "md5.h" 66#include "eap.h" 67 68#ifdef USE_SRP 69#include <t_pwd.h> 70#include <t_server.h> 71#include <t_client.h> 72#include "pppcrypt.h" 73#endif /* USE_SRP */ 74 75#ifndef SHA_DIGESTSIZE 76#define SHA_DIGESTSIZE 20 77#endif 78 79static const char rcsid[] = RCSID; 80 81eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */ 82#ifdef USE_SRP 83static char *pn_secret = NULL; /* Pseudonym generating secret */ 84#endif 85 86/* 87 * Command-line options. 88 */ 89static option_t eap_option_list[] = { 90 { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout, 91 "Set retransmit timeout for EAP Requests (server)" }, 92 { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests, 93 "Set max number of EAP Requests sent (server)" }, 94 { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout, 95 "Set time limit for peer EAP authentication" }, 96 { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests, 97 "Set max number of EAP Requests allows (client)" }, 98 { "eap-interval", o_int, &eap_states[0].es_rechallenge, 99 "Set interval for EAP rechallenge" }, 100#ifdef USE_SRP 101 { "srp-interval", o_int, &eap_states[0].es_lwrechallenge, 102 "Set interval for SRP lightweight rechallenge" }, 103 { "srp-pn-secret", o_string, &pn_secret, 104 "Long term pseudonym generation secret" }, 105 { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo, 106 "Use pseudonym if offered one by server", 1 }, 107#endif 108 { NULL } 109}; 110 111/* 112 * Protocol entry points. 113 */ 114static void eap_init __P((int unit)); 115static void eap_input __P((int unit, u_char *inp, int inlen)); 116static void eap_protrej __P((int unit)); 117static void eap_lowerup __P((int unit)); 118static void eap_lowerdown __P((int unit)); 119static int eap_printpkt __P((u_char *inp, int inlen, 120 void (*)(void *arg, char *fmt, ...), void *arg)); 121 122struct protent eap_protent = { 123 PPP_EAP, /* protocol number */ 124 eap_init, /* initialization procedure */ 125 eap_input, /* process a received packet */ 126 eap_protrej, /* process a received protocol-reject */ 127 eap_lowerup, /* lower layer has gone up */ 128 eap_lowerdown, /* lower layer has gone down */ 129 NULL, /* open the protocol */ 130 NULL, /* close the protocol */ 131 eap_printpkt, /* print a packet in readable form */ 132 NULL, /* process a received data packet */ 133 1, /* protocol enabled */ 134 "EAP", /* text name of protocol */ 135 NULL, /* text name of corresponding data protocol */ 136 eap_option_list, /* list of command-line options */ 137 NULL, /* check requested options; assign defaults */ 138 NULL, /* configure interface for demand-dial */ 139 NULL /* say whether to bring up link for this pkt */ 140}; 141 142/* 143 * A well-known 2048 bit modulus. 144 */ 145static const u_char wkmodulus[] = { 146 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 147 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, 148 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 149 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50, 150 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED, 151 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D, 152 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D, 153 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50, 154 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0, 155 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, 156 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 157 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, 158 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA, 159 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74, 160 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7, 161 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B, 162 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16, 163 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81, 164 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 165 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, 166 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 167 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA, 168 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78, 169 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6, 170 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29, 171 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8, 172 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82, 173 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, 174 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 175 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, 176 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 177 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73 178}; 179 180/* Local forward declarations. */ 181static void eap_server_timeout __P((void *arg)); 182 183/* 184 * Convert EAP state code to printable string for debug. 185 */ 186static const char * 187eap_state_name(esc) 188enum eap_state_code esc; 189{ 190 static const char *state_names[] = { EAP_STATES }; 191 192 return (state_names[(int)esc]); 193} 194 195/* 196 * eap_init - Initialize state for an EAP user. This is currently 197 * called once by main() during start-up. 198 */ 199static void 200eap_init(unit) 201int unit; 202{ 203 eap_state *esp = &eap_states[unit]; 204 205 BZERO(esp, sizeof (*esp)); 206 esp->es_unit = unit; 207 esp->es_server.ea_timeout = EAP_DEFTIMEOUT; 208 esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS; 209 esp->es_server.ea_id = (u_char)(drand48() * 0x100); 210 esp->es_client.ea_timeout = EAP_DEFREQTIME; 211 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ; 212} 213 214/* 215 * eap_client_timeout - Give up waiting for the peer to send any 216 * Request messages. 217 */ 218static void 219eap_client_timeout(arg) 220void *arg; 221{ 222 eap_state *esp = (eap_state *) arg; 223 224 if (!eap_client_active(esp)) 225 return; 226 227 error("EAP: timeout waiting for Request from peer"); 228 auth_withpeer_fail(esp->es_unit, PPP_EAP); 229 esp->es_client.ea_state = eapBadAuth; 230} 231 232/* 233 * eap_authwithpeer - Authenticate to our peer (behave as client). 234 * 235 * Start client state and wait for requests. This is called only 236 * after eap_lowerup. 237 */ 238void 239eap_authwithpeer(unit, localname) 240int unit; 241char *localname; 242{ 243 eap_state *esp = &eap_states[unit]; 244 245 /* Save the peer name we're given */ 246 esp->es_client.ea_name = localname; 247 esp->es_client.ea_namelen = strlen(localname); 248 249 esp->es_client.ea_state = eapListen; 250 251 /* 252 * Start a timer so that if the other end just goes 253 * silent, we don't sit here waiting forever. 254 */ 255 if (esp->es_client.ea_timeout > 0) 256 TIMEOUT(eap_client_timeout, (void *)esp, 257 esp->es_client.ea_timeout); 258} 259 260/* 261 * Format a standard EAP Failure message and send it to the peer. 262 * (Server operation) 263 */ 264static void 265eap_send_failure(esp) 266eap_state *esp; 267{ 268 u_char *outp; 269 270 outp = outpacket_buf; 271 272 MAKEHEADER(outp, PPP_EAP); 273 274 PUTCHAR(EAP_FAILURE, outp); 275 esp->es_server.ea_id++; 276 PUTCHAR(esp->es_server.ea_id, outp); 277 PUTSHORT(EAP_HEADERLEN, outp); 278 279 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); 280 281 esp->es_server.ea_state = eapBadAuth; 282 auth_peer_fail(esp->es_unit, PPP_EAP); 283} 284 285/* 286 * Format a standard EAP Success message and send it to the peer. 287 * (Server operation) 288 */ 289static void 290eap_send_success(esp) 291eap_state *esp; 292{ 293 u_char *outp; 294 295 outp = outpacket_buf; 296 297 MAKEHEADER(outp, PPP_EAP); 298 299 PUTCHAR(EAP_SUCCESS, outp); 300 esp->es_server.ea_id++; 301 PUTCHAR(esp->es_server.ea_id, outp); 302 PUTSHORT(EAP_HEADERLEN, outp); 303 304 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); 305 306 auth_peer_success(esp->es_unit, PPP_EAP, 0, 307 esp->es_server.ea_peer, esp->es_server.ea_peerlen); 308} 309 310#ifdef USE_SRP 311/* 312 * Set DES key according to pseudonym-generating secret and current 313 * date. 314 */ 315static bool 316pncrypt_setkey(int timeoffs) 317{ 318 struct tm *tp; 319 char tbuf[9]; 320 SHA1_CTX ctxt; 321 u_char dig[SHA_DIGESTSIZE]; 322 time_t reftime; 323 324 if (pn_secret == NULL) 325 return (0); 326 reftime = time(NULL) + timeoffs; 327 tp = localtime(&reftime); 328 SHA1Init(&ctxt); 329 SHA1Update(&ctxt, pn_secret, strlen(pn_secret)); 330 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp); 331 SHA1Update(&ctxt, tbuf, strlen(tbuf)); 332 SHA1Final(dig, &ctxt); 333 return (DesSetkey(dig)); 334} 335 336static char base64[] = 337"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 338 339struct b64state { 340 u_int32_t bs_bits; 341 int bs_offs; 342}; 343 344static int 345b64enc(bs, inp, inlen, outp) 346struct b64state *bs; 347u_char *inp; 348int inlen; 349u_char *outp; 350{ 351 int outlen = 0; 352 353 while (inlen > 0) { 354 bs->bs_bits = (bs->bs_bits << 8) | *inp++; 355 inlen--; 356 bs->bs_offs += 8; 357 if (bs->bs_offs >= 24) { 358 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F]; 359 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F]; 360 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F]; 361 *outp++ = base64[bs->bs_bits & 0x3F]; 362 outlen += 4; 363 bs->bs_offs = 0; 364 bs->bs_bits = 0; 365 } 366 } 367 return (outlen); 368} 369 370static int 371b64flush(bs, outp) 372struct b64state *bs; 373u_char *outp; 374{ 375 int outlen = 0; 376 377 if (bs->bs_offs == 8) { 378 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F]; 379 *outp++ = base64[(bs->bs_bits << 4) & 0x3F]; 380 outlen = 2; 381 } else if (bs->bs_offs == 16) { 382 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F]; 383 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F]; 384 *outp++ = base64[(bs->bs_bits << 2) & 0x3F]; 385 outlen = 3; 386 } 387 bs->bs_offs = 0; 388 bs->bs_bits = 0; 389 return (outlen); 390} 391 392static int 393b64dec(bs, inp, inlen, outp) 394struct b64state *bs; 395u_char *inp; 396int inlen; 397u_char *outp; 398{ 399 int outlen = 0; 400 char *cp; 401 402 while (inlen > 0) { 403 if ((cp = strchr(base64, *inp++)) == NULL) 404 break; 405 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64); 406 inlen--; 407 bs->bs_offs += 6; 408 if (bs->bs_offs >= 8) { 409 *outp++ = bs->bs_bits >> (bs->bs_offs - 8); 410 outlen++; 411 bs->bs_offs -= 8; 412 } 413 } 414 return (outlen); 415} 416#endif /* USE_SRP */ 417 418/* 419 * Assume that current waiting server state is complete and figure 420 * next state to use based on available authentication data. 'status' 421 * indicates if there was an error in handling the last query. It is 422 * 0 for success and non-zero for failure. 423 */ 424static void 425eap_figure_next_state(esp, status) 426eap_state *esp; 427int status; 428{ 429#ifdef USE_SRP 430 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp; 431 struct t_pw tpw; 432 struct t_confent *tce, mytce; 433 char *cp, *cp2; 434 struct t_server *ts; 435 int id, i, plen, toffs; 436 u_char vals[2]; 437 struct b64state bs; 438#endif /* USE_SRP */ 439 440 esp->es_server.ea_timeout = esp->es_savedtime; 441 switch (esp->es_server.ea_state) { 442 case eapBadAuth: 443 return; 444 445 case eapIdentify: 446#ifdef USE_SRP 447 /* Discard any previous session. */ 448 ts = (struct t_server *)esp->es_server.ea_session; 449 if (ts != NULL) { 450 t_serverclose(ts); 451 esp->es_server.ea_session = NULL; 452 esp->es_server.ea_skey = NULL; 453 } 454#endif /* USE_SRP */ 455 if (status != 0) { 456 esp->es_server.ea_state = eapBadAuth; 457 break; 458 } 459#ifdef USE_SRP 460 /* If we've got a pseudonym, try to decode to real name. */ 461 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN && 462 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID, 463 SRP_PSEUDO_LEN) == 0 && 464 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 < 465 sizeof (secbuf)) { 466 BZERO(&bs, sizeof (bs)); 467 plen = b64dec(&bs, 468 esp->es_server.ea_peer + SRP_PSEUDO_LEN, 469 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN, 470 secbuf); 471 toffs = 0; 472 for (i = 0; i < 5; i++) { 473 pncrypt_setkey(toffs); 474 toffs -= 86400; 475 if (!DesDecrypt(secbuf, clear)) { 476 dbglog("no DES here; cannot decode " 477 "pseudonym"); 478 return; 479 } 480 id = *(unsigned char *)clear; 481 if (id + 1 <= plen && id + 9 > plen) 482 break; 483 } 484 if (plen % 8 == 0 && i < 5) { 485 /* 486 * Note that this is always shorter than the 487 * original stored string, so there's no need 488 * to realloc. 489 */ 490 if ((i = plen = *(unsigned char *)clear) > 7) 491 i = 7; 492 esp->es_server.ea_peerlen = plen; 493 dp = (unsigned char *)esp->es_server.ea_peer; 494 BCOPY(clear + 1, dp, i); 495 plen -= i; 496 dp += i; 497 sp = secbuf + 8; 498 while (plen > 0) { 499 (void) DesDecrypt(sp, dp); 500 sp += 8; 501 dp += 8; 502 plen -= 8; 503 } 504 esp->es_server.ea_peer[ 505 esp->es_server.ea_peerlen] = '\0'; 506 dbglog("decoded pseudonym to \"%.*q\"", 507 esp->es_server.ea_peerlen, 508 esp->es_server.ea_peer); 509 } else { 510 dbglog("failed to decode real name"); 511 /* Stay in eapIdentfy state; requery */ 512 break; 513 } 514 } 515 /* Look up user in secrets database. */ 516 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer, 517 esp->es_server.ea_name, (char *)secbuf, 1) != 0) { 518 /* Set up default in case SRP entry is bad */ 519 esp->es_server.ea_state = eapMD5Chall; 520 /* Get t_confent based on index in srp-secrets */ 521 id = strtol((char *)secbuf, &cp, 10); 522 if (*cp++ != ':' || id < 0) 523 break; 524 if (id == 0) { 525 mytce.index = 0; 526 mytce.modulus.data = (u_char *)wkmodulus; 527 mytce.modulus.len = sizeof (wkmodulus); 528 mytce.generator.data = (u_char *)"\002"; 529 mytce.generator.len = 1; 530 tce = &mytce; 531 } else if ((tce = gettcid(id)) != NULL) { 532 /* 533 * Client will have to verify this modulus/ 534 * generator combination, and that will take 535 * a while. Lengthen the timeout here. 536 */ 537 if (esp->es_server.ea_timeout > 0 && 538 esp->es_server.ea_timeout < 30) 539 esp->es_server.ea_timeout = 30; 540 } else { 541 break; 542 } 543 if ((cp2 = strchr(cp, ':')) == NULL) 544 break; 545 *cp2++ = '\0'; 546 tpw.pebuf.name = esp->es_server.ea_peer; 547 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf, 548 cp); 549 tpw.pebuf.password.data = tpw.pwbuf; 550 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf, 551 cp2); 552 tpw.pebuf.salt.data = tpw.saltbuf; 553 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL) 554 break; 555 esp->es_server.ea_session = (void *)ts; 556 esp->es_server.ea_state = eapSRP1; 557 vals[0] = esp->es_server.ea_id + 1; 558 vals[1] = EAPT_SRP; 559 t_serveraddexdata(ts, vals, 2); 560 /* Generate B; must call before t_servergetkey() */ 561 t_servergenexp(ts); 562 break; 563 } 564#endif /* USE_SRP */ 565 esp->es_server.ea_state = eapMD5Chall; 566 break; 567 568 case eapSRP1: 569#ifdef USE_SRP 570 ts = (struct t_server *)esp->es_server.ea_session; 571 if (ts != NULL && status != 0) { 572 t_serverclose(ts); 573 esp->es_server.ea_session = NULL; 574 esp->es_server.ea_skey = NULL; 575 } 576#endif /* USE_SRP */ 577 if (status == 1) { 578 esp->es_server.ea_state = eapMD5Chall; 579 } else if (status != 0 || esp->es_server.ea_session == NULL) { 580 esp->es_server.ea_state = eapBadAuth; 581 } else { 582 esp->es_server.ea_state = eapSRP2; 583 } 584 break; 585 586 case eapSRP2: 587#ifdef USE_SRP 588 ts = (struct t_server *)esp->es_server.ea_session; 589 if (ts != NULL && status != 0) { 590 t_serverclose(ts); 591 esp->es_server.ea_session = NULL; 592 esp->es_server.ea_skey = NULL; 593 } 594#endif /* USE_SRP */ 595 if (status != 0 || esp->es_server.ea_session == NULL) { 596 esp->es_server.ea_state = eapBadAuth; 597 } else { 598 esp->es_server.ea_state = eapSRP3; 599 } 600 break; 601 602 case eapSRP3: 603 case eapSRP4: 604#ifdef USE_SRP 605 ts = (struct t_server *)esp->es_server.ea_session; 606 if (ts != NULL && status != 0) { 607 t_serverclose(ts); 608 esp->es_server.ea_session = NULL; 609 esp->es_server.ea_skey = NULL; 610 } 611#endif /* USE_SRP */ 612 if (status != 0 || esp->es_server.ea_session == NULL) { 613 esp->es_server.ea_state = eapBadAuth; 614 } else { 615 esp->es_server.ea_state = eapOpen; 616 } 617 break; 618 619 case eapMD5Chall: 620 if (status != 0) { 621 esp->es_server.ea_state = eapBadAuth; 622 } else { 623 esp->es_server.ea_state = eapOpen; 624 } 625 break; 626 627 default: 628 esp->es_server.ea_state = eapBadAuth; 629 break; 630 } 631 if (esp->es_server.ea_state == eapBadAuth) 632 eap_send_failure(esp); 633} 634 635/* 636 * Format an EAP Request message and send it to the peer. Message 637 * type depends on current state. (Server operation) 638 */ 639static void 640eap_send_request(esp) 641eap_state *esp; 642{ 643 u_char *outp; 644 u_char *lenloc; 645 u_char *ptr; 646 int outlen; 647 int challen; 648 char *str; 649#ifdef USE_SRP 650 struct t_server *ts; 651 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp; 652 int i, j; 653 struct b64state b64; 654 SHA1_CTX ctxt; 655#endif /* USE_SRP */ 656 657 /* Handle both initial auth and restart */ 658 if (esp->es_server.ea_state < eapIdentify && 659 esp->es_server.ea_state != eapInitial) { 660 esp->es_server.ea_state = eapIdentify; 661 if (explicit_remote) { 662 /* 663 * If we already know the peer's 664 * unauthenticated name, then there's no 665 * reason to ask. Go to next state instead. 666 */ 667 esp->es_server.ea_peer = remote_name; 668 esp->es_server.ea_peerlen = strlen(remote_name); 669 eap_figure_next_state(esp, 0); 670 } 671 } 672 673 if (esp->es_server.ea_maxrequests > 0 && 674 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) { 675 if (esp->es_server.ea_responses > 0) 676 error("EAP: too many Requests sent"); 677 else 678 error("EAP: no response to Requests"); 679 eap_send_failure(esp); 680 return; 681 } 682 683 outp = outpacket_buf; 684 685 MAKEHEADER(outp, PPP_EAP); 686 687 PUTCHAR(EAP_REQUEST, outp); 688 PUTCHAR(esp->es_server.ea_id, outp); 689 lenloc = outp; 690 INCPTR(2, outp); 691 692 switch (esp->es_server.ea_state) { 693 case eapIdentify: 694 PUTCHAR(EAPT_IDENTITY, outp); 695 str = "Name"; 696 challen = strlen(str); 697 BCOPY(str, outp, challen); 698 INCPTR(challen, outp); 699 break; 700 701 case eapMD5Chall: 702 PUTCHAR(EAPT_MD5CHAP, outp); 703 /* 704 * pick a random challenge length between 705 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH 706 */ 707 challen = (drand48() * 708 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) + 709 MIN_CHALLENGE_LENGTH; 710 PUTCHAR(challen, outp); 711 esp->es_challen = challen; 712 ptr = esp->es_challenge; 713 while (--challen >= 0) 714 *ptr++ = (u_char) (drand48() * 0x100); 715 BCOPY(esp->es_challenge, outp, esp->es_challen); 716 INCPTR(esp->es_challen, outp); 717 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen); 718 INCPTR(esp->es_server.ea_namelen, outp); 719 break; 720 721#ifdef USE_SRP 722 case eapSRP1: 723 PUTCHAR(EAPT_SRP, outp); 724 PUTCHAR(EAPSRP_CHALLENGE, outp); 725 726 PUTCHAR(esp->es_server.ea_namelen, outp); 727 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen); 728 INCPTR(esp->es_server.ea_namelen, outp); 729 730 ts = (struct t_server *)esp->es_server.ea_session; 731 assert(ts != NULL); 732 PUTCHAR(ts->s.len, outp); 733 BCOPY(ts->s.data, outp, ts->s.len); 734 INCPTR(ts->s.len, outp); 735 736 if (ts->g.len == 1 && ts->g.data[0] == 2) { 737 PUTCHAR(0, outp); 738 } else { 739 PUTCHAR(ts->g.len, outp); 740 BCOPY(ts->g.data, outp, ts->g.len); 741 INCPTR(ts->g.len, outp); 742 } 743 744 if (ts->n.len != sizeof (wkmodulus) || 745 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) { 746 BCOPY(ts->n.data, outp, ts->n.len); 747 INCPTR(ts->n.len, outp); 748 } 749 break; 750 751 case eapSRP2: 752 PUTCHAR(EAPT_SRP, outp); 753 PUTCHAR(EAPSRP_SKEY, outp); 754 755 ts = (struct t_server *)esp->es_server.ea_session; 756 assert(ts != NULL); 757 BCOPY(ts->B.data, outp, ts->B.len); 758 INCPTR(ts->B.len, outp); 759 break; 760 761 case eapSRP3: 762 PUTCHAR(EAPT_SRP, outp); 763 PUTCHAR(EAPSRP_SVALIDATOR, outp); 764 PUTLONG(SRPVAL_EBIT, outp); 765 ts = (struct t_server *)esp->es_server.ea_session; 766 assert(ts != NULL); 767 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE); 768 INCPTR(SHA_DIGESTSIZE, outp); 769 770 if (pncrypt_setkey(0)) { 771 /* Generate pseudonym */ 772 optr = outp; 773 cp = (unsigned char *)esp->es_server.ea_peer; 774 if ((j = i = esp->es_server.ea_peerlen) > 7) 775 j = 7; 776 clear[0] = i; 777 BCOPY(cp, clear + 1, j); 778 i -= j; 779 cp += j; 780 if (!DesEncrypt(clear, cipher)) { 781 dbglog("no DES here; not generating pseudonym"); 782 break; 783 } 784 BZERO(&b64, sizeof (b64)); 785 outp++; /* space for pseudonym length */ 786 outp += b64enc(&b64, cipher, 8, outp); 787 while (i >= 8) { 788 (void) DesEncrypt(cp, cipher); 789 outp += b64enc(&b64, cipher, 8, outp); 790 cp += 8; 791 i -= 8; 792 } 793 if (i > 0) { 794 BCOPY(cp, clear, i); 795 cp += i; 796 while (i < 8) { 797 *cp++ = drand48() * 0x100; 798 i++; 799 } 800 (void) DesEncrypt(clear, cipher); 801 outp += b64enc(&b64, cipher, 8, outp); 802 } 803 outp += b64flush(&b64, outp); 804 805 /* Set length and pad out to next 20 octet boundary */ 806 i = outp - optr - 1; 807 *optr = i; 808 i %= SHA_DIGESTSIZE; 809 if (i != 0) { 810 while (i < SHA_DIGESTSIZE) { 811 *outp++ = drand48() * 0x100; 812 i++; 813 } 814 } 815 816 /* Obscure the pseudonym with SHA1 hash */ 817 SHA1Init(&ctxt); 818 SHA1Update(&ctxt, &esp->es_server.ea_id, 1); 819 SHA1Update(&ctxt, esp->es_server.ea_skey, 820 SESSION_KEY_LEN); 821 SHA1Update(&ctxt, esp->es_server.ea_peer, 822 esp->es_server.ea_peerlen); 823 while (optr < outp) { 824 SHA1Final(dig, &ctxt); 825 cp = dig; 826 while (cp < dig + SHA_DIGESTSIZE) 827 *optr++ ^= *cp++; 828 SHA1Init(&ctxt); 829 SHA1Update(&ctxt, &esp->es_server.ea_id, 1); 830 SHA1Update(&ctxt, esp->es_server.ea_skey, 831 SESSION_KEY_LEN); 832 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE, 833 SHA_DIGESTSIZE); 834 } 835 } 836 break; 837 838 case eapSRP4: 839 PUTCHAR(EAPT_SRP, outp); 840 PUTCHAR(EAPSRP_LWRECHALLENGE, outp); 841 challen = MIN_CHALLENGE_LENGTH + 842 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48()); 843 esp->es_challen = challen; 844 ptr = esp->es_challenge; 845 while (--challen >= 0) 846 *ptr++ = drand48() * 0x100; 847 BCOPY(esp->es_challenge, outp, esp->es_challen); 848 INCPTR(esp->es_challen, outp); 849 break; 850#endif /* USE_SRP */ 851 852 default: 853 return; 854 } 855 856 outlen = (outp - outpacket_buf) - PPP_HDRLEN; 857 PUTSHORT(outlen, lenloc); 858 859 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); 860 861 esp->es_server.ea_requests++; 862 863 if (esp->es_server.ea_timeout > 0) 864 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout); 865} 866 867/* 868 * eap_authpeer - Authenticate our peer (behave as server). 869 * 870 * Start server state and send first request. This is called only 871 * after eap_lowerup. 872 */ 873void 874eap_authpeer(unit, localname) 875int unit; 876char *localname; 877{ 878 eap_state *esp = &eap_states[unit]; 879 880 /* Save the name we're given. */ 881 esp->es_server.ea_name = localname; 882 esp->es_server.ea_namelen = strlen(localname); 883 884 esp->es_savedtime = esp->es_server.ea_timeout; 885 886 /* Lower layer up yet? */ 887 if (esp->es_server.ea_state == eapInitial || 888 esp->es_server.ea_state == eapPending) { 889 esp->es_server.ea_state = eapPending; 890 return; 891 } 892 893 esp->es_server.ea_state = eapPending; 894 895 /* ID number not updated here intentionally; hashed into M1 */ 896 eap_send_request(esp); 897} 898 899/* 900 * eap_server_timeout - Retransmission timer for sending Requests 901 * expired. 902 */ 903static void 904eap_server_timeout(arg) 905void *arg; 906{ 907 eap_state *esp = (eap_state *) arg; 908 909 if (!eap_server_active(esp)) 910 return; 911 912 /* EAP ID number must not change on timeout. */ 913 eap_send_request(esp); 914} 915 916/* 917 * When it's time to send rechallenge the peer, this timeout is 918 * called. Once the rechallenge is successful, the response handler 919 * will restart the timer. If it fails, then the link is dropped. 920 */ 921static void 922eap_rechallenge(arg) 923void *arg; 924{ 925 eap_state *esp = (eap_state *)arg; 926 927 if (esp->es_server.ea_state != eapOpen && 928 esp->es_server.ea_state != eapSRP4) 929 return; 930 931 esp->es_server.ea_requests = 0; 932 esp->es_server.ea_state = eapIdentify; 933 eap_figure_next_state(esp, 0); 934 esp->es_server.ea_id++; 935 eap_send_request(esp); 936} 937 938static void 939srp_lwrechallenge(arg) 940void *arg; 941{ 942 eap_state *esp = (eap_state *)arg; 943 944 if (esp->es_server.ea_state != eapOpen || 945 esp->es_server.ea_type != EAPT_SRP) 946 return; 947 948 esp->es_server.ea_requests = 0; 949 esp->es_server.ea_state = eapSRP4; 950 esp->es_server.ea_id++; 951 eap_send_request(esp); 952} 953 954/* 955 * eap_lowerup - The lower layer is now up. 956 * 957 * This is called before either eap_authpeer or eap_authwithpeer. See 958 * link_established() in auth.c. All that's necessary here is to 959 * return to closed state so that those two routines will do the right 960 * thing. 961 */ 962static void 963eap_lowerup(unit) 964int unit; 965{ 966 eap_state *esp = &eap_states[unit]; 967 968 /* Discard any (possibly authenticated) peer name. */ 969 if (esp->es_server.ea_peer != NULL && 970 esp->es_server.ea_peer != remote_name) 971 free(esp->es_server.ea_peer); 972 esp->es_server.ea_peer = NULL; 973 if (esp->es_client.ea_peer != NULL) 974 free(esp->es_client.ea_peer); 975 esp->es_client.ea_peer = NULL; 976 977 esp->es_client.ea_state = eapClosed; 978 esp->es_server.ea_state = eapClosed; 979} 980 981/* 982 * eap_lowerdown - The lower layer is now down. 983 * 984 * Cancel all timeouts and return to initial state. 985 */ 986static void 987eap_lowerdown(unit) 988int unit; 989{ 990 eap_state *esp = &eap_states[unit]; 991 992 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) { 993 UNTIMEOUT(eap_client_timeout, (void *)esp); 994 } 995 if (eap_server_active(esp)) { 996 if (esp->es_server.ea_timeout > 0) { 997 UNTIMEOUT(eap_server_timeout, (void *)esp); 998 } 999 } else { 1000 if ((esp->es_server.ea_state == eapOpen || 1001 esp->es_server.ea_state == eapSRP4) && 1002 esp->es_rechallenge > 0) { 1003 UNTIMEOUT(eap_rechallenge, (void *)esp); 1004 } 1005 if (esp->es_server.ea_state == eapOpen && 1006 esp->es_lwrechallenge > 0) { 1007 UNTIMEOUT(srp_lwrechallenge, (void *)esp); 1008 } 1009 } 1010 1011 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial; 1012 esp->es_client.ea_requests = esp->es_server.ea_requests = 0; 1013} 1014 1015/* 1016 * eap_protrej - Peer doesn't speak this protocol. 1017 * 1018 * This shouldn't happen. If it does, it represents authentication 1019 * failure. 1020 */ 1021static void 1022eap_protrej(unit) 1023int unit; 1024{ 1025 eap_state *esp = &eap_states[unit]; 1026 1027 if (eap_client_active(esp)) { 1028 error("EAP authentication failed due to Protocol-Reject"); 1029 auth_withpeer_fail(unit, PPP_EAP); 1030 } 1031 if (eap_server_active(esp)) { 1032 error("EAP authentication of peer failed on Protocol-Reject"); 1033 auth_peer_fail(unit, PPP_EAP); 1034 } 1035 eap_lowerdown(unit); 1036} 1037 1038/* 1039 * Format and send a regular EAP Response message. 1040 */ 1041static void 1042eap_send_response(esp, id, typenum, str, lenstr) 1043eap_state *esp; 1044u_char id; 1045u_char typenum; 1046u_char *str; 1047int lenstr; 1048{ 1049 u_char *outp; 1050 int msglen; 1051 1052 outp = outpacket_buf; 1053 1054 MAKEHEADER(outp, PPP_EAP); 1055 1056 PUTCHAR(EAP_RESPONSE, outp); 1057 PUTCHAR(id, outp); 1058 esp->es_client.ea_id = id; 1059 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; 1060 PUTSHORT(msglen, outp); 1061 PUTCHAR(typenum, outp); 1062 if (lenstr > 0) { 1063 BCOPY(str, outp, lenstr); 1064 } 1065 1066 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); 1067} 1068 1069/* 1070 * Format and send an MD5-Challenge EAP Response message. 1071 */ 1072static void 1073eap_chap_response(esp, id, hash, name, namelen) 1074eap_state *esp; 1075u_char id; 1076u_char *hash; 1077char *name; 1078int namelen; 1079{ 1080 u_char *outp; 1081 int msglen; 1082 1083 outp = outpacket_buf; 1084 1085 MAKEHEADER(outp, PPP_EAP); 1086 1087 PUTCHAR(EAP_RESPONSE, outp); 1088 PUTCHAR(id, outp); 1089 esp->es_client.ea_id = id; 1090 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE + 1091 namelen; 1092 PUTSHORT(msglen, outp); 1093 PUTCHAR(EAPT_MD5CHAP, outp); 1094 PUTCHAR(MD5_SIGNATURE_SIZE, outp); 1095 BCOPY(hash, outp, MD5_SIGNATURE_SIZE); 1096 INCPTR(MD5_SIGNATURE_SIZE, outp); 1097 if (namelen > 0) { 1098 BCOPY(name, outp, namelen); 1099 } 1100 1101 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); 1102} 1103 1104#ifdef USE_SRP 1105/* 1106 * Format and send a SRP EAP Response message. 1107 */ 1108static void 1109eap_srp_response(esp, id, subtypenum, str, lenstr) 1110eap_state *esp; 1111u_char id; 1112u_char subtypenum; 1113u_char *str; 1114int lenstr; 1115{ 1116 u_char *outp; 1117 int msglen; 1118 1119 outp = outpacket_buf; 1120 1121 MAKEHEADER(outp, PPP_EAP); 1122 1123 PUTCHAR(EAP_RESPONSE, outp); 1124 PUTCHAR(id, outp); 1125 esp->es_client.ea_id = id; 1126 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; 1127 PUTSHORT(msglen, outp); 1128 PUTCHAR(EAPT_SRP, outp); 1129 PUTCHAR(subtypenum, outp); 1130 if (lenstr > 0) { 1131 BCOPY(str, outp, lenstr); 1132 } 1133 1134 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); 1135} 1136 1137/* 1138 * Format and send a SRP EAP Client Validator Response message. 1139 */ 1140static void 1141eap_srpval_response(esp, id, flags, str) 1142eap_state *esp; 1143u_char id; 1144u_int32_t flags; 1145u_char *str; 1146{ 1147 u_char *outp; 1148 int msglen; 1149 1150 outp = outpacket_buf; 1151 1152 MAKEHEADER(outp, PPP_EAP); 1153 1154 PUTCHAR(EAP_RESPONSE, outp); 1155 PUTCHAR(id, outp); 1156 esp->es_client.ea_id = id; 1157 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) + 1158 SHA_DIGESTSIZE; 1159 PUTSHORT(msglen, outp); 1160 PUTCHAR(EAPT_SRP, outp); 1161 PUTCHAR(EAPSRP_CVALIDATOR, outp); 1162 PUTLONG(flags, outp); 1163 BCOPY(str, outp, SHA_DIGESTSIZE); 1164 1165 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); 1166} 1167#endif /* USE_SRP */ 1168 1169static void 1170eap_send_nak(esp, id, type) 1171eap_state *esp; 1172u_char id; 1173u_char type; 1174{ 1175 u_char *outp; 1176 int msglen; 1177 1178 outp = outpacket_buf; 1179 1180 MAKEHEADER(outp, PPP_EAP); 1181 1182 PUTCHAR(EAP_RESPONSE, outp); 1183 PUTCHAR(id, outp); 1184 esp->es_client.ea_id = id; 1185 msglen = EAP_HEADERLEN + 2 * sizeof (u_char); 1186 PUTSHORT(msglen, outp); 1187 PUTCHAR(EAPT_NAK, outp); 1188 PUTCHAR(type, outp); 1189 1190 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); 1191} 1192 1193#ifdef USE_SRP 1194static char * 1195name_of_pn_file() 1196{ 1197 char *user, *path, *file; 1198 struct passwd *pw; 1199 size_t pl; 1200 static bool pnlogged = 0; 1201 1202 pw = getpwuid(getuid()); 1203 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) { 1204 errno = EINVAL; 1205 return (NULL); 1206 } 1207 file = _PATH_PSEUDONYM; 1208 pl = strlen(user) + strlen(file) + 2; 1209 path = malloc(pl); 1210 if (path == NULL) 1211 return (NULL); 1212 (void) slprintf(path, pl, "%s/%s", user, file); 1213 if (!pnlogged) { 1214 dbglog("pseudonym file: %s", path); 1215 pnlogged = 1; 1216 } 1217 return (path); 1218} 1219 1220static int 1221open_pn_file(modebits) 1222mode_t modebits; 1223{ 1224 char *path; 1225 int fd, err; 1226 1227 if ((path = name_of_pn_file()) == NULL) 1228 return (-1); 1229 fd = open(path, modebits, S_IRUSR | S_IWUSR); 1230 err = errno; 1231 free(path); 1232 errno = err; 1233 return (fd); 1234} 1235 1236static void 1237remove_pn_file() 1238{ 1239 char *path; 1240 1241 if ((path = name_of_pn_file()) != NULL) { 1242 (void) unlink(path); 1243 (void) free(path); 1244 } 1245} 1246 1247static void 1248write_pseudonym(esp, inp, len, id) 1249eap_state *esp; 1250u_char *inp; 1251int len, id; 1252{ 1253 u_char val; 1254 u_char *datp, *digp; 1255 SHA1_CTX ctxt; 1256 u_char dig[SHA_DIGESTSIZE]; 1257 int dsize, fd, olen = len; 1258 1259 /* 1260 * Do the decoding by working backwards. This eliminates the need 1261 * to save the decoded output in a separate buffer. 1262 */ 1263 val = id; 1264 while (len > 0) { 1265 if ((dsize = len % SHA_DIGESTSIZE) == 0) 1266 dsize = SHA_DIGESTSIZE; 1267 len -= dsize; 1268 datp = inp + len; 1269 SHA1Init(&ctxt); 1270 SHA1Update(&ctxt, &val, 1); 1271 SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN); 1272 if (len > 0) { 1273 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE); 1274 } else { 1275 SHA1Update(&ctxt, esp->es_client.ea_name, 1276 esp->es_client.ea_namelen); 1277 } 1278 SHA1Final(dig, &ctxt); 1279 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++) 1280 *datp++ ^= *digp; 1281 } 1282 1283 /* Now check that the result is sane */ 1284 if (olen <= 0 || *inp + 1 > olen) { 1285 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp); 1286 return; 1287 } 1288 1289 /* Save it away */ 1290 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC); 1291 if (fd < 0) { 1292 dbglog("EAP: error saving pseudonym: %m"); 1293 return; 1294 } 1295 len = write(fd, inp + 1, *inp); 1296 if (close(fd) != -1 && len == *inp) { 1297 dbglog("EAP: saved pseudonym"); 1298 esp->es_usedpseudo = 0; 1299 } else { 1300 dbglog("EAP: failed to save pseudonym"); 1301 remove_pn_file(); 1302 } 1303} 1304#endif /* USE_SRP */ 1305 1306/* 1307 * eap_request - Receive EAP Request message (client mode). 1308 */ 1309static void 1310eap_request(esp, inp, id, len) 1311eap_state *esp; 1312u_char *inp; 1313int id; 1314int len; 1315{ 1316 u_char typenum; 1317 u_char vallen; 1318 int secret_len; 1319 char secret[MAXWORDLEN]; 1320 char rhostname[256]; 1321 MD5_CTX mdContext; 1322 u_char hash[MD5_SIGNATURE_SIZE]; 1323#ifdef USE_SRP 1324 struct t_client *tc; 1325 struct t_num sval, gval, Nval, *Ap, Bval; 1326 u_char vals[2]; 1327 SHA1_CTX ctxt; 1328 u_char dig[SHA_DIGESTSIZE]; 1329 int fd; 1330#endif /* USE_SRP */ 1331 1332 /* 1333 * Note: we update es_client.ea_id *only if* a Response 1334 * message is being generated. Otherwise, we leave it the 1335 * same for duplicate detection purposes. 1336 */ 1337 1338 esp->es_client.ea_requests++; 1339 if (esp->es_client.ea_maxrequests != 0 && 1340 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) { 1341 info("EAP: received too many Request messages"); 1342 if (esp->es_client.ea_timeout > 0) { 1343 UNTIMEOUT(eap_client_timeout, (void *)esp); 1344 } 1345 auth_withpeer_fail(esp->es_unit, PPP_EAP); 1346 return; 1347 } 1348 1349 if (len <= 0) { 1350 error("EAP: empty Request message discarded"); 1351 return; 1352 } 1353 1354 GETCHAR(typenum, inp); 1355 len--; 1356 1357 switch (typenum) { 1358 case EAPT_IDENTITY: 1359 if (len > 0) 1360 info("EAP: Identity prompt \"%.*q\"", len, inp); 1361#ifdef USE_SRP 1362 if (esp->es_usepseudo && 1363 (esp->es_usedpseudo == 0 || 1364 (esp->es_usedpseudo == 1 && 1365 id == esp->es_client.ea_id))) { 1366 esp->es_usedpseudo = 1; 1367 /* Try to get a pseudonym */ 1368 if ((fd = open_pn_file(O_RDONLY)) >= 0) { 1369 strcpy(rhostname, SRP_PSEUDO_ID); 1370 len = read(fd, rhostname + SRP_PSEUDO_LEN, 1371 sizeof (rhostname) - SRP_PSEUDO_LEN); 1372 /* XXX NAI unsupported */ 1373 if (len > 0) { 1374 eap_send_response(esp, id, typenum, 1375 rhostname, len + SRP_PSEUDO_LEN); 1376 } 1377 (void) close(fd); 1378 if (len > 0) 1379 break; 1380 } 1381 } 1382 /* Stop using pseudonym now. */ 1383 if (esp->es_usepseudo && esp->es_usedpseudo != 2) { 1384 remove_pn_file(); 1385 esp->es_usedpseudo = 2; 1386 } 1387#endif /* USE_SRP */ 1388 eap_send_response(esp, id, typenum, esp->es_client.ea_name, 1389 esp->es_client.ea_namelen); 1390 break; 1391 1392 case EAPT_NOTIFICATION: 1393 if (len > 0) 1394 info("EAP: Notification \"%.*q\"", len, inp); 1395 eap_send_response(esp, id, typenum, NULL, 0); 1396 break; 1397 1398 case EAPT_NAK: 1399 /* 1400 * Avoid the temptation to send Response Nak in reply 1401 * to Request Nak here. It can only lead to trouble. 1402 */ 1403 warn("EAP: unexpected Nak in Request; ignored"); 1404 /* Return because we're waiting for something real. */ 1405 return; 1406 1407 case EAPT_MD5CHAP: 1408 if (len < 1) { 1409 error("EAP: received MD5-Challenge with no data"); 1410 /* Bogus request; wait for something real. */ 1411 return; 1412 } 1413 GETCHAR(vallen, inp); 1414 len--; 1415 if (vallen < 8 || vallen > len) { 1416 error("EAP: MD5-Challenge with bad length %d (8..%d)", 1417 vallen, len); 1418 /* Try something better. */ 1419 eap_send_nak(esp, id, EAPT_SRP); 1420 break; 1421 } 1422 1423 /* Not so likely to happen. */ 1424 if (vallen >= len + sizeof (rhostname)) { 1425 dbglog("EAP: trimming really long peer name down"); 1426 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); 1427 rhostname[sizeof (rhostname) - 1] = '\0'; 1428 } else { 1429 BCOPY(inp + vallen, rhostname, len - vallen); 1430 rhostname[len - vallen] = '\0'; 1431 } 1432 1433 /* In case the remote doesn't give us his name. */ 1434 if (explicit_remote || 1435 (remote_name[0] != '\0' && vallen == len)) 1436 strlcpy(rhostname, remote_name, sizeof (rhostname)); 1437 1438 /* 1439 * Get the secret for authenticating ourselves with 1440 * the specified host. 1441 */ 1442 if (!get_secret(esp->es_unit, esp->es_client.ea_name, 1443 rhostname, secret, &secret_len, 0)) { 1444 dbglog("EAP: no MD5 secret for auth to %q", rhostname); 1445 eap_send_nak(esp, id, EAPT_SRP); 1446 break; 1447 } 1448 MD5_Init(&mdContext); 1449 typenum = id; 1450 MD5_Update(&mdContext, &typenum, 1); 1451 MD5_Update(&mdContext, (u_char *)secret, secret_len); 1452 BZERO(secret, sizeof (secret)); 1453 MD5_Update(&mdContext, inp, vallen); 1454 MD5_Final(hash, &mdContext); 1455 eap_chap_response(esp, id, hash, esp->es_client.ea_name, 1456 esp->es_client.ea_namelen); 1457 break; 1458 1459#ifdef USE_SRP 1460 case EAPT_SRP: 1461 if (len < 1) { 1462 error("EAP: received empty SRP Request"); 1463 /* Bogus request; wait for something real. */ 1464 return; 1465 } 1466 1467 /* Get subtype */ 1468 GETCHAR(vallen, inp); 1469 len--; 1470 switch (vallen) { 1471 case EAPSRP_CHALLENGE: 1472 tc = NULL; 1473 if (esp->es_client.ea_session != NULL) { 1474 tc = (struct t_client *)esp->es_client. 1475 ea_session; 1476 /* 1477 * If this is a new challenge, then start 1478 * over with a new client session context. 1479 * Otherwise, just resend last response. 1480 */ 1481 if (id != esp->es_client.ea_id) { 1482 t_clientclose(tc); 1483 esp->es_client.ea_session = NULL; 1484 tc = NULL; 1485 } 1486 } 1487 /* No session key just yet */ 1488 esp->es_client.ea_skey = NULL; 1489 if (tc == NULL) { 1490 GETCHAR(vallen, inp); 1491 len--; 1492 if (vallen >= len) { 1493 error("EAP: badly-formed SRP Challenge" 1494 " (name)"); 1495 /* Ignore badly-formed messages */ 1496 return; 1497 } 1498 BCOPY(inp, rhostname, vallen); 1499 rhostname[vallen] = '\0'; 1500 INCPTR(vallen, inp); 1501 len -= vallen; 1502 1503 /* 1504 * In case the remote doesn't give us his name, 1505 * use configured name. 1506 */ 1507 if (explicit_remote || 1508 (remote_name[0] != '\0' && vallen == 0)) { 1509 strlcpy(rhostname, remote_name, 1510 sizeof (rhostname)); 1511 } 1512 1513 if (esp->es_client.ea_peer != NULL) 1514 free(esp->es_client.ea_peer); 1515 esp->es_client.ea_peer = strdup(rhostname); 1516 esp->es_client.ea_peerlen = strlen(rhostname); 1517 1518 GETCHAR(vallen, inp); 1519 len--; 1520 if (vallen >= len) { 1521 error("EAP: badly-formed SRP Challenge" 1522 " (s)"); 1523 /* Ignore badly-formed messages */ 1524 return; 1525 } 1526 sval.data = inp; 1527 sval.len = vallen; 1528 INCPTR(vallen, inp); 1529 len -= vallen; 1530 1531 GETCHAR(vallen, inp); 1532 len--; 1533 if (vallen > len) { 1534 error("EAP: badly-formed SRP Challenge" 1535 " (g)"); 1536 /* Ignore badly-formed messages */ 1537 return; 1538 } 1539 /* If no generator present, then use value 2 */ 1540 if (vallen == 0) { 1541 gval.data = (u_char *)"\002"; 1542 gval.len = 1; 1543 } else { 1544 gval.data = inp; 1545 gval.len = vallen; 1546 } 1547 INCPTR(vallen, inp); 1548 len -= vallen; 1549 1550 /* 1551 * If no modulus present, then use well-known 1552 * value. 1553 */ 1554 if (len == 0) { 1555 Nval.data = (u_char *)wkmodulus; 1556 Nval.len = sizeof (wkmodulus); 1557 } else { 1558 Nval.data = inp; 1559 Nval.len = len; 1560 } 1561 tc = t_clientopen(esp->es_client.ea_name, 1562 &Nval, &gval, &sval); 1563 if (tc == NULL) { 1564 eap_send_nak(esp, id, EAPT_MD5CHAP); 1565 break; 1566 } 1567 esp->es_client.ea_session = (void *)tc; 1568 1569 /* Add Challenge ID & type to verifier */ 1570 vals[0] = id; 1571 vals[1] = EAPT_SRP; 1572 t_clientaddexdata(tc, vals, 2); 1573 } 1574 Ap = t_clientgenexp(tc); 1575 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data, 1576 Ap->len); 1577 break; 1578 1579 case EAPSRP_SKEY: 1580 tc = (struct t_client *)esp->es_client.ea_session; 1581 if (tc == NULL) { 1582 warn("EAP: peer sent Subtype 2 without 1"); 1583 eap_send_nak(esp, id, EAPT_MD5CHAP); 1584 break; 1585 } 1586 if (esp->es_client.ea_skey != NULL) { 1587 /* 1588 * ID number should not change here. Warn 1589 * if it does (but otherwise ignore). 1590 */ 1591 if (id != esp->es_client.ea_id) { 1592 warn("EAP: ID changed from %d to %d " 1593 "in SRP Subtype 2 rexmit", 1594 esp->es_client.ea_id, id); 1595 } 1596 } else { 1597 if (get_srp_secret(esp->es_unit, 1598 esp->es_client.ea_name, 1599 esp->es_client.ea_peer, secret, 0) == 0) { 1600 /* 1601 * Can't work with this peer because 1602 * the secret is missing. Just give 1603 * up. 1604 */ 1605 eap_send_nak(esp, id, EAPT_MD5CHAP); 1606 break; 1607 } 1608 Bval.data = inp; 1609 Bval.len = len; 1610 t_clientpasswd(tc, secret); 1611 BZERO(secret, sizeof (secret)); 1612 esp->es_client.ea_skey = 1613 t_clientgetkey(tc, &Bval); 1614 if (esp->es_client.ea_skey == NULL) { 1615 /* Server is rogue; stop now */ 1616 error("EAP: SRP server is rogue"); 1617 goto client_failure; 1618 } 1619 } 1620 eap_srpval_response(esp, id, SRPVAL_EBIT, 1621 t_clientresponse(tc)); 1622 break; 1623 1624 case EAPSRP_SVALIDATOR: 1625 tc = (struct t_client *)esp->es_client.ea_session; 1626 if (tc == NULL || esp->es_client.ea_skey == NULL) { 1627 warn("EAP: peer sent Subtype 3 without 1/2"); 1628 eap_send_nak(esp, id, EAPT_MD5CHAP); 1629 break; 1630 } 1631 /* 1632 * If we're already open, then this ought to be a 1633 * duplicate. Otherwise, check that the server is 1634 * who we think it is. 1635 */ 1636 if (esp->es_client.ea_state == eapOpen) { 1637 if (id != esp->es_client.ea_id) { 1638 warn("EAP: ID changed from %d to %d " 1639 "in SRP Subtype 3 rexmit", 1640 esp->es_client.ea_id, id); 1641 } 1642 } else { 1643 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE; 1644 if (len < 0 || t_clientverify(tc, inp + 1645 sizeof (u_int32_t)) != 0) { 1646 error("EAP: SRP server verification " 1647 "failed"); 1648 goto client_failure; 1649 } 1650 GETLONG(esp->es_client.ea_keyflags, inp); 1651 /* Save pseudonym if user wants it. */ 1652 if (len > 0 && esp->es_usepseudo) { 1653 INCPTR(SHA_DIGESTSIZE, inp); 1654 write_pseudonym(esp, inp, len, id); 1655 } 1656 } 1657 /* 1658 * We've verified our peer. We're now mostly done, 1659 * except for waiting on the regular EAP Success 1660 * message. 1661 */ 1662 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0); 1663 break; 1664 1665 case EAPSRP_LWRECHALLENGE: 1666 if (len < 4) { 1667 warn("EAP: malformed Lightweight rechallenge"); 1668 return; 1669 } 1670 SHA1Init(&ctxt); 1671 vals[0] = id; 1672 SHA1Update(&ctxt, vals, 1); 1673 SHA1Update(&ctxt, esp->es_client.ea_skey, 1674 SESSION_KEY_LEN); 1675 SHA1Update(&ctxt, inp, len); 1676 SHA1Update(&ctxt, esp->es_client.ea_name, 1677 esp->es_client.ea_namelen); 1678 SHA1Final(dig, &ctxt); 1679 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig, 1680 SHA_DIGESTSIZE); 1681 break; 1682 1683 default: 1684 error("EAP: unknown SRP Subtype %d", vallen); 1685 eap_send_nak(esp, id, EAPT_MD5CHAP); 1686 break; 1687 } 1688 break; 1689#endif /* USE_SRP */ 1690 1691 default: 1692 info("EAP: unknown authentication type %d; Naking", typenum); 1693 eap_send_nak(esp, id, EAPT_SRP); 1694 break; 1695 } 1696 1697 if (esp->es_client.ea_timeout > 0) { 1698 UNTIMEOUT(eap_client_timeout, (void *)esp); 1699 TIMEOUT(eap_client_timeout, (void *)esp, 1700 esp->es_client.ea_timeout); 1701 } 1702 return; 1703 1704#ifdef USE_SRP 1705client_failure: 1706 esp->es_client.ea_state = eapBadAuth; 1707 if (esp->es_client.ea_timeout > 0) { 1708 UNTIMEOUT(eap_client_timeout, (void *)esp); 1709 } 1710 esp->es_client.ea_session = NULL; 1711 t_clientclose(tc); 1712 auth_withpeer_fail(esp->es_unit, PPP_EAP); 1713#endif /* USE_SRP */ 1714} 1715 1716/* 1717 * eap_response - Receive EAP Response message (server mode). 1718 */ 1719static void 1720eap_response(esp, inp, id, len) 1721eap_state *esp; 1722u_char *inp; 1723int id; 1724int len; 1725{ 1726 u_char typenum; 1727 u_char vallen; 1728 int secret_len; 1729 char secret[MAXSECRETLEN]; 1730 char rhostname[256]; 1731 MD5_CTX mdContext; 1732 u_char hash[MD5_SIGNATURE_SIZE]; 1733#ifdef USE_SRP 1734 struct t_server *ts; 1735 struct t_num A; 1736 SHA1_CTX ctxt; 1737 u_char dig[SHA_DIGESTSIZE]; 1738#endif /* USE_SRP */ 1739 1740 if (esp->es_server.ea_id != id) { 1741 dbglog("EAP: discarding Response %d; expected ID %d", id, 1742 esp->es_server.ea_id); 1743 return; 1744 } 1745 1746 esp->es_server.ea_responses++; 1747 1748 if (len <= 0) { 1749 error("EAP: empty Response message discarded"); 1750 return; 1751 } 1752 1753 GETCHAR(typenum, inp); 1754 len--; 1755 1756 switch (typenum) { 1757 case EAPT_IDENTITY: 1758 if (esp->es_server.ea_state != eapIdentify) { 1759 dbglog("EAP discarding unwanted Identify \"%.q\"", len, 1760 inp); 1761 break; 1762 } 1763 info("EAP: unauthenticated peer name \"%.*q\"", len, inp); 1764 if (esp->es_server.ea_peer != NULL && 1765 esp->es_server.ea_peer != remote_name) 1766 free(esp->es_server.ea_peer); 1767 esp->es_server.ea_peer = malloc(len + 1); 1768 if (esp->es_server.ea_peer == NULL) { 1769 esp->es_server.ea_peerlen = 0; 1770 eap_figure_next_state(esp, 1); 1771 break; 1772 } 1773 BCOPY(inp, esp->es_server.ea_peer, len); 1774 esp->es_server.ea_peer[len] = '\0'; 1775 esp->es_server.ea_peerlen = len; 1776 eap_figure_next_state(esp, 0); 1777 break; 1778 1779 case EAPT_NOTIFICATION: 1780 dbglog("EAP unexpected Notification; response discarded"); 1781 break; 1782 1783 case EAPT_NAK: 1784 if (len < 1) { 1785 info("EAP: Nak Response with no suggested protocol"); 1786 eap_figure_next_state(esp, 1); 1787 break; 1788 } 1789 1790 GETCHAR(vallen, inp); 1791 len--; 1792 1793 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){ 1794 /* Peer cannot Nak Identify Request */ 1795 eap_figure_next_state(esp, 1); 1796 break; 1797 } 1798 1799 switch (vallen) { 1800 case EAPT_SRP: 1801 /* Run through SRP validator selection again. */ 1802 esp->es_server.ea_state = eapIdentify; 1803 eap_figure_next_state(esp, 0); 1804 break; 1805 1806 case EAPT_MD5CHAP: 1807 esp->es_server.ea_state = eapMD5Chall; 1808 break; 1809 1810 default: 1811 dbglog("EAP: peer requesting unknown Type %d", vallen); 1812 switch (esp->es_server.ea_state) { 1813 case eapSRP1: 1814 case eapSRP2: 1815 case eapSRP3: 1816 esp->es_server.ea_state = eapMD5Chall; 1817 break; 1818 case eapMD5Chall: 1819 case eapSRP4: 1820 esp->es_server.ea_state = eapIdentify; 1821 eap_figure_next_state(esp, 0); 1822 break; 1823 default: 1824 break; 1825 } 1826 break; 1827 } 1828 break; 1829 1830 case EAPT_MD5CHAP: 1831 if (esp->es_server.ea_state != eapMD5Chall) { 1832 error("EAP: unexpected MD5-Response"); 1833 eap_figure_next_state(esp, 1); 1834 break; 1835 } 1836 if (len < 1) { 1837 error("EAP: received MD5-Response with no data"); 1838 eap_figure_next_state(esp, 1); 1839 break; 1840 } 1841 GETCHAR(vallen, inp); 1842 len--; 1843 if (vallen != 16 || vallen > len) { 1844 error("EAP: MD5-Response with bad length %d", vallen); 1845 eap_figure_next_state(esp, 1); 1846 break; 1847 } 1848 1849 /* Not so likely to happen. */ 1850 if (vallen >= len + sizeof (rhostname)) { 1851 dbglog("EAP: trimming really long peer name down"); 1852 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); 1853 rhostname[sizeof (rhostname) - 1] = '\0'; 1854 } else { 1855 BCOPY(inp + vallen, rhostname, len - vallen); 1856 rhostname[len - vallen] = '\0'; 1857 } 1858 1859 /* In case the remote doesn't give us his name. */ 1860 if (explicit_remote || 1861 (remote_name[0] != '\0' && vallen == len)) 1862 strlcpy(rhostname, remote_name, sizeof (rhostname)); 1863 1864 /* 1865 * Get the secret for authenticating the specified 1866 * host. 1867 */ 1868 if (!get_secret(esp->es_unit, rhostname, 1869 esp->es_server.ea_name, secret, &secret_len, 1)) { 1870 dbglog("EAP: no MD5 secret for auth of %q", rhostname); 1871 eap_send_failure(esp); 1872 break; 1873 } 1874 MD5_Init(&mdContext); 1875 MD5_Update(&mdContext, &esp->es_server.ea_id, 1); 1876 MD5_Update(&mdContext, (u_char *)secret, secret_len); 1877 BZERO(secret, sizeof (secret)); 1878 MD5_Update(&mdContext, esp->es_challenge, esp->es_challen); 1879 MD5_Final(hash, &mdContext); 1880 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { 1881 eap_send_failure(esp); 1882 break; 1883 } 1884 esp->es_server.ea_type = EAPT_MD5CHAP; 1885 eap_send_success(esp); 1886 eap_figure_next_state(esp, 0); 1887 if (esp->es_rechallenge != 0) 1888 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge); 1889 break; 1890 1891#ifdef USE_SRP 1892 case EAPT_SRP: 1893 if (len < 1) { 1894 error("EAP: empty SRP Response"); 1895 eap_figure_next_state(esp, 1); 1896 break; 1897 } 1898 GETCHAR(typenum, inp); 1899 len--; 1900 switch (typenum) { 1901 case EAPSRP_CKEY: 1902 if (esp->es_server.ea_state != eapSRP1) { 1903 error("EAP: unexpected SRP Subtype 1 Response"); 1904 eap_figure_next_state(esp, 1); 1905 break; 1906 } 1907 A.data = inp; 1908 A.len = len; 1909 ts = (struct t_server *)esp->es_server.ea_session; 1910 assert(ts != NULL); 1911 esp->es_server.ea_skey = t_servergetkey(ts, &A); 1912 if (esp->es_server.ea_skey == NULL) { 1913 /* Client's A value is bogus; terminate now */ 1914 error("EAP: bogus A value from client"); 1915 eap_send_failure(esp); 1916 } else { 1917 eap_figure_next_state(esp, 0); 1918 } 1919 break; 1920 1921 case EAPSRP_CVALIDATOR: 1922 if (esp->es_server.ea_state != eapSRP2) { 1923 error("EAP: unexpected SRP Subtype 2 Response"); 1924 eap_figure_next_state(esp, 1); 1925 break; 1926 } 1927 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) { 1928 error("EAP: M1 length %d < %d", len, 1929 sizeof (u_int32_t) + SHA_DIGESTSIZE); 1930 eap_figure_next_state(esp, 1); 1931 break; 1932 } 1933 GETLONG(esp->es_server.ea_keyflags, inp); 1934 ts = (struct t_server *)esp->es_server.ea_session; 1935 assert(ts != NULL); 1936 if (t_serververify(ts, inp)) { 1937 info("EAP: unable to validate client identity"); 1938 eap_send_failure(esp); 1939 break; 1940 } 1941 eap_figure_next_state(esp, 0); 1942 break; 1943 1944 case EAPSRP_ACK: 1945 if (esp->es_server.ea_state != eapSRP3) { 1946 error("EAP: unexpected SRP Subtype 3 Response"); 1947 eap_send_failure(esp); 1948 break; 1949 } 1950 esp->es_server.ea_type = EAPT_SRP; 1951 eap_send_success(esp); 1952 eap_figure_next_state(esp, 0); 1953 if (esp->es_rechallenge != 0) 1954 TIMEOUT(eap_rechallenge, esp, 1955 esp->es_rechallenge); 1956 if (esp->es_lwrechallenge != 0) 1957 TIMEOUT(srp_lwrechallenge, esp, 1958 esp->es_lwrechallenge); 1959 break; 1960 1961 case EAPSRP_LWRECHALLENGE: 1962 if (esp->es_server.ea_state != eapSRP4) { 1963 info("EAP: unexpected SRP Subtype 4 Response"); 1964 return; 1965 } 1966 if (len != SHA_DIGESTSIZE) { 1967 error("EAP: bad Lightweight rechallenge " 1968 "response"); 1969 return; 1970 } 1971 SHA1Init(&ctxt); 1972 vallen = id; 1973 SHA1Update(&ctxt, &vallen, 1); 1974 SHA1Update(&ctxt, esp->es_server.ea_skey, 1975 SESSION_KEY_LEN); 1976 SHA1Update(&ctxt, esp->es_challenge, esp->es_challen); 1977 SHA1Update(&ctxt, esp->es_server.ea_peer, 1978 esp->es_server.ea_peerlen); 1979 SHA1Final(dig, &ctxt); 1980 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) { 1981 error("EAP: failed Lightweight rechallenge"); 1982 eap_send_failure(esp); 1983 break; 1984 } 1985 esp->es_server.ea_state = eapOpen; 1986 if (esp->es_lwrechallenge != 0) 1987 TIMEOUT(srp_lwrechallenge, esp, 1988 esp->es_lwrechallenge); 1989 break; 1990 } 1991 break; 1992#endif /* USE_SRP */ 1993 1994 default: 1995 /* This can't happen. */ 1996 error("EAP: unknown Response type %d; ignored", typenum); 1997 return; 1998 } 1999 2000 if (esp->es_server.ea_timeout > 0) { 2001 UNTIMEOUT(eap_server_timeout, (void *)esp); 2002 } 2003 2004 if (esp->es_server.ea_state != eapBadAuth && 2005 esp->es_server.ea_state != eapOpen) { 2006 esp->es_server.ea_id++; 2007 eap_send_request(esp); 2008 } 2009} 2010 2011/* 2012 * eap_success - Receive EAP Success message (client mode). 2013 */ 2014static void 2015eap_success(esp, inp, id, len) 2016eap_state *esp; 2017u_char *inp; 2018int id; 2019int len; 2020{ 2021 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) { 2022 dbglog("EAP unexpected success message in state %s (%d)", 2023 eap_state_name(esp->es_client.ea_state), 2024 esp->es_client.ea_state); 2025 return; 2026 } 2027 2028 if (esp->es_client.ea_timeout > 0) { 2029 UNTIMEOUT(eap_client_timeout, (void *)esp); 2030 } 2031 2032 if (len > 0) { 2033 /* This is odd. The spec doesn't allow for this. */ 2034 PRINTMSG(inp, len); 2035 } 2036 2037 esp->es_client.ea_state = eapOpen; 2038 auth_withpeer_success(esp->es_unit, PPP_EAP, 0); 2039} 2040 2041/* 2042 * eap_failure - Receive EAP Failure message (client mode). 2043 */ 2044static void 2045eap_failure(esp, inp, id, len) 2046eap_state *esp; 2047u_char *inp; 2048int id; 2049int len; 2050{ 2051 if (!eap_client_active(esp)) { 2052 dbglog("EAP unexpected failure message in state %s (%d)", 2053 eap_state_name(esp->es_client.ea_state), 2054 esp->es_client.ea_state); 2055 } 2056 2057 if (esp->es_client.ea_timeout > 0) { 2058 UNTIMEOUT(eap_client_timeout, (void *)esp); 2059 } 2060 2061 if (len > 0) { 2062 /* This is odd. The spec doesn't allow for this. */ 2063 PRINTMSG(inp, len); 2064 } 2065 2066 esp->es_client.ea_state = eapBadAuth; 2067 2068 error("EAP: peer reports authentication failure"); 2069 auth_withpeer_fail(esp->es_unit, PPP_EAP); 2070} 2071 2072/* 2073 * eap_input - Handle received EAP message. 2074 */ 2075static void 2076eap_input(unit, inp, inlen) 2077int unit; 2078u_char *inp; 2079int inlen; 2080{ 2081 eap_state *esp = &eap_states[unit]; 2082 u_char code, id; 2083 int len; 2084 2085 /* 2086 * Parse header (code, id and length). If packet too short, 2087 * drop it. 2088 */ 2089 if (inlen < EAP_HEADERLEN) { 2090 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN); 2091 return; 2092 } 2093 GETCHAR(code, inp); 2094 GETCHAR(id, inp); 2095 GETSHORT(len, inp); 2096 if (len < EAP_HEADERLEN || len > inlen) { 2097 error("EAP: packet has illegal length field %d (%d..%d)", len, 2098 EAP_HEADERLEN, inlen); 2099 return; 2100 } 2101 len -= EAP_HEADERLEN; 2102 2103 /* Dispatch based on message code */ 2104 switch (code) { 2105 case EAP_REQUEST: 2106 eap_request(esp, inp, id, len); 2107 break; 2108 2109 case EAP_RESPONSE: 2110 eap_response(esp, inp, id, len); 2111 break; 2112 2113 case EAP_SUCCESS: 2114 eap_success(esp, inp, id, len); 2115 break; 2116 2117 case EAP_FAILURE: 2118 eap_failure(esp, inp, id, len); 2119 break; 2120 2121 default: /* XXX Need code reject */ 2122 /* Note: it's not legal to send EAP Nak here. */ 2123 warn("EAP: unknown code %d received", code); 2124 break; 2125 } 2126} 2127 2128/* 2129 * eap_printpkt - print the contents of an EAP packet. 2130 */ 2131static char *eap_codenames[] = { 2132 "Request", "Response", "Success", "Failure" 2133}; 2134 2135static char *eap_typenames[] = { 2136 "Identity", "Notification", "Nak", "MD5-Challenge", 2137 "OTP", "Generic-Token", NULL, NULL, 2138 "RSA", "DSS", "KEA", "KEA-Validate", 2139 "TLS", "Defender", "Windows 2000", "Arcot", 2140 "Cisco", "Nokia", "SRP" 2141}; 2142 2143static int 2144eap_printpkt(inp, inlen, printer, arg) 2145u_char *inp; 2146int inlen; 2147void (*printer) __P((void *, char *, ...)); 2148void *arg; 2149{ 2150 int code, id, len, rtype, vallen; 2151 u_char *pstart; 2152 u_int32_t uval; 2153 2154 if (inlen < EAP_HEADERLEN) 2155 return (0); 2156 pstart = inp; 2157 GETCHAR(code, inp); 2158 GETCHAR(id, inp); 2159 GETSHORT(len, inp); 2160 if (len < EAP_HEADERLEN || len > inlen) 2161 return (0); 2162 2163 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *)) 2164 printer(arg, " %s", eap_codenames[code-1]); 2165 else 2166 printer(arg, " code=0x%x", code); 2167 printer(arg, " id=0x%x", id); 2168 len -= EAP_HEADERLEN; 2169 switch (code) { 2170 case EAP_REQUEST: 2171 if (len < 1) { 2172 printer(arg, " <missing type>"); 2173 break; 2174 } 2175 GETCHAR(rtype, inp); 2176 len--; 2177 if (rtype >= 1 && 2178 rtype <= sizeof (eap_typenames) / sizeof (char *)) 2179 printer(arg, " %s", eap_typenames[rtype-1]); 2180 else 2181 printer(arg, " type=0x%x", rtype); 2182 switch (rtype) { 2183 case EAPT_IDENTITY: 2184 case EAPT_NOTIFICATION: 2185 if (len > 0) { 2186 printer(arg, " <Message "); 2187 print_string((char *)inp, len, printer, arg); 2188 printer(arg, ">"); 2189 INCPTR(len, inp); 2190 len = 0; 2191 } else { 2192 printer(arg, " <No message>"); 2193 } 2194 break; 2195 2196 case EAPT_MD5CHAP: 2197 if (len <= 0) 2198 break; 2199 GETCHAR(vallen, inp); 2200 len--; 2201 if (vallen > len) 2202 goto truncated; 2203 printer(arg, " <Value%.*B>", vallen, inp); 2204 INCPTR(vallen, inp); 2205 len -= vallen; 2206 if (len > 0) { 2207 printer(arg, " <Name "); 2208 print_string((char *)inp, len, printer, arg); 2209 printer(arg, ">"); 2210 INCPTR(len, inp); 2211 len = 0; 2212 } else { 2213 printer(arg, " <No name>"); 2214 } 2215 break; 2216 2217 case EAPT_SRP: 2218 if (len < 3) 2219 goto truncated; 2220 GETCHAR(vallen, inp); 2221 len--; 2222 printer(arg, "-%d", vallen); 2223 switch (vallen) { 2224 case EAPSRP_CHALLENGE: 2225 GETCHAR(vallen, inp); 2226 len--; 2227 if (vallen >= len) 2228 goto truncated; 2229 if (vallen > 0) { 2230 printer(arg, " <Name "); 2231 print_string((char *)inp, vallen, printer, 2232 arg); 2233 printer(arg, ">"); 2234 } else { 2235 printer(arg, " <No name>"); 2236 } 2237 INCPTR(vallen, inp); 2238 len -= vallen; 2239 GETCHAR(vallen, inp); 2240 len--; 2241 if (vallen >= len) 2242 goto truncated; 2243 printer(arg, " <s%.*B>", vallen, inp); 2244 INCPTR(vallen, inp); 2245 len -= vallen; 2246 GETCHAR(vallen, inp); 2247 len--; 2248 if (vallen > len) 2249 goto truncated; 2250 if (vallen == 0) { 2251 printer(arg, " <Default g=2>"); 2252 } else { 2253 printer(arg, " <g%.*B>", vallen, inp); 2254 } 2255 INCPTR(vallen, inp); 2256 len -= vallen; 2257 if (len == 0) { 2258 printer(arg, " <Default N>"); 2259 } else { 2260 printer(arg, " <N%.*B>", len, inp); 2261 INCPTR(len, inp); 2262 len = 0; 2263 } 2264 break; 2265 2266 case EAPSRP_SKEY: 2267 printer(arg, " <B%.*B>", len, inp); 2268 INCPTR(len, inp); 2269 len = 0; 2270 break; 2271 2272 case EAPSRP_SVALIDATOR: 2273 if (len < sizeof (u_int32_t)) 2274 break; 2275 GETLONG(uval, inp); 2276 len -= sizeof (u_int32_t); 2277 if (uval & SRPVAL_EBIT) { 2278 printer(arg, " E"); 2279 uval &= ~SRPVAL_EBIT; 2280 } 2281 if (uval != 0) { 2282 printer(arg, " f<%X>", uval); 2283 } 2284 if ((vallen = len) > SHA_DIGESTSIZE) 2285 vallen = SHA_DIGESTSIZE; 2286 printer(arg, " <M2%.*B%s>", len, inp, 2287 len < SHA_DIGESTSIZE ? "?" : ""); 2288 INCPTR(vallen, inp); 2289 len -= vallen; 2290 if (len > 0) { 2291 printer(arg, " <PN%.*B>", len, inp); 2292 INCPTR(len, inp); 2293 len = 0; 2294 } 2295 break; 2296 2297 case EAPSRP_LWRECHALLENGE: 2298 printer(arg, " <Challenge%.*B>", len, inp); 2299 INCPTR(len, inp); 2300 len = 0; 2301 break; 2302 } 2303 break; 2304 } 2305 break; 2306 2307 case EAP_RESPONSE: 2308 if (len < 1) 2309 break; 2310 GETCHAR(rtype, inp); 2311 len--; 2312 if (rtype >= 1 && 2313 rtype <= sizeof (eap_typenames) / sizeof (char *)) 2314 printer(arg, " %s", eap_typenames[rtype-1]); 2315 else 2316 printer(arg, " type=0x%x", rtype); 2317 switch (rtype) { 2318 case EAPT_IDENTITY: 2319 if (len > 0) { 2320 printer(arg, " <Name "); 2321 print_string((char *)inp, len, printer, arg); 2322 printer(arg, ">"); 2323 INCPTR(len, inp); 2324 len = 0; 2325 } 2326 break; 2327 2328 case EAPT_NAK: 2329 if (len <= 0) { 2330 printer(arg, " <missing hint>"); 2331 break; 2332 } 2333 GETCHAR(rtype, inp); 2334 len--; 2335 printer(arg, " <Suggested-type %02X", rtype); 2336 if (rtype >= 1 && 2337 rtype < sizeof (eap_typenames) / sizeof (char *)) 2338 printer(arg, " (%s)", eap_typenames[rtype-1]); 2339 printer(arg, ">"); 2340 break; 2341 2342 case EAPT_MD5CHAP: 2343 if (len <= 0) { 2344 printer(arg, " <missing length>"); 2345 break; 2346 } 2347 GETCHAR(vallen, inp); 2348 len--; 2349 if (vallen > len) 2350 goto truncated; 2351 printer(arg, " <Value%.*B>", vallen, inp); 2352 INCPTR(vallen, inp); 2353 len -= vallen; 2354 if (len > 0) { 2355 printer(arg, " <Name "); 2356 print_string((char *)inp, len, printer, arg); 2357 printer(arg, ">"); 2358 INCPTR(len, inp); 2359 len = 0; 2360 } else { 2361 printer(arg, " <No name>"); 2362 } 2363 break; 2364 2365 case EAPT_SRP: 2366 if (len < 1) 2367 goto truncated; 2368 GETCHAR(vallen, inp); 2369 len--; 2370 printer(arg, "-%d", vallen); 2371 switch (vallen) { 2372 case EAPSRP_CKEY: 2373 printer(arg, " <A%.*B>", len, inp); 2374 INCPTR(len, inp); 2375 len = 0; 2376 break; 2377 2378 case EAPSRP_CVALIDATOR: 2379 if (len < sizeof (u_int32_t)) 2380 break; 2381 GETLONG(uval, inp); 2382 len -= sizeof (u_int32_t); 2383 if (uval & SRPVAL_EBIT) { 2384 printer(arg, " E"); 2385 uval &= ~SRPVAL_EBIT; 2386 } 2387 if (uval != 0) { 2388 printer(arg, " f<%X>", uval); 2389 } 2390 printer(arg, " <M1%.*B%s>", len, inp, 2391 len == SHA_DIGESTSIZE ? "" : "?"); 2392 INCPTR(len, inp); 2393 len = 0; 2394 break; 2395 2396 case EAPSRP_ACK: 2397 break; 2398 2399 case EAPSRP_LWRECHALLENGE: 2400 printer(arg, " <Response%.*B%s>", len, inp, 2401 len == SHA_DIGESTSIZE ? "" : "?"); 2402 if ((vallen = len) > SHA_DIGESTSIZE) 2403 vallen = SHA_DIGESTSIZE; 2404 INCPTR(vallen, inp); 2405 len -= vallen; 2406 break; 2407 } 2408 break; 2409 } 2410 break; 2411 2412 case EAP_SUCCESS: /* No payload expected for these! */ 2413 case EAP_FAILURE: 2414 break; 2415 2416 truncated: 2417 printer(arg, " <truncated>"); 2418 break; 2419 } 2420 2421 if (len > 8) 2422 printer(arg, "%8B...", inp); 2423 else if (len > 0) 2424 printer(arg, "%.*B", len, inp); 2425 INCPTR(len, inp); 2426 2427 return (inp - pstart); 2428} 2429