1 /* 2 * hostapd / EAP Full Authenticator state machine (RFC 4137) 3 * Copyright (c) 2004-2014, Jouni Malinen <j (at) w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 * 8 * This state machine is based on the full authenticator state machine defined 9 * in RFC 4137. However, to support backend authentication in RADIUS 10 * authentication server functionality, parts of backend authenticator (also 11 * from RFC 4137) are mixed in. This functionality is enabled by setting 12 * backend_auth configuration variable to TRUE. 13 */ 14 15 #include "includes.h" 16 17 #include "common.h" 18 #include "crypto/sha256.h" 19 #include "eap_i.h" 20 #include "state_machine.h" 21 #include "common/wpa_ctrl.h" 22 23 #define STATE_MACHINE_DATA struct eap_sm 24 #define STATE_MACHINE_DEBUG_PREFIX "EAP" 25 26 #define EAP_MAX_AUTH_ROUNDS 50 27 28 static void eap_user_free(struct eap_user *user); 29 30 31 /* EAP state machines are described in RFC 4137 */ 32 33 static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount, 34 int eapSRTT, int eapRTTVAR, 35 int methodTimeout); 36 static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp); 37 static int eap_sm_getId(const struct wpabuf *data); 38 static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id); 39 static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id); 40 static int eap_sm_nextId(struct eap_sm *sm, int id); 41 static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list, 42 size_t len); 43 static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor); 44 static int eap_sm_Policy_getDecision(struct eap_sm *sm); 45 static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method); 46 47 48 static int eap_get_erp_send_reauth_start(struct eap_sm *sm) 49 { 50 if (sm->eapol_cb->get_erp_send_reauth_start) 51 return sm->eapol_cb->get_erp_send_reauth_start(sm->eapol_ctx); 52 return 0; 53 } 54 55 56 static const char * eap_get_erp_domain(struct eap_sm *sm) 57 { 58 if (sm->eapol_cb->get_erp_domain) 59 return sm->eapol_cb->get_erp_domain(sm->eapol_ctx); 60 return NULL; 61 } 62 63 64 #ifdef CONFIG_ERP 65 66 static struct eap_server_erp_key * eap_erp_get_key(struct eap_sm *sm, 67 const char *keyname) 68 { 69 if (sm->eapol_cb->erp_get_key) 70 return sm->eapol_cb->erp_get_key(sm->eapol_ctx, keyname); 71 return NULL; 72 } 73 74 75 static int eap_erp_add_key(struct eap_sm *sm, struct eap_server_erp_key *erp) 76 { 77 if (sm->eapol_cb->erp_add_key) 78 return sm->eapol_cb->erp_add_key(sm->eapol_ctx, erp); 79 return -1; 80 } 81 82 #endif /* CONFIG_ERP */ 83 84 85 static struct wpabuf * eap_sm_buildInitiateReauthStart(struct eap_sm *sm, 86 u8 id) 87 { 88 const char *domain; 89 size_t plen = 1; 90 struct wpabuf *msg; 91 size_t domain_len = 0; 92 93 domain = eap_get_erp_domain(sm); 94 if (domain) { 95 domain_len = os_strlen(domain); 96 plen += 2 + domain_len; 97 } 98 99 msg = eap_msg_alloc(EAP_VENDOR_IETF, 100 (EapType) EAP_ERP_TYPE_REAUTH_START, plen, 101 EAP_CODE_INITIATE, id); 102 if (msg == NULL) 103 return NULL; 104 wpabuf_put_u8(msg, 0); /* Reserved */ 105 if (domain) { 106 /* Domain name TLV */ 107 wpabuf_put_u8(msg, EAP_ERP_TLV_DOMAIN_NAME); 108 wpabuf_put_u8(msg, domain_len); 109 wpabuf_put_data(msg, domain, domain_len); 110 } 111 112 return msg; 113 } 114 115 116 static int eap_copy_buf(struct wpabuf **dst, const struct wpabuf *src) 117 { 118 if (src == NULL) 119 return -1; 120 121 wpabuf_free(*dst); 122 *dst = wpabuf_dup(src); 123 return *dst ? 0 : -1; 124 } 125 126 127 static int eap_copy_data(u8 **dst, size_t *dst_len, 128 const u8 *src, size_t src_len) 129 { 130 if (src == NULL) 131 return -1; 132 133 os_free(*dst); 134 *dst = os_malloc(src_len); 135 if (*dst) { 136 os_memcpy(*dst, src, src_len); 137 *dst_len = src_len; 138 return 0; 139 } else { 140 *dst_len = 0; 141 return -1; 142 } 143 } 144 145 #define EAP_COPY(dst, src) \ 146 eap_copy_data((dst), (dst ## Len), (src), (src ## Len)) 147 148 149 /** 150 * eap_user_get - Fetch user information from the database 151 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 152 * @identity: Identity (User-Name) of the user 153 * @identity_len: Length of identity in bytes 154 * @phase2: 0 = EAP phase1 user, 1 = EAP phase2 (tunneled) user 155 * Returns: 0 on success, or -1 on failure 156 * 157 * This function is used to fetch user information for EAP. The user will be 158 * selected based on the specified identity. sm->user and 159 * sm->user_eap_method_index are updated for the new user when a matching user 160 * is found. sm->user can be used to get user information (e.g., password). 161 */ 162 int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len, 163 int phase2) 164 { 165 struct eap_user *user; 166 167 if (sm == NULL || sm->eapol_cb == NULL || 168 sm->eapol_cb->get_eap_user == NULL) 169 return -1; 170 171 eap_user_free(sm->user); 172 sm->user = NULL; 173 174 user = os_zalloc(sizeof(*user)); 175 if (user == NULL) 176 return -1; 177 178 if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity, 179 identity_len, phase2, user) != 0) { 180 eap_user_free(user); 181 return -1; 182 } 183 184 sm->user = user; 185 sm->user_eap_method_index = 0; 186 187 return 0; 188 } 189 190 191 void eap_log_msg(struct eap_sm *sm, const char *fmt, ...) 192 { 193 va_list ap; 194 char *buf; 195 int buflen; 196 197 if (sm == NULL || sm->eapol_cb == NULL || sm->eapol_cb->log_msg == NULL) 198 return; 199 200 va_start(ap, fmt); 201 buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 202 va_end(ap); 203 204 buf = os_malloc(buflen); 205 if (buf == NULL) 206 return; 207 va_start(ap, fmt); 208 vsnprintf(buf, buflen, fmt, ap); 209 va_end(ap); 210 211 sm->eapol_cb->log_msg(sm->eapol_ctx, buf); 212 213 os_free(buf); 214 } 215 216 217 SM_STATE(EAP, DISABLED) 218 { 219 SM_ENTRY(EAP, DISABLED); 220 sm->num_rounds = 0; 221 } 222 223 224 SM_STATE(EAP, INITIALIZE) 225 { 226 SM_ENTRY(EAP, INITIALIZE); 227 228 if (sm->eap_if.eapRestart && !sm->eap_server && sm->identity) { 229 /* 230 * Need to allow internal Identity method to be used instead 231 * of passthrough at the beginning of reauthentication. 232 */ 233 eap_server_clear_identity(sm); 234 } 235 236 sm->try_initiate_reauth = FALSE; 237 sm->currentId = -1; 238 sm->eap_if.eapSuccess = FALSE; 239 sm->eap_if.eapFail = FALSE; 240 sm->eap_if.eapTimeout = FALSE; 241 bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); 242 sm->eap_if.eapKeyData = NULL; 243 sm->eap_if.eapKeyDataLen = 0; 244 os_free(sm->eap_if.eapSessionId); 245 sm->eap_if.eapSessionId = NULL; 246 sm->eap_if.eapSessionIdLen = 0; 247 sm->eap_if.eapKeyAvailable = FALSE; 248 sm->eap_if.eapRestart = FALSE; 249 250 /* 251 * This is not defined in RFC 4137, but method state needs to be 252 * reseted here so that it does not remain in success state when 253 * re-authentication starts. 254 */ 255 if (sm->m && sm->eap_method_priv) { 256 sm->m->reset(sm, sm->eap_method_priv); 257 sm->eap_method_priv = NULL; 258 } 259 sm->m = NULL; 260 sm->user_eap_method_index = 0; 261 262 if (sm->backend_auth) { 263 sm->currentMethod = EAP_TYPE_NONE; 264 /* parse rxResp, respId, respMethod */ 265 eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 266 if (sm->rxResp) { 267 sm->currentId = sm->respId; 268 } 269 } 270 sm->num_rounds = 0; 271 sm->method_pending = METHOD_PENDING_NONE; 272 273 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED 274 MACSTR, MAC2STR(sm->peer_addr)); 275 } 276 277 278 SM_STATE(EAP, PICK_UP_METHOD) 279 { 280 SM_ENTRY(EAP, PICK_UP_METHOD); 281 282 if (eap_sm_Policy_doPickUp(sm, sm->respMethod)) { 283 sm->currentMethod = sm->respMethod; 284 if (sm->m && sm->eap_method_priv) { 285 sm->m->reset(sm, sm->eap_method_priv); 286 sm->eap_method_priv = NULL; 287 } 288 sm->m = eap_server_get_eap_method(EAP_VENDOR_IETF, 289 sm->currentMethod); 290 if (sm->m && sm->m->initPickUp) { 291 sm->eap_method_priv = sm->m->initPickUp(sm); 292 if (sm->eap_method_priv == NULL) { 293 wpa_printf(MSG_DEBUG, "EAP: Failed to " 294 "initialize EAP method %d", 295 sm->currentMethod); 296 sm->m = NULL; 297 sm->currentMethod = EAP_TYPE_NONE; 298 } 299 } else { 300 sm->m = NULL; 301 sm->currentMethod = EAP_TYPE_NONE; 302 } 303 } 304 305 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 306 "method=%u", sm->currentMethod); 307 } 308 309 310 SM_STATE(EAP, IDLE) 311 { 312 SM_ENTRY(EAP, IDLE); 313 314 sm->eap_if.retransWhile = eap_sm_calculateTimeout( 315 sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR, 316 sm->methodTimeout); 317 } 318 319 320 SM_STATE(EAP, RETRANSMIT) 321 { 322 SM_ENTRY(EAP, RETRANSMIT); 323 324 sm->retransCount++; 325 if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) { 326 if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0) 327 sm->eap_if.eapReq = TRUE; 328 } 329 } 330 331 332 SM_STATE(EAP, RECEIVED) 333 { 334 SM_ENTRY(EAP, RECEIVED); 335 336 /* parse rxResp, respId, respMethod */ 337 eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 338 sm->num_rounds++; 339 } 340 341 342 SM_STATE(EAP, DISCARD) 343 { 344 SM_ENTRY(EAP, DISCARD); 345 sm->eap_if.eapResp = FALSE; 346 sm->eap_if.eapNoReq = TRUE; 347 } 348 349 350 SM_STATE(EAP, SEND_REQUEST) 351 { 352 SM_ENTRY(EAP, SEND_REQUEST); 353 354 sm->retransCount = 0; 355 if (sm->eap_if.eapReqData) { 356 if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0) 357 { 358 sm->eap_if.eapResp = FALSE; 359 sm->eap_if.eapReq = TRUE; 360 } else { 361 sm->eap_if.eapResp = FALSE; 362 sm->eap_if.eapReq = FALSE; 363 } 364 } else { 365 wpa_printf(MSG_INFO, "EAP: SEND_REQUEST - no eapReqData"); 366 sm->eap_if.eapResp = FALSE; 367 sm->eap_if.eapReq = FALSE; 368 sm->eap_if.eapNoReq = TRUE; 369 } 370 } 371 372 373 SM_STATE(EAP, INTEGRITY_CHECK) 374 { 375 SM_ENTRY(EAP, INTEGRITY_CHECK); 376 377 if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) { 378 sm->ignore = TRUE; 379 return; 380 } 381 382 if (sm->m->check) { 383 sm->ignore = sm->m->check(sm, sm->eap_method_priv, 384 sm->eap_if.eapRespData); 385 } 386 } 387 388 389 SM_STATE(EAP, METHOD_REQUEST) 390 { 391 SM_ENTRY(EAP, METHOD_REQUEST); 392 393 if (sm->m == NULL) { 394 wpa_printf(MSG_DEBUG, "EAP: method not initialized"); 395 return; 396 } 397 398 sm->currentId = eap_sm_nextId(sm, sm->currentId); 399 wpa_printf(MSG_DEBUG, "EAP: building EAP-Request: Identifier %d", 400 sm->currentId); 401 sm->lastId = sm->currentId; 402 wpabuf_free(sm->eap_if.eapReqData); 403 sm->eap_if.eapReqData = sm->m->buildReq(sm, sm->eap_method_priv, 404 sm->currentId); 405 if (sm->m->getTimeout) 406 sm->methodTimeout = sm->m->getTimeout(sm, sm->eap_method_priv); 407 else 408 sm->methodTimeout = 0; 409 } 410 411 412 static void eap_server_erp_init(struct eap_sm *sm) 413 { 414 #ifdef CONFIG_ERP 415 u8 *emsk = NULL; 416 size_t emsk_len = 0; 417 u8 EMSKname[EAP_EMSK_NAME_LEN]; 418 u8 len[2], ctx[3]; 419 const char *domain; 420 size_t domain_len, nai_buf_len; 421 struct eap_server_erp_key *erp = NULL; 422 int pos; 423 424 domain = eap_get_erp_domain(sm); 425 if (!domain) 426 return; 427 428 domain_len = os_strlen(domain); 429 430 nai_buf_len = 2 * EAP_EMSK_NAME_LEN + 1 + domain_len; 431 if (nai_buf_len > 253) { 432 /* 433 * keyName-NAI has a maximum length of 253 octet to fit in 434 * RADIUS attributes. 435 */ 436 wpa_printf(MSG_DEBUG, 437 "EAP: Too long realm for ERP keyName-NAI maximum length"); 438 return; 439 } 440 nai_buf_len++; /* null termination */ 441 erp = os_zalloc(sizeof(*erp) + nai_buf_len); 442 if (erp == NULL) 443 goto fail; 444 erp->recv_seq = (u32) -1; 445 446 emsk = sm->m->get_emsk(sm, sm->eap_method_priv, &emsk_len); 447 if (!emsk || emsk_len == 0 || emsk_len > ERP_MAX_KEY_LEN) { 448 wpa_printf(MSG_DEBUG, 449 "EAP: No suitable EMSK available for ERP"); 450 goto fail; 451 } 452 453 wpa_hexdump_key(MSG_DEBUG, "EAP: EMSK", emsk, emsk_len); 454 455 WPA_PUT_BE16(len, EAP_EMSK_NAME_LEN); 456 if (hmac_sha256_kdf(sm->eap_if.eapSessionId, sm->eap_if.eapSessionIdLen, 457 "EMSK", len, sizeof(len), 458 EMSKname, EAP_EMSK_NAME_LEN) < 0) { 459 wpa_printf(MSG_DEBUG, "EAP: Could not derive EMSKname"); 460 goto fail; 461 } 462 wpa_hexdump(MSG_DEBUG, "EAP: EMSKname", EMSKname, EAP_EMSK_NAME_LEN); 463 464 pos = wpa_snprintf_hex(erp->keyname_nai, nai_buf_len, 465 EMSKname, EAP_EMSK_NAME_LEN); 466 erp->keyname_nai[pos] = '@'; 467 os_memcpy(&erp->keyname_nai[pos + 1], domain, domain_len); 468 469 WPA_PUT_BE16(len, emsk_len); 470 if (hmac_sha256_kdf(emsk, emsk_len, 471 "EAP Re-authentication Root Key (at) ietf.org", 472 len, sizeof(len), erp->rRK, emsk_len) < 0) { 473 wpa_printf(MSG_DEBUG, "EAP: Could not derive rRK for ERP"); 474 goto fail; 475 } 476 erp->rRK_len = emsk_len; 477 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rRK", erp->rRK, erp->rRK_len); 478 479 ctx[0] = EAP_ERP_CS_HMAC_SHA256_128; 480 WPA_PUT_BE16(&ctx[1], erp->rRK_len); 481 if (hmac_sha256_kdf(erp->rRK, erp->rRK_len, 482 "Re-authentication Integrity Key (at) ietf.org", 483 ctx, sizeof(ctx), erp->rIK, erp->rRK_len) < 0) { 484 wpa_printf(MSG_DEBUG, "EAP: Could not derive rIK for ERP"); 485 goto fail; 486 } 487 erp->rIK_len = erp->rRK_len; 488 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rIK", erp->rIK, erp->rIK_len); 489 490 if (eap_erp_add_key(sm, erp) == 0) { 491 wpa_printf(MSG_DEBUG, "EAP: Stored ERP keys %s", 492 erp->keyname_nai); 493 erp = NULL; 494 } 495 496 fail: 497 bin_clear_free(emsk, emsk_len); 498 bin_clear_free(erp, sizeof(*erp)); 499 #endif /* CONFIG_ERP */ 500 } 501 502 503 SM_STATE(EAP, METHOD_RESPONSE) 504 { 505 SM_ENTRY(EAP, METHOD_RESPONSE); 506 507 if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) 508 return; 509 510 sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData); 511 if (sm->m->isDone(sm, sm->eap_method_priv)) { 512 eap_sm_Policy_update(sm, NULL, 0); 513 bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); 514 if (sm->m->getKey) { 515 sm->eap_if.eapKeyData = sm->m->getKey( 516 sm, sm->eap_method_priv, 517 &sm->eap_if.eapKeyDataLen); 518 } else { 519 sm->eap_if.eapKeyData = NULL; 520 sm->eap_if.eapKeyDataLen = 0; 521 } 522 os_free(sm->eap_if.eapSessionId); 523 sm->eap_if.eapSessionId = NULL; 524 if (sm->m->getSessionId) { 525 sm->eap_if.eapSessionId = sm->m->getSessionId( 526 sm, sm->eap_method_priv, 527 &sm->eap_if.eapSessionIdLen); 528 wpa_hexdump(MSG_DEBUG, "EAP: Session-Id", 529 sm->eap_if.eapSessionId, 530 sm->eap_if.eapSessionIdLen); 531 } 532 if (sm->erp && sm->m->get_emsk && sm->eap_if.eapSessionId) 533 eap_server_erp_init(sm); 534 sm->methodState = METHOD_END; 535 } else { 536 sm->methodState = METHOD_CONTINUE; 537 } 538 } 539 540 541 SM_STATE(EAP, PROPOSE_METHOD) 542 { 543 int vendor; 544 EapType type; 545 546 SM_ENTRY(EAP, PROPOSE_METHOD); 547 548 sm->try_initiate_reauth = FALSE; 549 try_another_method: 550 type = eap_sm_Policy_getNextMethod(sm, &vendor); 551 if (vendor == EAP_VENDOR_IETF) 552 sm->currentMethod = type; 553 else 554 sm->currentMethod = EAP_TYPE_EXPANDED; 555 if (sm->m && sm->eap_method_priv) { 556 sm->m->reset(sm, sm->eap_method_priv); 557 sm->eap_method_priv = NULL; 558 } 559 sm->m = eap_server_get_eap_method(vendor, type); 560 if (sm->m) { 561 sm->eap_method_priv = sm->m->init(sm); 562 if (sm->eap_method_priv == NULL) { 563 wpa_printf(MSG_DEBUG, "EAP: Failed to initialize EAP " 564 "method %d", sm->currentMethod); 565 sm->m = NULL; 566 sm->currentMethod = EAP_TYPE_NONE; 567 goto try_another_method; 568 } 569 } 570 if (sm->m == NULL) { 571 wpa_printf(MSG_DEBUG, "EAP: Could not find suitable EAP method"); 572 eap_log_msg(sm, "Could not find suitable EAP method"); 573 sm->decision = DECISION_FAILURE; 574 return; 575 } 576 if (sm->currentMethod == EAP_TYPE_IDENTITY || 577 sm->currentMethod == EAP_TYPE_NOTIFICATION) 578 sm->methodState = METHOD_CONTINUE; 579 else 580 sm->methodState = METHOD_PROPOSED; 581 582 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 583 "vendor=%u method=%u", vendor, sm->currentMethod); 584 eap_log_msg(sm, "Propose EAP method vendor=%u method=%u", 585 vendor, sm->currentMethod); 586 } 587 588 589 SM_STATE(EAP, NAK) 590 { 591 const struct eap_hdr *nak; 592 size_t len = 0; 593 const u8 *pos; 594 const u8 *nak_list = NULL; 595 596 SM_ENTRY(EAP, NAK); 597 598 if (sm->eap_method_priv) { 599 sm->m->reset(sm, sm->eap_method_priv); 600 sm->eap_method_priv = NULL; 601 } 602 sm->m = NULL; 603 604 if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) 605 return; 606 607 nak = wpabuf_head(sm->eap_if.eapRespData); 608 if (nak && wpabuf_len(sm->eap_if.eapRespData) > sizeof(*nak)) { 609 len = be_to_host16(nak->length); 610 if (len > wpabuf_len(sm->eap_if.eapRespData)) 611 len = wpabuf_len(sm->eap_if.eapRespData); 612 pos = (const u8 *) (nak + 1); 613 len -= sizeof(*nak); 614 if (*pos == EAP_TYPE_NAK) { 615 pos++; 616 len--; 617 nak_list = pos; 618 } 619 } 620 eap_sm_Policy_update(sm, nak_list, len); 621 } 622 623 624 SM_STATE(EAP, SELECT_ACTION) 625 { 626 SM_ENTRY(EAP, SELECT_ACTION); 627 628 sm->decision = eap_sm_Policy_getDecision(sm); 629 } 630 631 632 SM_STATE(EAP, TIMEOUT_FAILURE) 633 { 634 SM_ENTRY(EAP, TIMEOUT_FAILURE); 635 636 sm->eap_if.eapTimeout = TRUE; 637 } 638 639 640 SM_STATE(EAP, FAILURE) 641 { 642 SM_ENTRY(EAP, FAILURE); 643 644 wpabuf_free(sm->eap_if.eapReqData); 645 sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId); 646 wpabuf_free(sm->lastReqData); 647 sm->lastReqData = NULL; 648 sm->eap_if.eapFail = TRUE; 649 650 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 651 MACSTR, MAC2STR(sm->peer_addr)); 652 } 653 654 655 SM_STATE(EAP, SUCCESS) 656 { 657 SM_ENTRY(EAP, SUCCESS); 658 659 wpabuf_free(sm->eap_if.eapReqData); 660 sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId); 661 wpabuf_free(sm->lastReqData); 662 sm->lastReqData = NULL; 663 if (sm->eap_if.eapKeyData) 664 sm->eap_if.eapKeyAvailable = TRUE; 665 sm->eap_if.eapSuccess = TRUE; 666 667 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 668 MACSTR, MAC2STR(sm->peer_addr)); 669 } 670 671 672 SM_STATE(EAP, INITIATE_REAUTH_START) 673 { 674 SM_ENTRY(EAP, INITIATE_REAUTH_START); 675 676 sm->initiate_reauth_start_sent = TRUE; 677 sm->try_initiate_reauth = TRUE; 678 sm->currentId = eap_sm_nextId(sm, sm->currentId); 679 wpa_printf(MSG_DEBUG, 680 "EAP: building EAP-Initiate-Re-auth-Start: Identifier %d", 681 sm->currentId); 682 sm->lastId = sm->currentId; 683 wpabuf_free(sm->eap_if.eapReqData); 684 sm->eap_if.eapReqData = eap_sm_buildInitiateReauthStart(sm, 685 sm->currentId); 686 wpabuf_free(sm->lastReqData); 687 sm->lastReqData = NULL; 688 } 689 690 691 #ifdef CONFIG_ERP 692 693 static void erp_send_finish_reauth(struct eap_sm *sm, 694 struct eap_server_erp_key *erp, u8 id, 695 u8 flags, u16 seq, const char *nai) 696 { 697 size_t plen; 698 struct wpabuf *msg; 699 u8 hash[SHA256_MAC_LEN]; 700 size_t hash_len; 701 u8 seed[4]; 702 703 if (erp) { 704 switch (erp->cryptosuite) { 705 case EAP_ERP_CS_HMAC_SHA256_256: 706 hash_len = 32; 707 break; 708 case EAP_ERP_CS_HMAC_SHA256_128: 709 hash_len = 16; 710 break; 711 default: 712 return; 713 } 714 } else 715 hash_len = 0; 716 717 plen = 1 + 2 + 2 + os_strlen(nai); 718 if (hash_len) 719 plen += 1 + hash_len; 720 msg = eap_msg_alloc(EAP_VENDOR_IETF, (EapType) EAP_ERP_TYPE_REAUTH, 721 plen, EAP_CODE_FINISH, id); 722 if (msg == NULL) 723 return; 724 wpabuf_put_u8(msg, flags); 725 wpabuf_put_be16(msg, seq); 726 727 wpabuf_put_u8(msg, EAP_ERP_TLV_KEYNAME_NAI); 728 wpabuf_put_u8(msg, os_strlen(nai)); 729 wpabuf_put_str(msg, nai); 730 731 if (erp) { 732 wpabuf_put_u8(msg, erp->cryptosuite); 733 if (hmac_sha256(erp->rIK, erp->rIK_len, 734 wpabuf_head(msg), wpabuf_len(msg), hash) < 0) { 735 wpabuf_free(msg); 736 return; 737 } 738 wpabuf_put_data(msg, hash, hash_len); 739 } 740 741 wpa_printf(MSG_DEBUG, "EAP: Send EAP-Finish/Re-auth (%s)", 742 flags & 0x80 ? "failure" : "success"); 743 744 sm->lastId = sm->currentId; 745 sm->currentId = id; 746 wpabuf_free(sm->eap_if.eapReqData); 747 sm->eap_if.eapReqData = msg; 748 wpabuf_free(sm->lastReqData); 749 sm->lastReqData = NULL; 750 751 if ((flags & 0x80) || !erp) { 752 sm->eap_if.eapFail = TRUE; 753 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 754 MACSTR, MAC2STR(sm->peer_addr)); 755 return; 756 } 757 758 bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); 759 sm->eap_if.eapKeyDataLen = 0; 760 sm->eap_if.eapKeyData = os_malloc(erp->rRK_len); 761 if (!sm->eap_if.eapKeyData) 762 return; 763 764 WPA_PUT_BE16(seed, seq); 765 WPA_PUT_BE16(&seed[2], erp->rRK_len); 766 if (hmac_sha256_kdf(erp->rRK, erp->rRK_len, 767 "Re-authentication Master Session Key (at) ietf.org", 768 seed, sizeof(seed), 769 sm->eap_if.eapKeyData, erp->rRK_len) < 0) { 770 wpa_printf(MSG_DEBUG, "EAP: Could not derive rMSK for ERP"); 771 bin_clear_free(sm->eap_if.eapKeyData, erp->rRK_len); 772 sm->eap_if.eapKeyData = NULL; 773 return; 774 } 775 sm->eap_if.eapKeyDataLen = erp->rRK_len; 776 sm->eap_if.eapKeyAvailable = TRUE; 777 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rMSK", 778 sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); 779 sm->eap_if.eapSuccess = TRUE; 780 781 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 782 MACSTR, MAC2STR(sm->peer_addr)); 783 } 784 785 786 SM_STATE(EAP, INITIATE_RECEIVED) 787 { 788 const u8 *pos, *end, *start, *tlvs, *hdr; 789 const struct eap_hdr *ehdr; 790 size_t len; 791 u8 flags; 792 u16 seq; 793 char nai[254]; 794 struct eap_server_erp_key *erp; 795 int max_len; 796 u8 hash[SHA256_MAC_LEN]; 797 size_t hash_len; 798 struct erp_tlvs parse; 799 u8 resp_flags = 0x80; /* default to failure; cleared on success */ 800 801 SM_ENTRY(EAP, INITIATE_RECEIVED); 802 803 sm->rxInitiate = FALSE; 804 805 pos = eap_hdr_validate(EAP_VENDOR_IETF, (EapType) EAP_ERP_TYPE_REAUTH, 806 sm->eap_if.eapRespData, &len); 807 if (pos == NULL) { 808 wpa_printf(MSG_INFO, "EAP-Initiate: Invalid frame"); 809 goto fail; 810 } 811 hdr = wpabuf_head(sm->eap_if.eapRespData); 812 ehdr = wpabuf_head(sm->eap_if.eapRespData); 813 814 wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-Auth", pos, len); 815 if (len < 4) { 816 wpa_printf(MSG_INFO, "EAP: Too short EAP-Initiate/Re-auth"); 817 goto fail; 818 } 819 end = pos + len; 820 821 flags = *pos++; 822 seq = WPA_GET_BE16(pos); 823 pos += 2; 824 wpa_printf(MSG_DEBUG, "EAP: Flags=0x%x SEQ=%u", flags, seq); 825 tlvs = pos; 826 827 /* 828 * Parse TVs/TLVs. Since we do not yet know the length of the 829 * Authentication Tag, stop parsing if an unknown TV/TLV is seen and 830 * just try to find the keyName-NAI first so that we can check the 831 * Authentication Tag. 832 */ 833 if (erp_parse_tlvs(tlvs, end, &parse, 1) < 0) 834 goto fail; 835 836 if (!parse.keyname) { 837 wpa_printf(MSG_DEBUG, 838 "EAP: No keyName-NAI in EAP-Initiate/Re-auth Packet"); 839 goto fail; 840 } 841 842 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Initiate/Re-auth - keyName-NAI", 843 parse.keyname, parse.keyname_len); 844 if (parse.keyname_len > 253) { 845 wpa_printf(MSG_DEBUG, 846 "EAP: Too long keyName-NAI in EAP-Initiate/Re-auth"); 847 goto fail; 848 } 849 os_memcpy(nai, parse.keyname, parse.keyname_len); 850 nai[parse.keyname_len] = '\0'; 851 852 if (!sm->eap_server) { 853 /* 854 * In passthrough case, EAP-Initiate/Re-auth replaces 855 * EAP Identity exchange. Use keyName-NAI as the user identity 856 * and forward EAP-Initiate/Re-auth to the backend 857 * authentication server. 858 */ 859 wpa_printf(MSG_DEBUG, 860 "EAP: Use keyName-NAI as user identity for backend authentication"); 861 eap_server_clear_identity(sm); 862 sm->identity = (u8 *) dup_binstr(parse.keyname, 863 parse.keyname_len); 864 if (!sm->identity) 865 goto fail; 866 sm->identity_len = parse.keyname_len; 867 return; 868 } 869 870 erp = eap_erp_get_key(sm, nai); 871 if (!erp) { 872 wpa_printf(MSG_DEBUG, "EAP: No matching ERP key found for %s", 873 nai); 874 goto report_error; 875 } 876 877 if (erp->recv_seq != (u32) -1 && erp->recv_seq >= seq) { 878 wpa_printf(MSG_DEBUG, 879 "EAP: SEQ=%u replayed (already received SEQ=%u)", 880 seq, erp->recv_seq); 881 goto fail; 882 } 883 884 /* Is there enough room for Cryptosuite and Authentication Tag? */ 885 start = parse.keyname + parse.keyname_len; 886 max_len = end - start; 887 if (max_len < 888 1 + (erp->cryptosuite == EAP_ERP_CS_HMAC_SHA256_256 ? 32 : 16)) { 889 wpa_printf(MSG_DEBUG, 890 "EAP: Not enough room for Authentication Tag"); 891 goto fail; 892 } 893 894 switch (erp->cryptosuite) { 895 case EAP_ERP_CS_HMAC_SHA256_256: 896 if (end[-33] != erp->cryptosuite) { 897 wpa_printf(MSG_DEBUG, 898 "EAP: Different Cryptosuite used"); 899 goto fail; 900 } 901 hash_len = 32; 902 break; 903 case EAP_ERP_CS_HMAC_SHA256_128: 904 if (end[-17] != erp->cryptosuite) { 905 wpa_printf(MSG_DEBUG, 906 "EAP: Different Cryptosuite used"); 907 goto fail; 908 } 909 hash_len = 16; 910 break; 911 default: 912 hash_len = 0; 913 break; 914 } 915 916 if (hash_len) { 917 if (hmac_sha256(erp->rIK, erp->rIK_len, hdr, 918 end - hdr - hash_len, hash) < 0) 919 goto fail; 920 if (os_memcmp(end - hash_len, hash, hash_len) != 0) { 921 wpa_printf(MSG_DEBUG, 922 "EAP: Authentication Tag mismatch"); 923 goto fail; 924 } 925 } 926 927 /* Check if any supported CS results in matching tag */ 928 if (!hash_len && max_len >= 1 + 32 && 929 end[-33] == EAP_ERP_CS_HMAC_SHA256_256) { 930 if (hmac_sha256(erp->rIK, erp->rIK_len, hdr, 931 end - hdr - 32, hash) < 0) 932 goto fail; 933 if (os_memcmp(end - 32, hash, 32) == 0) { 934 wpa_printf(MSG_DEBUG, 935 "EAP: Authentication Tag match using HMAC-SHA256-256"); 936 hash_len = 32; 937 erp->cryptosuite = EAP_ERP_CS_HMAC_SHA256_256; 938 } 939 } 940 941 if (!hash_len && end[-17] == EAP_ERP_CS_HMAC_SHA256_128) { 942 if (hmac_sha256(erp->rIK, erp->rIK_len, hdr, 943 end - hdr - 16, hash) < 0) 944 goto fail; 945 if (os_memcmp(end - 16, hash, 16) == 0) { 946 wpa_printf(MSG_DEBUG, 947 "EAP: Authentication Tag match using HMAC-SHA256-128"); 948 hash_len = 16; 949 erp->cryptosuite = EAP_ERP_CS_HMAC_SHA256_128; 950 } 951 } 952 953 if (!hash_len) { 954 wpa_printf(MSG_DEBUG, 955 "EAP: No supported cryptosuite matched Authentication Tag"); 956 goto fail; 957 } 958 end -= 1 + hash_len; 959 960 /* 961 * Parse TVs/TLVs again now that we know the exact part of the buffer 962 * that contains them. 963 */ 964 wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-Auth TVs/TLVs", 965 tlvs, end - tlvs); 966 if (erp_parse_tlvs(tlvs, end, &parse, 0) < 0) 967 goto fail; 968 969 wpa_printf(MSG_DEBUG, "EAP: ERP key %s SEQ updated to %u", 970 erp->keyname_nai, seq); 971 erp->recv_seq = seq; 972 resp_flags &= ~0x80; /* R=0 - success */ 973 974 report_error: 975 erp_send_finish_reauth(sm, erp, ehdr->identifier, resp_flags, seq, nai); 976 return; 977 978 fail: 979 sm->ignore = TRUE; 980 } 981 982 #endif /* CONFIG_ERP */ 983 984 985 SM_STATE(EAP, INITIALIZE_PASSTHROUGH) 986 { 987 SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH); 988 989 wpabuf_free(sm->eap_if.aaaEapRespData); 990 sm->eap_if.aaaEapRespData = NULL; 991 sm->try_initiate_reauth = FALSE; 992 } 993 994 995 SM_STATE(EAP, IDLE2) 996 { 997 SM_ENTRY(EAP, IDLE2); 998 999 sm->eap_if.retransWhile = eap_sm_calculateTimeout( 1000 sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR, 1001 sm->methodTimeout); 1002 } 1003 1004 1005 SM_STATE(EAP, RETRANSMIT2) 1006 { 1007 SM_ENTRY(EAP, RETRANSMIT2); 1008 1009 sm->retransCount++; 1010 if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) { 1011 if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0) 1012 sm->eap_if.eapReq = TRUE; 1013 } 1014 } 1015 1016 1017 SM_STATE(EAP, RECEIVED2) 1018 { 1019 SM_ENTRY(EAP, RECEIVED2); 1020 1021 /* parse rxResp, respId, respMethod */ 1022 eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 1023 } 1024 1025 1026 SM_STATE(EAP, DISCARD2) 1027 { 1028 SM_ENTRY(EAP, DISCARD2); 1029 sm->eap_if.eapResp = FALSE; 1030 sm->eap_if.eapNoReq = TRUE; 1031 } 1032 1033 1034 SM_STATE(EAP, SEND_REQUEST2) 1035 { 1036 SM_ENTRY(EAP, SEND_REQUEST2); 1037 1038 sm->retransCount = 0; 1039 if (sm->eap_if.eapReqData) { 1040 if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0) 1041 { 1042 sm->eap_if.eapResp = FALSE; 1043 sm->eap_if.eapReq = TRUE; 1044 } else { 1045 sm->eap_if.eapResp = FALSE; 1046 sm->eap_if.eapReq = FALSE; 1047 } 1048 } else { 1049 wpa_printf(MSG_INFO, "EAP: SEND_REQUEST2 - no eapReqData"); 1050 sm->eap_if.eapResp = FALSE; 1051 sm->eap_if.eapReq = FALSE; 1052 sm->eap_if.eapNoReq = TRUE; 1053 } 1054 } 1055 1056 1057 SM_STATE(EAP, AAA_REQUEST) 1058 { 1059 SM_ENTRY(EAP, AAA_REQUEST); 1060 1061 if (sm->eap_if.eapRespData == NULL) { 1062 wpa_printf(MSG_INFO, "EAP: AAA_REQUEST - no eapRespData"); 1063 return; 1064 } 1065 1066 /* 1067 * if (respMethod == IDENTITY) 1068 * aaaIdentity = eapRespData 1069 * This is already taken care of by the EAP-Identity method which 1070 * stores the identity into sm->identity. 1071 */ 1072 1073 eap_copy_buf(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData); 1074 } 1075 1076 1077 SM_STATE(EAP, AAA_RESPONSE) 1078 { 1079 SM_ENTRY(EAP, AAA_RESPONSE); 1080 1081 eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 1082 sm->currentId = eap_sm_getId(sm->eap_if.eapReqData); 1083 sm->methodTimeout = sm->eap_if.aaaMethodTimeout; 1084 } 1085 1086 1087 SM_STATE(EAP, AAA_IDLE) 1088 { 1089 SM_ENTRY(EAP, AAA_IDLE); 1090 1091 sm->eap_if.aaaFail = FALSE; 1092 sm->eap_if.aaaSuccess = FALSE; 1093 sm->eap_if.aaaEapReq = FALSE; 1094 sm->eap_if.aaaEapNoReq = FALSE; 1095 sm->eap_if.aaaEapResp = TRUE; 1096 } 1097 1098 1099 SM_STATE(EAP, TIMEOUT_FAILURE2) 1100 { 1101 SM_ENTRY(EAP, TIMEOUT_FAILURE2); 1102 1103 sm->eap_if.eapTimeout = TRUE; 1104 } 1105 1106 1107 SM_STATE(EAP, FAILURE2) 1108 { 1109 SM_ENTRY(EAP, FAILURE2); 1110 1111 eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 1112 sm->eap_if.eapFail = TRUE; 1113 } 1114 1115 1116 SM_STATE(EAP, SUCCESS2) 1117 { 1118 SM_ENTRY(EAP, SUCCESS2); 1119 1120 eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 1121 1122 sm->eap_if.eapKeyAvailable = sm->eap_if.aaaEapKeyAvailable; 1123 if (sm->eap_if.aaaEapKeyAvailable) { 1124 EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData); 1125 } else { 1126 bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); 1127 sm->eap_if.eapKeyData = NULL; 1128 sm->eap_if.eapKeyDataLen = 0; 1129 } 1130 1131 sm->eap_if.eapSuccess = TRUE; 1132 1133 /* 1134 * Start reauthentication with identity request even though we know the 1135 * previously used identity. This is needed to get reauthentication 1136 * started properly. 1137 */ 1138 sm->start_reauth = TRUE; 1139 } 1140 1141 1142 SM_STEP(EAP) 1143 { 1144 if (sm->eap_if.eapRestart && sm->eap_if.portEnabled) 1145 SM_ENTER_GLOBAL(EAP, INITIALIZE); 1146 else if (!sm->eap_if.portEnabled) 1147 SM_ENTER_GLOBAL(EAP, DISABLED); 1148 else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { 1149 if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { 1150 wpa_printf(MSG_DEBUG, "EAP: more than %d " 1151 "authentication rounds - abort", 1152 EAP_MAX_AUTH_ROUNDS); 1153 sm->num_rounds++; 1154 SM_ENTER_GLOBAL(EAP, FAILURE); 1155 } 1156 } else switch (sm->EAP_state) { 1157 case EAP_INITIALIZE: 1158 if (sm->backend_auth) { 1159 if (!sm->rxResp) 1160 SM_ENTER(EAP, SELECT_ACTION); 1161 else if (sm->rxResp && 1162 (sm->respMethod == EAP_TYPE_NAK || 1163 (sm->respMethod == EAP_TYPE_EXPANDED && 1164 sm->respVendor == EAP_VENDOR_IETF && 1165 sm->respVendorMethod == EAP_TYPE_NAK))) 1166 SM_ENTER(EAP, NAK); 1167 else 1168 SM_ENTER(EAP, PICK_UP_METHOD); 1169 } else { 1170 SM_ENTER(EAP, SELECT_ACTION); 1171 } 1172 break; 1173 case EAP_PICK_UP_METHOD: 1174 if (sm->currentMethod == EAP_TYPE_NONE) { 1175 SM_ENTER(EAP, SELECT_ACTION); 1176 } else { 1177 SM_ENTER(EAP, METHOD_RESPONSE); 1178 } 1179 break; 1180 case EAP_DISABLED: 1181 if (sm->eap_if.portEnabled) 1182 SM_ENTER(EAP, INITIALIZE); 1183 break; 1184 case EAP_IDLE: 1185 if (sm->eap_if.retransWhile == 0) { 1186 if (sm->try_initiate_reauth) { 1187 sm->try_initiate_reauth = FALSE; 1188 SM_ENTER(EAP, SELECT_ACTION); 1189 } else { 1190 SM_ENTER(EAP, RETRANSMIT); 1191 } 1192 } else if (sm->eap_if.eapResp) 1193 SM_ENTER(EAP, RECEIVED); 1194 break; 1195 case EAP_RETRANSMIT: 1196 if (sm->retransCount > sm->MaxRetrans) 1197 SM_ENTER(EAP, TIMEOUT_FAILURE); 1198 else 1199 SM_ENTER(EAP, IDLE); 1200 break; 1201 case EAP_RECEIVED: 1202 if (sm->rxResp && (sm->respId == sm->currentId) && 1203 (sm->respMethod == EAP_TYPE_NAK || 1204 (sm->respMethod == EAP_TYPE_EXPANDED && 1205 sm->respVendor == EAP_VENDOR_IETF && 1206 sm->respVendorMethod == EAP_TYPE_NAK)) 1207 && (sm->methodState == METHOD_PROPOSED)) 1208 SM_ENTER(EAP, NAK); 1209 else if (sm->rxResp && (sm->respId == sm->currentId) && 1210 ((sm->respMethod == sm->currentMethod) || 1211 (sm->respMethod == EAP_TYPE_EXPANDED && 1212 sm->respVendor == EAP_VENDOR_IETF && 1213 sm->respVendorMethod == sm->currentMethod))) 1214 SM_ENTER(EAP, INTEGRITY_CHECK); 1215 #ifdef CONFIG_ERP 1216 else if (sm->rxInitiate) 1217 SM_ENTER(EAP, INITIATE_RECEIVED); 1218 #endif /* CONFIG_ERP */ 1219 else { 1220 wpa_printf(MSG_DEBUG, "EAP: RECEIVED->DISCARD: " 1221 "rxResp=%d respId=%d currentId=%d " 1222 "respMethod=%d currentMethod=%d", 1223 sm->rxResp, sm->respId, sm->currentId, 1224 sm->respMethod, sm->currentMethod); 1225 eap_log_msg(sm, "Discard received EAP message"); 1226 SM_ENTER(EAP, DISCARD); 1227 } 1228 break; 1229 case EAP_DISCARD: 1230 SM_ENTER(EAP, IDLE); 1231 break; 1232 case EAP_SEND_REQUEST: 1233 SM_ENTER(EAP, IDLE); 1234 break; 1235 case EAP_INTEGRITY_CHECK: 1236 if (sm->ignore) 1237 SM_ENTER(EAP, DISCARD); 1238 else 1239 SM_ENTER(EAP, METHOD_RESPONSE); 1240 break; 1241 case EAP_METHOD_REQUEST: 1242 if (sm->m == NULL) { 1243 /* 1244 * This transition is not mentioned in RFC 4137, but it 1245 * is needed to handle cleanly a case where EAP method 1246 * initialization fails. 1247 */ 1248 SM_ENTER(EAP, FAILURE); 1249 break; 1250 } 1251 SM_ENTER(EAP, SEND_REQUEST); 1252 if (sm->eap_if.eapNoReq && !sm->eap_if.eapReq) { 1253 /* 1254 * This transition is not mentioned in RFC 4137, but it 1255 * is needed to handle cleanly a case where EAP method 1256 * buildReq fails. 1257 */ 1258 wpa_printf(MSG_DEBUG, 1259 "EAP: Method did not return a request"); 1260 SM_ENTER(EAP, FAILURE); 1261 break; 1262 } 1263 break; 1264 case EAP_METHOD_RESPONSE: 1265 /* 1266 * Note: Mechanism to allow EAP methods to wait while going 1267 * through pending processing is an extension to RFC 4137 1268 * which only defines the transits to SELECT_ACTION and 1269 * METHOD_REQUEST from this METHOD_RESPONSE state. 1270 */ 1271 if (sm->methodState == METHOD_END) 1272 SM_ENTER(EAP, SELECT_ACTION); 1273 else if (sm->method_pending == METHOD_PENDING_WAIT) { 1274 wpa_printf(MSG_DEBUG, "EAP: Method has pending " 1275 "processing - wait before proceeding to " 1276 "METHOD_REQUEST state"); 1277 } else if (sm->method_pending == METHOD_PENDING_CONT) { 1278 wpa_printf(MSG_DEBUG, "EAP: Method has completed " 1279 "pending processing - reprocess pending " 1280 "EAP message"); 1281 sm->method_pending = METHOD_PENDING_NONE; 1282 SM_ENTER(EAP, METHOD_RESPONSE); 1283 } else 1284 SM_ENTER(EAP, METHOD_REQUEST); 1285 break; 1286 case EAP_PROPOSE_METHOD: 1287 /* 1288 * Note: Mechanism to allow EAP methods to wait while going 1289 * through pending processing is an extension to RFC 4137 1290 * which only defines the transit to METHOD_REQUEST from this 1291 * PROPOSE_METHOD state. 1292 */ 1293 if (sm->method_pending == METHOD_PENDING_WAIT) { 1294 wpa_printf(MSG_DEBUG, "EAP: Method has pending " 1295 "processing - wait before proceeding to " 1296 "METHOD_REQUEST state"); 1297 if (sm->user_eap_method_index > 0) 1298 sm->user_eap_method_index--; 1299 } else if (sm->method_pending == METHOD_PENDING_CONT) { 1300 wpa_printf(MSG_DEBUG, "EAP: Method has completed " 1301 "pending processing - reprocess pending " 1302 "EAP message"); 1303 sm->method_pending = METHOD_PENDING_NONE; 1304 SM_ENTER(EAP, PROPOSE_METHOD); 1305 } else 1306 SM_ENTER(EAP, METHOD_REQUEST); 1307 break; 1308 case EAP_NAK: 1309 SM_ENTER(EAP, SELECT_ACTION); 1310 break; 1311 case EAP_SELECT_ACTION: 1312 if (sm->decision == DECISION_FAILURE) 1313 SM_ENTER(EAP, FAILURE); 1314 else if (sm->decision == DECISION_SUCCESS) 1315 SM_ENTER(EAP, SUCCESS); 1316 else if (sm->decision == DECISION_PASSTHROUGH) 1317 SM_ENTER(EAP, INITIALIZE_PASSTHROUGH); 1318 else if (sm->decision == DECISION_INITIATE_REAUTH_START) 1319 SM_ENTER(EAP, INITIATE_REAUTH_START); 1320 #ifdef CONFIG_ERP 1321 else if (sm->eap_server && sm->erp && sm->rxInitiate) 1322 SM_ENTER(EAP, INITIATE_RECEIVED); 1323 #endif /* CONFIG_ERP */ 1324 else 1325 SM_ENTER(EAP, PROPOSE_METHOD); 1326 break; 1327 case EAP_INITIATE_REAUTH_START: 1328 SM_ENTER(EAP, SEND_REQUEST); 1329 break; 1330 case EAP_INITIATE_RECEIVED: 1331 if (!sm->eap_server) 1332 SM_ENTER(EAP, SELECT_ACTION); 1333 break; 1334 case EAP_TIMEOUT_FAILURE: 1335 break; 1336 case EAP_FAILURE: 1337 break; 1338 case EAP_SUCCESS: 1339 break; 1340 1341 case EAP_INITIALIZE_PASSTHROUGH: 1342 if (sm->currentId == -1) 1343 SM_ENTER(EAP, AAA_IDLE); 1344 else 1345 SM_ENTER(EAP, AAA_REQUEST); 1346 break; 1347 case EAP_IDLE2: 1348 if (sm->eap_if.eapResp) 1349 SM_ENTER(EAP, RECEIVED2); 1350 else if (sm->eap_if.retransWhile == 0) 1351 SM_ENTER(EAP, RETRANSMIT2); 1352 break; 1353 case EAP_RETRANSMIT2: 1354 if (sm->retransCount > sm->MaxRetrans) 1355 SM_ENTER(EAP, TIMEOUT_FAILURE2); 1356 else 1357 SM_ENTER(EAP, IDLE2); 1358 break; 1359 case EAP_RECEIVED2: 1360 if (sm->rxResp && (sm->respId == sm->currentId)) 1361 SM_ENTER(EAP, AAA_REQUEST); 1362 else 1363 SM_ENTER(EAP, DISCARD2); 1364 break; 1365 case EAP_DISCARD2: 1366 SM_ENTER(EAP, IDLE2); 1367 break; 1368 case EAP_SEND_REQUEST2: 1369 SM_ENTER(EAP, IDLE2); 1370 break; 1371 case EAP_AAA_REQUEST: 1372 SM_ENTER(EAP, AAA_IDLE); 1373 break; 1374 case EAP_AAA_RESPONSE: 1375 SM_ENTER(EAP, SEND_REQUEST2); 1376 break; 1377 case EAP_AAA_IDLE: 1378 if (sm->eap_if.aaaFail) 1379 SM_ENTER(EAP, FAILURE2); 1380 else if (sm->eap_if.aaaSuccess) 1381 SM_ENTER(EAP, SUCCESS2); 1382 else if (sm->eap_if.aaaEapReq) 1383 SM_ENTER(EAP, AAA_RESPONSE); 1384 else if (sm->eap_if.aaaTimeout) 1385 SM_ENTER(EAP, TIMEOUT_FAILURE2); 1386 break; 1387 case EAP_TIMEOUT_FAILURE2: 1388 break; 1389 case EAP_FAILURE2: 1390 break; 1391 case EAP_SUCCESS2: 1392 break; 1393 } 1394 } 1395 1396 1397 static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount, 1398 int eapSRTT, int eapRTTVAR, 1399 int methodTimeout) 1400 { 1401 int rto, i; 1402 1403 if (sm->try_initiate_reauth) { 1404 wpa_printf(MSG_DEBUG, 1405 "EAP: retransmit timeout 1 second for EAP-Initiate-Re-auth-Start"); 1406 return 1; 1407 } 1408 1409 if (methodTimeout) { 1410 /* 1411 * EAP method (either internal or through AAA server, provided 1412 * timeout hint. Use that as-is as a timeout for retransmitting 1413 * the EAP request if no response is received. 1414 */ 1415 wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds " 1416 "(from EAP method hint)", methodTimeout); 1417 return methodTimeout; 1418 } 1419 1420 /* 1421 * RFC 3748 recommends algorithms described in RFC 2988 for estimation 1422 * of the retransmission timeout. This should be implemented once 1423 * round-trip time measurements are available. For nowm a simple 1424 * backoff mechanism is used instead if there are no EAP method 1425 * specific hints. 1426 * 1427 * SRTT = smoothed round-trip time 1428 * RTTVAR = round-trip time variation 1429 * RTO = retransmission timeout 1430 */ 1431 1432 /* 1433 * RFC 2988, 2.1: before RTT measurement, set RTO to 3 seconds for 1434 * initial retransmission and then double the RTO to provide back off 1435 * per 5.5. Limit the maximum RTO to 20 seconds per RFC 3748, 4.3 1436 * modified RTOmax. 1437 */ 1438 rto = 3; 1439 for (i = 0; i < retransCount; i++) { 1440 rto *= 2; 1441 if (rto >= 20) { 1442 rto = 20; 1443 break; 1444 } 1445 } 1446 1447 wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds " 1448 "(from dynamic back off; retransCount=%d)", 1449 rto, retransCount); 1450 1451 return rto; 1452 } 1453 1454 1455 static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp) 1456 { 1457 const struct eap_hdr *hdr; 1458 size_t plen; 1459 1460 /* parse rxResp, respId, respMethod */ 1461 sm->rxResp = FALSE; 1462 sm->rxInitiate = FALSE; 1463 sm->respId = -1; 1464 sm->respMethod = EAP_TYPE_NONE; 1465 sm->respVendor = EAP_VENDOR_IETF; 1466 sm->respVendorMethod = EAP_TYPE_NONE; 1467 1468 if (resp == NULL || wpabuf_len(resp) < sizeof(*hdr)) { 1469 wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p " 1470 "len=%lu", resp, 1471 resp ? (unsigned long) wpabuf_len(resp) : 0); 1472 return; 1473 } 1474 1475 hdr = wpabuf_head(resp); 1476 plen = be_to_host16(hdr->length); 1477 if (plen > wpabuf_len(resp)) { 1478 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet " 1479 "(len=%lu plen=%lu)", 1480 (unsigned long) wpabuf_len(resp), 1481 (unsigned long) plen); 1482 return; 1483 } 1484 1485 sm->respId = hdr->identifier; 1486 1487 if (hdr->code == EAP_CODE_RESPONSE) 1488 sm->rxResp = TRUE; 1489 else if (hdr->code == EAP_CODE_INITIATE) 1490 sm->rxInitiate = TRUE; 1491 1492 if (plen > sizeof(*hdr)) { 1493 u8 *pos = (u8 *) (hdr + 1); 1494 sm->respMethod = *pos++; 1495 if (sm->respMethod == EAP_TYPE_EXPANDED) { 1496 if (plen < sizeof(*hdr) + 8) { 1497 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated " 1498 "expanded EAP-Packet (plen=%lu)", 1499 (unsigned long) plen); 1500 return; 1501 } 1502 sm->respVendor = WPA_GET_BE24(pos); 1503 pos += 3; 1504 sm->respVendorMethod = WPA_GET_BE32(pos); 1505 } 1506 } 1507 1508 wpa_printf(MSG_DEBUG, 1509 "EAP: parseEapResp: rxResp=%d rxInitiate=%d respId=%d respMethod=%u respVendor=%u respVendorMethod=%u", 1510 sm->rxResp, sm->rxInitiate, sm->respId, sm->respMethod, 1511 sm->respVendor, sm->respVendorMethod); 1512 } 1513 1514 1515 static int eap_sm_getId(const struct wpabuf *data) 1516 { 1517 const struct eap_hdr *hdr; 1518 1519 if (data == NULL || wpabuf_len(data) < sizeof(*hdr)) 1520 return -1; 1521 1522 hdr = wpabuf_head(data); 1523 wpa_printf(MSG_DEBUG, "EAP: getId: id=%d", hdr->identifier); 1524 return hdr->identifier; 1525 } 1526 1527 1528 static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id) 1529 { 1530 struct wpabuf *msg; 1531 struct eap_hdr *resp; 1532 wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (id=%d)", id); 1533 1534 msg = wpabuf_alloc(sizeof(*resp)); 1535 if (msg == NULL) 1536 return NULL; 1537 resp = wpabuf_put(msg, sizeof(*resp)); 1538 resp->code = EAP_CODE_SUCCESS; 1539 resp->identifier = id; 1540 resp->length = host_to_be16(sizeof(*resp)); 1541 1542 return msg; 1543 } 1544 1545 1546 static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id) 1547 { 1548 struct wpabuf *msg; 1549 struct eap_hdr *resp; 1550 wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id); 1551 1552 msg = wpabuf_alloc(sizeof(*resp)); 1553 if (msg == NULL) 1554 return NULL; 1555 resp = wpabuf_put(msg, sizeof(*resp)); 1556 resp->code = EAP_CODE_FAILURE; 1557 resp->identifier = id; 1558 resp->length = host_to_be16(sizeof(*resp)); 1559 1560 return msg; 1561 } 1562 1563 1564 static int eap_sm_nextId(struct eap_sm *sm, int id) 1565 { 1566 if (id < 0) { 1567 /* RFC 3748 Ch 4.1: recommended to initialize Identifier with a 1568 * random number */ 1569 id = rand() & 0xff; 1570 if (id != sm->lastId) 1571 return id; 1572 } 1573 return (id + 1) & 0xff; 1574 } 1575 1576 1577 /** 1578 * eap_sm_process_nak - Process EAP-Response/Nak 1579 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1580 * @nak_list: Nak list (allowed methods) from the supplicant 1581 * @len: Length of nak_list in bytes 1582 * 1583 * This function is called when EAP-Response/Nak is received from the 1584 * supplicant. This can happen for both phase 1 and phase 2 authentications. 1585 */ 1586 void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len) 1587 { 1588 int i; 1589 size_t j; 1590 1591 if (sm->user == NULL) 1592 return; 1593 1594 wpa_printf(MSG_MSGDUMP, "EAP: processing NAK (current EAP method " 1595 "index %d)", sm->user_eap_method_index); 1596 1597 wpa_hexdump(MSG_MSGDUMP, "EAP: configured methods", 1598 (u8 *) sm->user->methods, 1599 EAP_MAX_METHODS * sizeof(sm->user->methods[0])); 1600 wpa_hexdump(MSG_MSGDUMP, "EAP: list of methods supported by the peer", 1601 nak_list, len); 1602 1603 i = sm->user_eap_method_index; 1604 while (i < EAP_MAX_METHODS && 1605 (sm->user->methods[i].vendor != EAP_VENDOR_IETF || 1606 sm->user->methods[i].method != EAP_TYPE_NONE)) { 1607 if (sm->user->methods[i].vendor != EAP_VENDOR_IETF) 1608 goto not_found; 1609 for (j = 0; j < len; j++) { 1610 if (nak_list[j] == sm->user->methods[i].method) { 1611 break; 1612 } 1613 } 1614 1615 if (j < len) { 1616 /* found */ 1617 i++; 1618 continue; 1619 } 1620 1621 not_found: 1622 /* not found - remove from the list */ 1623 if (i + 1 < EAP_MAX_METHODS) { 1624 os_memmove(&sm->user->methods[i], 1625 &sm->user->methods[i + 1], 1626 (EAP_MAX_METHODS - i - 1) * 1627 sizeof(sm->user->methods[0])); 1628 } 1629 sm->user->methods[EAP_MAX_METHODS - 1].vendor = 1630 EAP_VENDOR_IETF; 1631 sm->user->methods[EAP_MAX_METHODS - 1].method = EAP_TYPE_NONE; 1632 } 1633 1634 wpa_hexdump(MSG_MSGDUMP, "EAP: new list of configured methods", 1635 (u8 *) sm->user->methods, EAP_MAX_METHODS * 1636 sizeof(sm->user->methods[0])); 1637 } 1638 1639 1640 static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list, 1641 size_t len) 1642 { 1643 if (nak_list == NULL || sm == NULL || sm->user == NULL) 1644 return; 1645 1646 if (sm->user->phase2) { 1647 wpa_printf(MSG_DEBUG, "EAP: EAP-Nak received after Phase2 user" 1648 " info was selected - reject"); 1649 sm->decision = DECISION_FAILURE; 1650 return; 1651 } 1652 1653 eap_sm_process_nak(sm, nak_list, len); 1654 } 1655 1656 1657 static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor) 1658 { 1659 EapType next; 1660 int idx = sm->user_eap_method_index; 1661 1662 /* In theory, there should be no problems with starting 1663 * re-authentication with something else than EAP-Request/Identity and 1664 * this does indeed work with wpa_supplicant. However, at least Funk 1665 * Supplicant seemed to ignore re-auth if it skipped 1666 * EAP-Request/Identity. 1667 * Re-auth sets currentId == -1, so that can be used here to select 1668 * whether Identity needs to be requested again. */ 1669 if (sm->identity == NULL || sm->currentId == -1) { 1670 *vendor = EAP_VENDOR_IETF; 1671 next = EAP_TYPE_IDENTITY; 1672 sm->update_user = TRUE; 1673 } else if (sm->user && idx < EAP_MAX_METHODS && 1674 (sm->user->methods[idx].vendor != EAP_VENDOR_IETF || 1675 sm->user->methods[idx].method != EAP_TYPE_NONE)) { 1676 *vendor = sm->user->methods[idx].vendor; 1677 next = sm->user->methods[idx].method; 1678 sm->user_eap_method_index++; 1679 } else { 1680 *vendor = EAP_VENDOR_IETF; 1681 next = EAP_TYPE_NONE; 1682 } 1683 wpa_printf(MSG_DEBUG, "EAP: getNextMethod: vendor %d type %d", 1684 *vendor, next); 1685 return next; 1686 } 1687 1688 1689 static int eap_sm_Policy_getDecision(struct eap_sm *sm) 1690 { 1691 if (!sm->eap_server && sm->identity && !sm->start_reauth) { 1692 wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH"); 1693 return DECISION_PASSTHROUGH; 1694 } 1695 1696 if (sm->m && sm->currentMethod != EAP_TYPE_IDENTITY && 1697 sm->m->isSuccess(sm, sm->eap_method_priv)) { 1698 wpa_printf(MSG_DEBUG, "EAP: getDecision: method succeeded -> " 1699 "SUCCESS"); 1700 sm->update_user = TRUE; 1701 return DECISION_SUCCESS; 1702 } 1703 1704 if (sm->m && sm->m->isDone(sm, sm->eap_method_priv) && 1705 !sm->m->isSuccess(sm, sm->eap_method_priv)) { 1706 wpa_printf(MSG_DEBUG, "EAP: getDecision: method failed -> " 1707 "FAILURE"); 1708 sm->update_user = TRUE; 1709 return DECISION_FAILURE; 1710 } 1711 1712 if ((sm->user == NULL || sm->update_user) && sm->identity && 1713 !sm->start_reauth) { 1714 /* 1715 * Allow Identity method to be started once to allow identity 1716 * selection hint to be sent from the authentication server, 1717 * but prevent a loop of Identity requests by only allowing 1718 * this to happen once. 1719 */ 1720 int id_req = 0; 1721 if (sm->user && sm->currentMethod == EAP_TYPE_IDENTITY && 1722 sm->user->methods[0].vendor == EAP_VENDOR_IETF && 1723 sm->user->methods[0].method == EAP_TYPE_IDENTITY) 1724 id_req = 1; 1725 if (eap_user_get(sm, sm->identity, sm->identity_len, 0) != 0) { 1726 wpa_printf(MSG_DEBUG, "EAP: getDecision: user not " 1727 "found from database -> FAILURE"); 1728 return DECISION_FAILURE; 1729 } 1730 if (id_req && sm->user && 1731 sm->user->methods[0].vendor == EAP_VENDOR_IETF && 1732 sm->user->methods[0].method == EAP_TYPE_IDENTITY) { 1733 wpa_printf(MSG_DEBUG, "EAP: getDecision: stop " 1734 "identity request loop -> FAILURE"); 1735 sm->update_user = TRUE; 1736 return DECISION_FAILURE; 1737 } 1738 sm->update_user = FALSE; 1739 } 1740 sm->start_reauth = FALSE; 1741 1742 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && 1743 (sm->user->methods[sm->user_eap_method_index].vendor != 1744 EAP_VENDOR_IETF || 1745 sm->user->methods[sm->user_eap_method_index].method != 1746 EAP_TYPE_NONE)) { 1747 wpa_printf(MSG_DEBUG, "EAP: getDecision: another method " 1748 "available -> CONTINUE"); 1749 return DECISION_CONTINUE; 1750 } 1751 1752 if (!sm->identity && eap_get_erp_send_reauth_start(sm) && 1753 !sm->initiate_reauth_start_sent) { 1754 wpa_printf(MSG_DEBUG, 1755 "EAP: getDecision: send EAP-Initiate/Re-auth-Start"); 1756 return DECISION_INITIATE_REAUTH_START; 1757 } 1758 1759 if (sm->identity == NULL || sm->currentId == -1) { 1760 wpa_printf(MSG_DEBUG, "EAP: getDecision: no identity known " 1761 "yet -> CONTINUE"); 1762 return DECISION_CONTINUE; 1763 } 1764 1765 wpa_printf(MSG_DEBUG, "EAP: getDecision: no more methods available -> " 1766 "FAILURE"); 1767 return DECISION_FAILURE; 1768 } 1769 1770 1771 static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method) 1772 { 1773 return method == EAP_TYPE_IDENTITY ? TRUE : FALSE; 1774 } 1775 1776 1777 /** 1778 * eap_server_sm_step - Step EAP server state machine 1779 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1780 * Returns: 1 if EAP state was changed or 0 if not 1781 * 1782 * This function advances EAP state machine to a new state to match with the 1783 * current variables. This should be called whenever variables used by the EAP 1784 * state machine have changed. 1785 */ 1786 int eap_server_sm_step(struct eap_sm *sm) 1787 { 1788 int res = 0; 1789 do { 1790 sm->changed = FALSE; 1791 SM_STEP_RUN(EAP); 1792 if (sm->changed) 1793 res = 1; 1794 } while (sm->changed); 1795 return res; 1796 } 1797 1798 1799 static void eap_user_free(struct eap_user *user) 1800 { 1801 if (user == NULL) 1802 return; 1803 bin_clear_free(user->password, user->password_len); 1804 user->password = NULL; 1805 os_free(user); 1806 } 1807 1808 1809 /** 1810 * eap_server_sm_init - Allocate and initialize EAP server state machine 1811 * @eapol_ctx: Context data to be used with eapol_cb calls 1812 * @eapol_cb: Pointer to EAPOL callback functions 1813 * @conf: EAP configuration 1814 * Returns: Pointer to the allocated EAP state machine or %NULL on failure 1815 * 1816 * This function allocates and initializes an EAP state machine. 1817 */ 1818 struct eap_sm * eap_server_sm_init(void *eapol_ctx, 1819 const struct eapol_callbacks *eapol_cb, 1820 struct eap_config *conf) 1821 { 1822 struct eap_sm *sm; 1823 1824 sm = os_zalloc(sizeof(*sm)); 1825 if (sm == NULL) 1826 return NULL; 1827 sm->eapol_ctx = eapol_ctx; 1828 sm->eapol_cb = eapol_cb; 1829 sm->MaxRetrans = 5; /* RFC 3748: max 3-5 retransmissions suggested */ 1830 sm->ssl_ctx = conf->ssl_ctx; 1831 sm->msg_ctx = conf->msg_ctx; 1832 sm->eap_sim_db_priv = conf->eap_sim_db_priv; 1833 sm->backend_auth = conf->backend_auth; 1834 sm->eap_server = conf->eap_server; 1835 if (conf->pac_opaque_encr_key) { 1836 sm->pac_opaque_encr_key = os_malloc(16); 1837 if (sm->pac_opaque_encr_key) { 1838 os_memcpy(sm->pac_opaque_encr_key, 1839 conf->pac_opaque_encr_key, 16); 1840 } 1841 } 1842 if (conf->eap_fast_a_id) { 1843 sm->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len); 1844 if (sm->eap_fast_a_id) { 1845 os_memcpy(sm->eap_fast_a_id, conf->eap_fast_a_id, 1846 conf->eap_fast_a_id_len); 1847 sm->eap_fast_a_id_len = conf->eap_fast_a_id_len; 1848 } 1849 } 1850 if (conf->eap_fast_a_id_info) 1851 sm->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info); 1852 sm->eap_fast_prov = conf->eap_fast_prov; 1853 sm->pac_key_lifetime = conf->pac_key_lifetime; 1854 sm->pac_key_refresh_time = conf->pac_key_refresh_time; 1855 sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; 1856 sm->tnc = conf->tnc; 1857 sm->wps = conf->wps; 1858 if (conf->assoc_wps_ie) 1859 sm->assoc_wps_ie = wpabuf_dup(conf->assoc_wps_ie); 1860 if (conf->assoc_p2p_ie) 1861 sm->assoc_p2p_ie = wpabuf_dup(conf->assoc_p2p_ie); 1862 if (conf->peer_addr) 1863 os_memcpy(sm->peer_addr, conf->peer_addr, ETH_ALEN); 1864 sm->fragment_size = conf->fragment_size; 1865 sm->pwd_group = conf->pwd_group; 1866 sm->pbc_in_m1 = conf->pbc_in_m1; 1867 sm->server_id = conf->server_id; 1868 sm->server_id_len = conf->server_id_len; 1869 sm->erp = conf->erp; 1870 sm->tls_session_lifetime = conf->tls_session_lifetime; 1871 sm->tls_flags = conf->tls_flags; 1872 1873 #ifdef CONFIG_TESTING_OPTIONS 1874 sm->tls_test_flags = conf->tls_test_flags; 1875 #endif /* CONFIG_TESTING_OPTIONS */ 1876 1877 wpa_printf(MSG_DEBUG, "EAP: Server state machine created"); 1878 1879 return sm; 1880 } 1881 1882 1883 /** 1884 * eap_server_sm_deinit - Deinitialize and free an EAP server state machine 1885 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1886 * 1887 * This function deinitializes EAP state machine and frees all allocated 1888 * resources. 1889 */ 1890 void eap_server_sm_deinit(struct eap_sm *sm) 1891 { 1892 if (sm == NULL) 1893 return; 1894 wpa_printf(MSG_DEBUG, "EAP: Server state machine removed"); 1895 if (sm->m && sm->eap_method_priv) 1896 sm->m->reset(sm, sm->eap_method_priv); 1897 wpabuf_free(sm->eap_if.eapReqData); 1898 bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); 1899 os_free(sm->eap_if.eapSessionId); 1900 wpabuf_free(sm->lastReqData); 1901 wpabuf_free(sm->eap_if.eapRespData); 1902 os_free(sm->identity); 1903 os_free(sm->pac_opaque_encr_key); 1904 os_free(sm->eap_fast_a_id); 1905 os_free(sm->eap_fast_a_id_info); 1906 wpabuf_free(sm->eap_if.aaaEapReqData); 1907 wpabuf_free(sm->eap_if.aaaEapRespData); 1908 bin_clear_free(sm->eap_if.aaaEapKeyData, sm->eap_if.aaaEapKeyDataLen); 1909 eap_user_free(sm->user); 1910 wpabuf_free(sm->assoc_wps_ie); 1911 wpabuf_free(sm->assoc_p2p_ie); 1912 os_free(sm); 1913 } 1914 1915 1916 /** 1917 * eap_sm_notify_cached - Notify EAP state machine of cached PMK 1918 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1919 * 1920 * This function is called when PMKSA caching is used to skip EAP 1921 * authentication. 1922 */ 1923 void eap_sm_notify_cached(struct eap_sm *sm) 1924 { 1925 if (sm == NULL) 1926 return; 1927 1928 sm->EAP_state = EAP_SUCCESS; 1929 } 1930 1931 1932 /** 1933 * eap_sm_pending_cb - EAP state machine callback for a pending EAP request 1934 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1935 * 1936 * This function is called when data for a pending EAP-Request is received. 1937 */ 1938 void eap_sm_pending_cb(struct eap_sm *sm) 1939 { 1940 if (sm == NULL) 1941 return; 1942 wpa_printf(MSG_DEBUG, "EAP: Callback for pending request received"); 1943 if (sm->method_pending == METHOD_PENDING_WAIT) 1944 sm->method_pending = METHOD_PENDING_CONT; 1945 } 1946 1947 1948 /** 1949 * eap_sm_method_pending - Query whether EAP method is waiting for pending data 1950 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1951 * Returns: 1 if method is waiting for pending data or 0 if not 1952 */ 1953 int eap_sm_method_pending(struct eap_sm *sm) 1954 { 1955 if (sm == NULL) 1956 return 0; 1957 return sm->method_pending == METHOD_PENDING_WAIT; 1958 } 1959 1960 1961 /** 1962 * eap_get_identity - Get the user identity (from EAP-Response/Identity) 1963 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1964 * @len: Buffer for returning identity length 1965 * Returns: Pointer to the user identity or %NULL if not available 1966 */ 1967 const u8 * eap_get_identity(struct eap_sm *sm, size_t *len) 1968 { 1969 *len = sm->identity_len; 1970 return sm->identity; 1971 } 1972 1973 1974 void eap_erp_update_identity(struct eap_sm *sm, const u8 *eap, size_t len) 1975 { 1976 #ifdef CONFIG_ERP 1977 const struct eap_hdr *hdr; 1978 const u8 *pos, *end; 1979 struct erp_tlvs parse; 1980 1981 if (len < sizeof(*hdr) + 1) 1982 return; 1983 hdr = (const struct eap_hdr *) eap; 1984 end = eap + len; 1985 pos = (const u8 *) (hdr + 1); 1986 if (hdr->code != EAP_CODE_INITIATE || *pos != EAP_ERP_TYPE_REAUTH) 1987 return; 1988 pos++; 1989 if (pos + 3 > end) 1990 return; 1991 1992 /* Skip Flags and SEQ */ 1993 pos += 3; 1994 1995 if (erp_parse_tlvs(pos, end, &parse, 1) < 0 || !parse.keyname) 1996 return; 1997 wpa_hexdump_ascii(MSG_DEBUG, 1998 "EAP: Update identity based on EAP-Initiate/Re-auth keyName-NAI", 1999 parse.keyname, parse.keyname_len); 2000 os_free(sm->identity); 2001 sm->identity = os_malloc(parse.keyname_len); 2002 if (sm->identity) { 2003 os_memcpy(sm->identity, parse.keyname, parse.keyname_len); 2004 sm->identity_len = parse.keyname_len; 2005 } else { 2006 sm->identity_len = 0; 2007 } 2008 #endif /* CONFIG_ERP */ 2009 } 2010 2011 2012 /** 2013 * eap_get_interface - Get pointer to EAP-EAPOL interface data 2014 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 2015 * Returns: Pointer to the EAP-EAPOL interface data 2016 */ 2017 struct eap_eapol_interface * eap_get_interface(struct eap_sm *sm) 2018 { 2019 return &sm->eap_if; 2020 } 2021 2022 2023 /** 2024 * eap_server_clear_identity - Clear EAP identity information 2025 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 2026 * 2027 * This function can be used to clear the EAP identity information in the EAP 2028 * server context. This allows the EAP/Identity method to be used again after 2029 * EAPOL-Start or EAPOL-Logoff. 2030 */ 2031 void eap_server_clear_identity(struct eap_sm *sm) 2032 { 2033 os_free(sm->identity); 2034 sm->identity = NULL; 2035 } 2036 2037 2038 #ifdef CONFIG_TESTING_OPTIONS 2039 void eap_server_mschap_rx_callback(struct eap_sm *sm, const char *source, 2040 const u8 *username, size_t username_len, 2041 const u8 *challenge, const u8 *response) 2042 { 2043 char hex_challenge[30], hex_response[90], user[100]; 2044 2045 /* Print out Challenge and Response in format supported by asleap. */ 2046 if (username) 2047 printf_encode(user, sizeof(user), username, username_len); 2048 else 2049 user[0] = '\0'; 2050 wpa_snprintf_hex_sep(hex_challenge, sizeof(hex_challenge), 2051 challenge, sizeof(challenge), ':'); 2052 wpa_snprintf_hex_sep(hex_response, sizeof(hex_response), response, 24, 2053 ':'); 2054 wpa_printf(MSG_DEBUG, "[%s/user=%s] asleap -C %s -R %s", 2055 source, user, hex_challenge, hex_response); 2056 } 2057 #endif /* CONFIG_TESTING_OPTIONS */ 2058