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