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