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 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 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_RETRANSMIT MACSTR, 331 MAC2STR(sm->peer_addr)); 332 } 333 334 335 SM_STATE(EAP, RECEIVED) 336 { 337 SM_ENTRY(EAP, RECEIVED); 338 339 /* parse rxResp, respId, respMethod */ 340 eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 341 sm->num_rounds++; 342 } 343 344 345 SM_STATE(EAP, DISCARD) 346 { 347 SM_ENTRY(EAP, DISCARD); 348 sm->eap_if.eapResp = FALSE; 349 sm->eap_if.eapNoReq = TRUE; 350 } 351 352 353 SM_STATE(EAP, SEND_REQUEST) 354 { 355 SM_ENTRY(EAP, SEND_REQUEST); 356 357 sm->retransCount = 0; 358 if (sm->eap_if.eapReqData) { 359 if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0) 360 { 361 sm->eap_if.eapResp = FALSE; 362 sm->eap_if.eapReq = TRUE; 363 } else { 364 sm->eap_if.eapResp = FALSE; 365 sm->eap_if.eapReq = FALSE; 366 } 367 } else { 368 wpa_printf(MSG_INFO, "EAP: SEND_REQUEST - no eapReqData"); 369 sm->eap_if.eapResp = FALSE; 370 sm->eap_if.eapReq = FALSE; 371 sm->eap_if.eapNoReq = TRUE; 372 } 373 } 374 375 376 SM_STATE(EAP, INTEGRITY_CHECK) 377 { 378 SM_ENTRY(EAP, INTEGRITY_CHECK); 379 380 if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) { 381 sm->ignore = TRUE; 382 return; 383 } 384 385 if (sm->m->check) { 386 sm->ignore = sm->m->check(sm, sm->eap_method_priv, 387 sm->eap_if.eapRespData); 388 } 389 } 390 391 392 SM_STATE(EAP, METHOD_REQUEST) 393 { 394 SM_ENTRY(EAP, METHOD_REQUEST); 395 396 if (sm->m == NULL) { 397 wpa_printf(MSG_DEBUG, "EAP: method not initialized"); 398 return; 399 } 400 401 sm->currentId = eap_sm_nextId(sm, sm->currentId); 402 wpa_printf(MSG_DEBUG, "EAP: building EAP-Request: Identifier %d", 403 sm->currentId); 404 sm->lastId = sm->currentId; 405 wpabuf_free(sm->eap_if.eapReqData); 406 sm->eap_if.eapReqData = sm->m->buildReq(sm, sm->eap_method_priv, 407 sm->currentId); 408 if (sm->m->getTimeout) 409 sm->methodTimeout = sm->m->getTimeout(sm, sm->eap_method_priv); 410 else 411 sm->methodTimeout = 0; 412 } 413 414 415 static void eap_server_erp_init(struct eap_sm *sm) 416 { 417 #ifdef CONFIG_ERP 418 u8 *emsk = NULL; 419 size_t emsk_len = 0; 420 u8 EMSKname[EAP_EMSK_NAME_LEN]; 421 u8 len[2], ctx[3]; 422 const char *domain; 423 size_t domain_len, nai_buf_len; 424 struct eap_server_erp_key *erp = NULL; 425 int pos; 426 427 domain = eap_get_erp_domain(sm); 428 if (!domain) 429 return; 430 431 domain_len = os_strlen(domain); 432 433 nai_buf_len = 2 * EAP_EMSK_NAME_LEN + 1 + domain_len; 434 if (nai_buf_len > 253) { 435 /* 436 * keyName-NAI has a maximum length of 253 octet to fit in 437 * RADIUS attributes. 438 */ 439 wpa_printf(MSG_DEBUG, 440 "EAP: Too long realm for ERP keyName-NAI maximum length"); 441 return; 442 } 443 nai_buf_len++; /* null termination */ 444 erp = os_zalloc(sizeof(*erp) + nai_buf_len); 445 if (erp == NULL) 446 goto fail; 447 erp->recv_seq = (u32) -1; 448 449 emsk = sm->m->get_emsk(sm, sm->eap_method_priv, &emsk_len); 450 if (!emsk || emsk_len == 0 || emsk_len > ERP_MAX_KEY_LEN) { 451 wpa_printf(MSG_DEBUG, 452 "EAP: No suitable EMSK available for ERP"); 453 goto fail; 454 } 455 456 wpa_hexdump_key(MSG_DEBUG, "EAP: EMSK", emsk, emsk_len); 457 458 WPA_PUT_BE16(len, EAP_EMSK_NAME_LEN); 459 if (hmac_sha256_kdf(sm->eap_if.eapSessionId, sm->eap_if.eapSessionIdLen, 460 "EMSK", len, sizeof(len), 461 EMSKname, EAP_EMSK_NAME_LEN) < 0) { 462 wpa_printf(MSG_DEBUG, "EAP: Could not derive EMSKname"); 463 goto fail; 464 } 465 wpa_hexdump(MSG_DEBUG, "EAP: EMSKname", EMSKname, EAP_EMSK_NAME_LEN); 466 467 pos = wpa_snprintf_hex(erp->keyname_nai, nai_buf_len, 468 EMSKname, EAP_EMSK_NAME_LEN); 469 erp->keyname_nai[pos] = '@'; 470 os_memcpy(&erp->keyname_nai[pos + 1], domain, domain_len); 471 472 WPA_PUT_BE16(len, emsk_len); 473 if (hmac_sha256_kdf(emsk, emsk_len, 474 "EAP Re-authentication Root Key@ietf.org", 475 len, sizeof(len), erp->rRK, emsk_len) < 0) { 476 wpa_printf(MSG_DEBUG, "EAP: Could not derive rRK for ERP"); 477 goto fail; 478 } 479 erp->rRK_len = emsk_len; 480 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rRK", erp->rRK, erp->rRK_len); 481 482 ctx[0] = EAP_ERP_CS_HMAC_SHA256_128; 483 WPA_PUT_BE16(&ctx[1], erp->rRK_len); 484 if (hmac_sha256_kdf(erp->rRK, erp->rRK_len, 485 "Re-authentication Integrity Key@ietf.org", 486 ctx, sizeof(ctx), erp->rIK, erp->rRK_len) < 0) { 487 wpa_printf(MSG_DEBUG, "EAP: Could not derive rIK for ERP"); 488 goto fail; 489 } 490 erp->rIK_len = erp->rRK_len; 491 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rIK", erp->rIK, erp->rIK_len); 492 493 if (eap_erp_add_key(sm, erp) == 0) { 494 wpa_printf(MSG_DEBUG, "EAP: Stored ERP keys %s", 495 erp->keyname_nai); 496 erp = NULL; 497 } 498 499 fail: 500 bin_clear_free(emsk, emsk_len); 501 bin_clear_free(erp, sizeof(*erp)); 502 #endif /* CONFIG_ERP */ 503 } 504 505 506 SM_STATE(EAP, METHOD_RESPONSE) 507 { 508 SM_ENTRY(EAP, METHOD_RESPONSE); 509 510 if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) 511 return; 512 513 sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData); 514 if (sm->m->isDone(sm, sm->eap_method_priv)) { 515 eap_sm_Policy_update(sm, NULL, 0); 516 bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); 517 if (sm->m->getKey) { 518 sm->eap_if.eapKeyData = sm->m->getKey( 519 sm, sm->eap_method_priv, 520 &sm->eap_if.eapKeyDataLen); 521 } else { 522 sm->eap_if.eapKeyData = NULL; 523 sm->eap_if.eapKeyDataLen = 0; 524 } 525 os_free(sm->eap_if.eapSessionId); 526 sm->eap_if.eapSessionId = NULL; 527 if (sm->m->getSessionId) { 528 sm->eap_if.eapSessionId = sm->m->getSessionId( 529 sm, sm->eap_method_priv, 530 &sm->eap_if.eapSessionIdLen); 531 wpa_hexdump(MSG_DEBUG, "EAP: Session-Id", 532 sm->eap_if.eapSessionId, 533 sm->eap_if.eapSessionIdLen); 534 } 535 if (sm->erp && sm->m->get_emsk && sm->eap_if.eapSessionId) 536 eap_server_erp_init(sm); 537 sm->methodState = METHOD_END; 538 } else { 539 sm->methodState = METHOD_CONTINUE; 540 } 541 } 542 543 544 SM_STATE(EAP, PROPOSE_METHOD) 545 { 546 int vendor; 547 EapType type; 548 549 SM_ENTRY(EAP, PROPOSE_METHOD); 550 551 sm->try_initiate_reauth = FALSE; 552 try_another_method: 553 type = eap_sm_Policy_getNextMethod(sm, &vendor); 554 if (vendor == EAP_VENDOR_IETF) 555 sm->currentMethod = type; 556 else 557 sm->currentMethod = EAP_TYPE_EXPANDED; 558 if (sm->m && sm->eap_method_priv) { 559 sm->m->reset(sm, sm->eap_method_priv); 560 sm->eap_method_priv = NULL; 561 } 562 sm->m = eap_server_get_eap_method(vendor, type); 563 if (sm->m) { 564 sm->eap_method_priv = sm->m->init(sm); 565 if (sm->eap_method_priv == NULL) { 566 wpa_printf(MSG_DEBUG, "EAP: Failed to initialize EAP " 567 "method %d", sm->currentMethod); 568 sm->m = NULL; 569 sm->currentMethod = EAP_TYPE_NONE; 570 goto try_another_method; 571 } 572 } 573 if (sm->m == NULL) { 574 wpa_printf(MSG_DEBUG, "EAP: Could not find suitable EAP method"); 575 eap_log_msg(sm, "Could not find suitable EAP method"); 576 sm->decision = DECISION_FAILURE; 577 return; 578 } 579 if (sm->currentMethod == EAP_TYPE_IDENTITY || 580 sm->currentMethod == EAP_TYPE_NOTIFICATION) 581 sm->methodState = METHOD_CONTINUE; 582 else 583 sm->methodState = METHOD_PROPOSED; 584 585 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 586 "vendor=%u method=%u", vendor, sm->currentMethod); 587 eap_log_msg(sm, "Propose EAP method vendor=%u method=%u", 588 vendor, sm->currentMethod); 589 } 590 591 592 SM_STATE(EAP, NAK) 593 { 594 const struct eap_hdr *nak; 595 size_t len = 0; 596 const u8 *pos; 597 const u8 *nak_list = NULL; 598 599 SM_ENTRY(EAP, NAK); 600 601 if (sm->eap_method_priv) { 602 sm->m->reset(sm, sm->eap_method_priv); 603 sm->eap_method_priv = NULL; 604 } 605 sm->m = NULL; 606 607 if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) 608 return; 609 610 nak = wpabuf_head(sm->eap_if.eapRespData); 611 if (nak && wpabuf_len(sm->eap_if.eapRespData) > sizeof(*nak)) { 612 len = be_to_host16(nak->length); 613 if (len > wpabuf_len(sm->eap_if.eapRespData)) 614 len = wpabuf_len(sm->eap_if.eapRespData); 615 pos = (const u8 *) (nak + 1); 616 len -= sizeof(*nak); 617 if (*pos == EAP_TYPE_NAK) { 618 pos++; 619 len--; 620 nak_list = pos; 621 } 622 } 623 eap_sm_Policy_update(sm, nak_list, len); 624 } 625 626 627 SM_STATE(EAP, SELECT_ACTION) 628 { 629 SM_ENTRY(EAP, SELECT_ACTION); 630 631 sm->decision = eap_sm_Policy_getDecision(sm); 632 } 633 634 635 SM_STATE(EAP, TIMEOUT_FAILURE) 636 { 637 SM_ENTRY(EAP, TIMEOUT_FAILURE); 638 639 sm->eap_if.eapTimeout = TRUE; 640 641 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TIMEOUT_FAILURE MACSTR, 642 MAC2STR(sm->peer_addr)); 643 } 644 645 646 SM_STATE(EAP, FAILURE) 647 { 648 SM_ENTRY(EAP, FAILURE); 649 650 wpabuf_free(sm->eap_if.eapReqData); 651 sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId); 652 wpabuf_free(sm->lastReqData); 653 sm->lastReqData = NULL; 654 sm->eap_if.eapFail = TRUE; 655 656 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 657 MACSTR, MAC2STR(sm->peer_addr)); 658 } 659 660 661 SM_STATE(EAP, SUCCESS) 662 { 663 SM_ENTRY(EAP, SUCCESS); 664 665 wpabuf_free(sm->eap_if.eapReqData); 666 sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId); 667 wpabuf_free(sm->lastReqData); 668 sm->lastReqData = NULL; 669 if (sm->eap_if.eapKeyData) 670 sm->eap_if.eapKeyAvailable = TRUE; 671 sm->eap_if.eapSuccess = TRUE; 672 673 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 674 MACSTR, MAC2STR(sm->peer_addr)); 675 } 676 677 678 SM_STATE(EAP, INITIATE_REAUTH_START) 679 { 680 SM_ENTRY(EAP, INITIATE_REAUTH_START); 681 682 sm->initiate_reauth_start_sent = TRUE; 683 sm->try_initiate_reauth = TRUE; 684 sm->currentId = eap_sm_nextId(sm, sm->currentId); 685 wpa_printf(MSG_DEBUG, 686 "EAP: building EAP-Initiate-Re-auth-Start: Identifier %d", 687 sm->currentId); 688 sm->lastId = sm->currentId; 689 wpabuf_free(sm->eap_if.eapReqData); 690 sm->eap_if.eapReqData = eap_sm_buildInitiateReauthStart(sm, 691 sm->currentId); 692 wpabuf_free(sm->lastReqData); 693 sm->lastReqData = NULL; 694 } 695 696 697 #ifdef CONFIG_ERP 698 699 static void erp_send_finish_reauth(struct eap_sm *sm, 700 struct eap_server_erp_key *erp, u8 id, 701 u8 flags, u16 seq, const char *nai) 702 { 703 size_t plen; 704 struct wpabuf *msg; 705 u8 hash[SHA256_MAC_LEN]; 706 size_t hash_len; 707 u8 seed[4]; 708 709 if (erp) { 710 switch (erp->cryptosuite) { 711 case EAP_ERP_CS_HMAC_SHA256_256: 712 hash_len = 32; 713 break; 714 case EAP_ERP_CS_HMAC_SHA256_128: 715 hash_len = 16; 716 break; 717 default: 718 return; 719 } 720 } else 721 hash_len = 0; 722 723 plen = 1 + 2 + 2 + os_strlen(nai); 724 if (hash_len) 725 plen += 1 + hash_len; 726 msg = eap_msg_alloc(EAP_VENDOR_IETF, (EapType) EAP_ERP_TYPE_REAUTH, 727 plen, EAP_CODE_FINISH, id); 728 if (msg == NULL) 729 return; 730 wpabuf_put_u8(msg, flags); 731 wpabuf_put_be16(msg, seq); 732 733 wpabuf_put_u8(msg, EAP_ERP_TLV_KEYNAME_NAI); 734 wpabuf_put_u8(msg, os_strlen(nai)); 735 wpabuf_put_str(msg, nai); 736 737 if (erp) { 738 wpabuf_put_u8(msg, erp->cryptosuite); 739 if (hmac_sha256(erp->rIK, erp->rIK_len, 740 wpabuf_head(msg), wpabuf_len(msg), hash) < 0) { 741 wpabuf_free(msg); 742 return; 743 } 744 wpabuf_put_data(msg, hash, hash_len); 745 } 746 747 wpa_printf(MSG_DEBUG, "EAP: Send EAP-Finish/Re-auth (%s)", 748 flags & 0x80 ? "failure" : "success"); 749 750 sm->lastId = sm->currentId; 751 sm->currentId = id; 752 wpabuf_free(sm->eap_if.eapReqData); 753 sm->eap_if.eapReqData = msg; 754 wpabuf_free(sm->lastReqData); 755 sm->lastReqData = NULL; 756 757 if ((flags & 0x80) || !erp) { 758 sm->eap_if.eapFail = TRUE; 759 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 760 MACSTR, MAC2STR(sm->peer_addr)); 761 return; 762 } 763 764 bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); 765 sm->eap_if.eapKeyDataLen = 0; 766 sm->eap_if.eapKeyData = os_malloc(erp->rRK_len); 767 if (!sm->eap_if.eapKeyData) 768 return; 769 770 WPA_PUT_BE16(seed, seq); 771 WPA_PUT_BE16(&seed[2], erp->rRK_len); 772 if (hmac_sha256_kdf(erp->rRK, erp->rRK_len, 773 "Re-authentication Master Session Key@ietf.org", 774 seed, sizeof(seed), 775 sm->eap_if.eapKeyData, erp->rRK_len) < 0) { 776 wpa_printf(MSG_DEBUG, "EAP: Could not derive rMSK for ERP"); 777 bin_clear_free(sm->eap_if.eapKeyData, erp->rRK_len); 778 sm->eap_if.eapKeyData = NULL; 779 return; 780 } 781 sm->eap_if.eapKeyDataLen = erp->rRK_len; 782 sm->eap_if.eapKeyAvailable = TRUE; 783 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rMSK", 784 sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); 785 sm->eap_if.eapSuccess = TRUE; 786 787 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 788 MACSTR, MAC2STR(sm->peer_addr)); 789 } 790 791 792 SM_STATE(EAP, INITIATE_RECEIVED) 793 { 794 const u8 *pos, *end, *start, *tlvs, *hdr; 795 const struct eap_hdr *ehdr; 796 size_t len; 797 u8 flags; 798 u16 seq; 799 char nai[254]; 800 struct eap_server_erp_key *erp; 801 int max_len; 802 u8 hash[SHA256_MAC_LEN]; 803 size_t hash_len; 804 struct erp_tlvs parse; 805 u8 resp_flags = 0x80; /* default to failure; cleared on success */ 806 807 SM_ENTRY(EAP, INITIATE_RECEIVED); 808 809 sm->rxInitiate = FALSE; 810 811 pos = eap_hdr_validate(EAP_VENDOR_IETF, (EapType) EAP_ERP_TYPE_REAUTH, 812 sm->eap_if.eapRespData, &len); 813 if (pos == NULL) { 814 wpa_printf(MSG_INFO, "EAP-Initiate: Invalid frame"); 815 goto fail; 816 } 817 hdr = wpabuf_head(sm->eap_if.eapRespData); 818 ehdr = wpabuf_head(sm->eap_if.eapRespData); 819 820 wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-Auth", pos, len); 821 if (len < 4) { 822 wpa_printf(MSG_INFO, "EAP: Too short EAP-Initiate/Re-auth"); 823 goto fail; 824 } 825 end = pos + len; 826 827 flags = *pos++; 828 seq = WPA_GET_BE16(pos); 829 pos += 2; 830 wpa_printf(MSG_DEBUG, "EAP: Flags=0x%x SEQ=%u", flags, seq); 831 tlvs = pos; 832 833 /* 834 * Parse TVs/TLVs. Since we do not yet know the length of the 835 * Authentication Tag, stop parsing if an unknown TV/TLV is seen and 836 * just try to find the keyName-NAI first so that we can check the 837 * Authentication Tag. 838 */ 839 if (erp_parse_tlvs(tlvs, end, &parse, 1) < 0) 840 goto fail; 841 842 if (!parse.keyname) { 843 wpa_printf(MSG_DEBUG, 844 "EAP: No keyName-NAI in EAP-Initiate/Re-auth Packet"); 845 goto fail; 846 } 847 848 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Initiate/Re-auth - keyName-NAI", 849 parse.keyname, parse.keyname_len); 850 if (parse.keyname_len > 253) { 851 wpa_printf(MSG_DEBUG, 852 "EAP: Too long keyName-NAI in EAP-Initiate/Re-auth"); 853 goto fail; 854 } 855 os_memcpy(nai, parse.keyname, parse.keyname_len); 856 nai[parse.keyname_len] = '\0'; 857 858 if (!sm->eap_server) { 859 /* 860 * In passthrough case, EAP-Initiate/Re-auth replaces 861 * EAP Identity exchange. Use keyName-NAI as the user identity 862 * and forward EAP-Initiate/Re-auth to the backend 863 * authentication server. 864 */ 865 wpa_printf(MSG_DEBUG, 866 "EAP: Use keyName-NAI as user identity for backend authentication"); 867 eap_server_clear_identity(sm); 868 sm->identity = (u8 *) dup_binstr(parse.keyname, 869 parse.keyname_len); 870 if (!sm->identity) 871 goto fail; 872 sm->identity_len = parse.keyname_len; 873 return; 874 } 875 876 erp = eap_erp_get_key(sm, nai); 877 if (!erp) { 878 wpa_printf(MSG_DEBUG, "EAP: No matching ERP key found for %s", 879 nai); 880 goto report_error; 881 } 882 883 if (erp->recv_seq != (u32) -1 && erp->recv_seq >= seq) { 884 wpa_printf(MSG_DEBUG, 885 "EAP: SEQ=%u replayed (already received SEQ=%u)", 886 seq, erp->recv_seq); 887 goto fail; 888 } 889 890 /* Is there enough room for Cryptosuite and Authentication Tag? */ 891 start = parse.keyname + parse.keyname_len; 892 max_len = end - start; 893 if (max_len < 894 1 + (erp->cryptosuite == EAP_ERP_CS_HMAC_SHA256_256 ? 32 : 16)) { 895 wpa_printf(MSG_DEBUG, 896 "EAP: Not enough room for Authentication Tag"); 897 goto fail; 898 } 899 900 switch (erp->cryptosuite) { 901 case EAP_ERP_CS_HMAC_SHA256_256: 902 if (end[-33] != erp->cryptosuite) { 903 wpa_printf(MSG_DEBUG, 904 "EAP: Different Cryptosuite used"); 905 goto fail; 906 } 907 hash_len = 32; 908 break; 909 case EAP_ERP_CS_HMAC_SHA256_128: 910 if (end[-17] != erp->cryptosuite) { 911 wpa_printf(MSG_DEBUG, 912 "EAP: Different Cryptosuite used"); 913 goto fail; 914 } 915 hash_len = 16; 916 break; 917 default: 918 hash_len = 0; 919 break; 920 } 921 922 if (hash_len) { 923 if (hmac_sha256(erp->rIK, erp->rIK_len, hdr, 924 end - hdr - hash_len, hash) < 0) 925 goto fail; 926 if (os_memcmp(end - hash_len, hash, hash_len) != 0) { 927 wpa_printf(MSG_DEBUG, 928 "EAP: Authentication Tag mismatch"); 929 goto fail; 930 } 931 } 932 933 /* Check if any supported CS results in matching tag */ 934 if (!hash_len && max_len >= 1 + 32 && 935 end[-33] == EAP_ERP_CS_HMAC_SHA256_256) { 936 if (hmac_sha256(erp->rIK, erp->rIK_len, hdr, 937 end - hdr - 32, hash) < 0) 938 goto fail; 939 if (os_memcmp(end - 32, hash, 32) == 0) { 940 wpa_printf(MSG_DEBUG, 941 "EAP: Authentication Tag match using HMAC-SHA256-256"); 942 hash_len = 32; 943 erp->cryptosuite = EAP_ERP_CS_HMAC_SHA256_256; 944 } 945 } 946 947 if (!hash_len && end[-17] == EAP_ERP_CS_HMAC_SHA256_128) { 948 if (hmac_sha256(erp->rIK, erp->rIK_len, hdr, 949 end - hdr - 16, hash) < 0) 950 goto fail; 951 if (os_memcmp(end - 16, hash, 16) == 0) { 952 wpa_printf(MSG_DEBUG, 953 "EAP: Authentication Tag match using HMAC-SHA256-128"); 954 hash_len = 16; 955 erp->cryptosuite = EAP_ERP_CS_HMAC_SHA256_128; 956 } 957 } 958 959 if (!hash_len) { 960 wpa_printf(MSG_DEBUG, 961 "EAP: No supported cryptosuite matched Authentication Tag"); 962 goto fail; 963 } 964 end -= 1 + hash_len; 965 966 /* 967 * Parse TVs/TLVs again now that we know the exact part of the buffer 968 * that contains them. 969 */ 970 wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-Auth TVs/TLVs", 971 tlvs, end - tlvs); 972 if (erp_parse_tlvs(tlvs, end, &parse, 0) < 0) 973 goto fail; 974 975 wpa_printf(MSG_DEBUG, "EAP: ERP key %s SEQ updated to %u", 976 erp->keyname_nai, seq); 977 erp->recv_seq = seq; 978 resp_flags &= ~0x80; /* R=0 - success */ 979 980 report_error: 981 erp_send_finish_reauth(sm, erp, ehdr->identifier, resp_flags, seq, nai); 982 return; 983 984 fail: 985 sm->ignore = TRUE; 986 } 987 988 #endif /* CONFIG_ERP */ 989 990 991 SM_STATE(EAP, INITIALIZE_PASSTHROUGH) 992 { 993 SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH); 994 995 wpabuf_free(sm->eap_if.aaaEapRespData); 996 sm->eap_if.aaaEapRespData = NULL; 997 sm->try_initiate_reauth = FALSE; 998 } 999 1000 1001 SM_STATE(EAP, IDLE2) 1002 { 1003 SM_ENTRY(EAP, IDLE2); 1004 1005 sm->eap_if.retransWhile = eap_sm_calculateTimeout( 1006 sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR, 1007 sm->methodTimeout); 1008 } 1009 1010 1011 SM_STATE(EAP, RETRANSMIT2) 1012 { 1013 SM_ENTRY(EAP, RETRANSMIT2); 1014 1015 sm->retransCount++; 1016 if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) { 1017 if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0) 1018 sm->eap_if.eapReq = TRUE; 1019 } 1020 1021 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_RETRANSMIT2 MACSTR, 1022 MAC2STR(sm->peer_addr)); 1023 } 1024 1025 1026 SM_STATE(EAP, RECEIVED2) 1027 { 1028 SM_ENTRY(EAP, RECEIVED2); 1029 1030 /* parse rxResp, respId, respMethod */ 1031 eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 1032 } 1033 1034 1035 SM_STATE(EAP, DISCARD2) 1036 { 1037 SM_ENTRY(EAP, DISCARD2); 1038 sm->eap_if.eapResp = FALSE; 1039 sm->eap_if.eapNoReq = TRUE; 1040 } 1041 1042 1043 SM_STATE(EAP, SEND_REQUEST2) 1044 { 1045 SM_ENTRY(EAP, SEND_REQUEST2); 1046 1047 sm->retransCount = 0; 1048 if (sm->eap_if.eapReqData) { 1049 if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0) 1050 { 1051 sm->eap_if.eapResp = FALSE; 1052 sm->eap_if.eapReq = TRUE; 1053 } else { 1054 sm->eap_if.eapResp = FALSE; 1055 sm->eap_if.eapReq = FALSE; 1056 } 1057 } else { 1058 wpa_printf(MSG_INFO, "EAP: SEND_REQUEST2 - no eapReqData"); 1059 sm->eap_if.eapResp = FALSE; 1060 sm->eap_if.eapReq = FALSE; 1061 sm->eap_if.eapNoReq = TRUE; 1062 } 1063 } 1064 1065 1066 SM_STATE(EAP, AAA_REQUEST) 1067 { 1068 SM_ENTRY(EAP, AAA_REQUEST); 1069 1070 if (sm->eap_if.eapRespData == NULL) { 1071 wpa_printf(MSG_INFO, "EAP: AAA_REQUEST - no eapRespData"); 1072 return; 1073 } 1074 1075 /* 1076 * if (respMethod == IDENTITY) 1077 * aaaIdentity = eapRespData 1078 * This is already taken care of by the EAP-Identity method which 1079 * stores the identity into sm->identity. 1080 */ 1081 1082 eap_copy_buf(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData); 1083 } 1084 1085 1086 SM_STATE(EAP, AAA_RESPONSE) 1087 { 1088 SM_ENTRY(EAP, AAA_RESPONSE); 1089 1090 eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 1091 sm->currentId = eap_sm_getId(sm->eap_if.eapReqData); 1092 sm->methodTimeout = sm->eap_if.aaaMethodTimeout; 1093 } 1094 1095 1096 SM_STATE(EAP, AAA_IDLE) 1097 { 1098 SM_ENTRY(EAP, AAA_IDLE); 1099 1100 sm->eap_if.aaaFail = FALSE; 1101 sm->eap_if.aaaSuccess = FALSE; 1102 sm->eap_if.aaaEapReq = FALSE; 1103 sm->eap_if.aaaEapNoReq = FALSE; 1104 sm->eap_if.aaaEapResp = TRUE; 1105 } 1106 1107 1108 SM_STATE(EAP, TIMEOUT_FAILURE2) 1109 { 1110 SM_ENTRY(EAP, TIMEOUT_FAILURE2); 1111 1112 sm->eap_if.eapTimeout = TRUE; 1113 1114 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TIMEOUT_FAILURE2 MACSTR, 1115 MAC2STR(sm->peer_addr)); 1116 } 1117 1118 1119 SM_STATE(EAP, FAILURE2) 1120 { 1121 SM_ENTRY(EAP, FAILURE2); 1122 1123 eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 1124 sm->eap_if.eapFail = TRUE; 1125 1126 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE2 MACSTR, 1127 MAC2STR(sm->peer_addr)); 1128 } 1129 1130 1131 SM_STATE(EAP, SUCCESS2) 1132 { 1133 SM_ENTRY(EAP, SUCCESS2); 1134 1135 eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 1136 1137 sm->eap_if.eapKeyAvailable = sm->eap_if.aaaEapKeyAvailable; 1138 if (sm->eap_if.aaaEapKeyAvailable) { 1139 EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData); 1140 } else { 1141 bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen); 1142 sm->eap_if.eapKeyData = NULL; 1143 sm->eap_if.eapKeyDataLen = 0; 1144 } 1145 1146 sm->eap_if.eapSuccess = TRUE; 1147 1148 /* 1149 * Start reauthentication with identity request even though we know the 1150 * previously used identity. This is needed to get reauthentication 1151 * started properly. 1152 */ 1153 sm->start_reauth = TRUE; 1154 1155 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS2 MACSTR, 1156 MAC2STR(sm->peer_addr)); 1157 } 1158 1159 1160 SM_STEP(EAP) 1161 { 1162 if (sm->eap_if.eapRestart && sm->eap_if.portEnabled) 1163 SM_ENTER_GLOBAL(EAP, INITIALIZE); 1164 else if (!sm->eap_if.portEnabled) 1165 SM_ENTER_GLOBAL(EAP, DISABLED); 1166 else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { 1167 if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { 1168 wpa_printf(MSG_DEBUG, "EAP: more than %d " 1169 "authentication rounds - abort", 1170 EAP_MAX_AUTH_ROUNDS); 1171 sm->num_rounds++; 1172 SM_ENTER_GLOBAL(EAP, FAILURE); 1173 } 1174 } else switch (sm->EAP_state) { 1175 case EAP_INITIALIZE: 1176 if (sm->backend_auth) { 1177 if (!sm->rxResp) 1178 SM_ENTER(EAP, SELECT_ACTION); 1179 else if (sm->rxResp && 1180 (sm->respMethod == EAP_TYPE_NAK || 1181 (sm->respMethod == EAP_TYPE_EXPANDED && 1182 sm->respVendor == EAP_VENDOR_IETF && 1183 sm->respVendorMethod == EAP_TYPE_NAK))) 1184 SM_ENTER(EAP, NAK); 1185 else 1186 SM_ENTER(EAP, PICK_UP_METHOD); 1187 } else { 1188 SM_ENTER(EAP, SELECT_ACTION); 1189 } 1190 break; 1191 case EAP_PICK_UP_METHOD: 1192 if (sm->currentMethod == EAP_TYPE_NONE) { 1193 SM_ENTER(EAP, SELECT_ACTION); 1194 } else { 1195 SM_ENTER(EAP, METHOD_RESPONSE); 1196 } 1197 break; 1198 case EAP_DISABLED: 1199 if (sm->eap_if.portEnabled) 1200 SM_ENTER(EAP, INITIALIZE); 1201 break; 1202 case EAP_IDLE: 1203 if (sm->eap_if.retransWhile == 0) { 1204 if (sm->try_initiate_reauth) { 1205 sm->try_initiate_reauth = FALSE; 1206 SM_ENTER(EAP, SELECT_ACTION); 1207 } else { 1208 SM_ENTER(EAP, RETRANSMIT); 1209 } 1210 } else if (sm->eap_if.eapResp) 1211 SM_ENTER(EAP, RECEIVED); 1212 break; 1213 case EAP_RETRANSMIT: 1214 if (sm->retransCount > sm->MaxRetrans) 1215 SM_ENTER(EAP, TIMEOUT_FAILURE); 1216 else 1217 SM_ENTER(EAP, IDLE); 1218 break; 1219 case EAP_RECEIVED: 1220 if (sm->rxResp && (sm->respId == sm->currentId) && 1221 (sm->respMethod == EAP_TYPE_NAK || 1222 (sm->respMethod == EAP_TYPE_EXPANDED && 1223 sm->respVendor == EAP_VENDOR_IETF && 1224 sm->respVendorMethod == EAP_TYPE_NAK)) 1225 && (sm->methodState == METHOD_PROPOSED)) 1226 SM_ENTER(EAP, NAK); 1227 else if (sm->rxResp && (sm->respId == sm->currentId) && 1228 ((sm->respMethod == sm->currentMethod) || 1229 (sm->respMethod == EAP_TYPE_EXPANDED && 1230 sm->respVendor == EAP_VENDOR_IETF && 1231 sm->respVendorMethod == sm->currentMethod))) 1232 SM_ENTER(EAP, INTEGRITY_CHECK); 1233 #ifdef CONFIG_ERP 1234 else if (sm->rxInitiate) 1235 SM_ENTER(EAP, INITIATE_RECEIVED); 1236 #endif /* CONFIG_ERP */ 1237 else { 1238 wpa_printf(MSG_DEBUG, "EAP: RECEIVED->DISCARD: " 1239 "rxResp=%d respId=%d currentId=%d " 1240 "respMethod=%d currentMethod=%d", 1241 sm->rxResp, sm->respId, sm->currentId, 1242 sm->respMethod, sm->currentMethod); 1243 eap_log_msg(sm, "Discard received EAP message"); 1244 SM_ENTER(EAP, DISCARD); 1245 } 1246 break; 1247 case EAP_DISCARD: 1248 SM_ENTER(EAP, IDLE); 1249 break; 1250 case EAP_SEND_REQUEST: 1251 SM_ENTER(EAP, IDLE); 1252 break; 1253 case EAP_INTEGRITY_CHECK: 1254 if (sm->ignore) 1255 SM_ENTER(EAP, DISCARD); 1256 else 1257 SM_ENTER(EAP, METHOD_RESPONSE); 1258 break; 1259 case EAP_METHOD_REQUEST: 1260 if (sm->m == NULL) { 1261 /* 1262 * This transition is not mentioned in RFC 4137, but it 1263 * is needed to handle cleanly a case where EAP method 1264 * initialization fails. 1265 */ 1266 SM_ENTER(EAP, FAILURE); 1267 break; 1268 } 1269 SM_ENTER(EAP, SEND_REQUEST); 1270 if (sm->eap_if.eapNoReq && !sm->eap_if.eapReq) { 1271 /* 1272 * This transition is not mentioned in RFC 4137, but it 1273 * is needed to handle cleanly a case where EAP method 1274 * buildReq fails. 1275 */ 1276 wpa_printf(MSG_DEBUG, 1277 "EAP: Method did not return a request"); 1278 SM_ENTER(EAP, FAILURE); 1279 break; 1280 } 1281 break; 1282 case EAP_METHOD_RESPONSE: 1283 /* 1284 * Note: Mechanism to allow EAP methods to wait while going 1285 * through pending processing is an extension to RFC 4137 1286 * which only defines the transits to SELECT_ACTION and 1287 * METHOD_REQUEST from this METHOD_RESPONSE state. 1288 */ 1289 if (sm->methodState == METHOD_END) 1290 SM_ENTER(EAP, SELECT_ACTION); 1291 else if (sm->method_pending == METHOD_PENDING_WAIT) { 1292 wpa_printf(MSG_DEBUG, "EAP: Method has pending " 1293 "processing - wait before proceeding to " 1294 "METHOD_REQUEST state"); 1295 } else if (sm->method_pending == METHOD_PENDING_CONT) { 1296 wpa_printf(MSG_DEBUG, "EAP: Method has completed " 1297 "pending processing - reprocess pending " 1298 "EAP message"); 1299 sm->method_pending = METHOD_PENDING_NONE; 1300 SM_ENTER(EAP, METHOD_RESPONSE); 1301 } else 1302 SM_ENTER(EAP, METHOD_REQUEST); 1303 break; 1304 case EAP_PROPOSE_METHOD: 1305 /* 1306 * Note: Mechanism to allow EAP methods to wait while going 1307 * through pending processing is an extension to RFC 4137 1308 * which only defines the transit to METHOD_REQUEST from this 1309 * PROPOSE_METHOD state. 1310 */ 1311 if (sm->method_pending == METHOD_PENDING_WAIT) { 1312 wpa_printf(MSG_DEBUG, "EAP: Method has pending " 1313 "processing - wait before proceeding to " 1314 "METHOD_REQUEST state"); 1315 if (sm->user_eap_method_index > 0) 1316 sm->user_eap_method_index--; 1317 } else if (sm->method_pending == METHOD_PENDING_CONT) { 1318 wpa_printf(MSG_DEBUG, "EAP: Method has completed " 1319 "pending processing - reprocess pending " 1320 "EAP message"); 1321 sm->method_pending = METHOD_PENDING_NONE; 1322 SM_ENTER(EAP, PROPOSE_METHOD); 1323 } else 1324 SM_ENTER(EAP, METHOD_REQUEST); 1325 break; 1326 case EAP_NAK: 1327 SM_ENTER(EAP, SELECT_ACTION); 1328 break; 1329 case EAP_SELECT_ACTION: 1330 if (sm->decision == DECISION_FAILURE) 1331 SM_ENTER(EAP, FAILURE); 1332 else if (sm->decision == DECISION_SUCCESS) 1333 SM_ENTER(EAP, SUCCESS); 1334 else if (sm->decision == DECISION_PASSTHROUGH) 1335 SM_ENTER(EAP, INITIALIZE_PASSTHROUGH); 1336 else if (sm->decision == DECISION_INITIATE_REAUTH_START) 1337 SM_ENTER(EAP, INITIATE_REAUTH_START); 1338 #ifdef CONFIG_ERP 1339 else if (sm->eap_server && sm->erp && sm->rxInitiate) 1340 SM_ENTER(EAP, INITIATE_RECEIVED); 1341 #endif /* CONFIG_ERP */ 1342 else 1343 SM_ENTER(EAP, PROPOSE_METHOD); 1344 break; 1345 case EAP_INITIATE_REAUTH_START: 1346 SM_ENTER(EAP, SEND_REQUEST); 1347 break; 1348 case EAP_INITIATE_RECEIVED: 1349 if (!sm->eap_server) 1350 SM_ENTER(EAP, SELECT_ACTION); 1351 break; 1352 case EAP_TIMEOUT_FAILURE: 1353 break; 1354 case EAP_FAILURE: 1355 break; 1356 case EAP_SUCCESS: 1357 break; 1358 1359 case EAP_INITIALIZE_PASSTHROUGH: 1360 if (sm->currentId == -1) 1361 SM_ENTER(EAP, AAA_IDLE); 1362 else 1363 SM_ENTER(EAP, AAA_REQUEST); 1364 break; 1365 case EAP_IDLE2: 1366 if (sm->eap_if.eapResp) 1367 SM_ENTER(EAP, RECEIVED2); 1368 else if (sm->eap_if.retransWhile == 0) 1369 SM_ENTER(EAP, RETRANSMIT2); 1370 break; 1371 case EAP_RETRANSMIT2: 1372 if (sm->retransCount > sm->MaxRetrans) 1373 SM_ENTER(EAP, TIMEOUT_FAILURE2); 1374 else 1375 SM_ENTER(EAP, IDLE2); 1376 break; 1377 case EAP_RECEIVED2: 1378 if (sm->rxResp && (sm->respId == sm->currentId)) 1379 SM_ENTER(EAP, AAA_REQUEST); 1380 else 1381 SM_ENTER(EAP, DISCARD2); 1382 break; 1383 case EAP_DISCARD2: 1384 SM_ENTER(EAP, IDLE2); 1385 break; 1386 case EAP_SEND_REQUEST2: 1387 SM_ENTER(EAP, IDLE2); 1388 break; 1389 case EAP_AAA_REQUEST: 1390 SM_ENTER(EAP, AAA_IDLE); 1391 break; 1392 case EAP_AAA_RESPONSE: 1393 SM_ENTER(EAP, SEND_REQUEST2); 1394 break; 1395 case EAP_AAA_IDLE: 1396 if (sm->eap_if.aaaFail) 1397 SM_ENTER(EAP, FAILURE2); 1398 else if (sm->eap_if.aaaSuccess) 1399 SM_ENTER(EAP, SUCCESS2); 1400 else if (sm->eap_if.aaaEapReq) 1401 SM_ENTER(EAP, AAA_RESPONSE); 1402 else if (sm->eap_if.aaaTimeout) 1403 SM_ENTER(EAP, TIMEOUT_FAILURE2); 1404 break; 1405 case EAP_TIMEOUT_FAILURE2: 1406 break; 1407 case EAP_FAILURE2: 1408 break; 1409 case EAP_SUCCESS2: 1410 break; 1411 } 1412 } 1413 1414 1415 static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount, 1416 int eapSRTT, int eapRTTVAR, 1417 int methodTimeout) 1418 { 1419 int rto, i; 1420 1421 if (sm->try_initiate_reauth) { 1422 wpa_printf(MSG_DEBUG, 1423 "EAP: retransmit timeout 1 second for EAP-Initiate-Re-auth-Start"); 1424 return 1; 1425 } 1426 1427 if (methodTimeout) { 1428 /* 1429 * EAP method (either internal or through AAA server, provided 1430 * timeout hint. Use that as-is as a timeout for retransmitting 1431 * the EAP request if no response is received. 1432 */ 1433 wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds " 1434 "(from EAP method hint)", methodTimeout); 1435 return methodTimeout; 1436 } 1437 1438 /* 1439 * RFC 3748 recommends algorithms described in RFC 2988 for estimation 1440 * of the retransmission timeout. This should be implemented once 1441 * round-trip time measurements are available. For nowm a simple 1442 * backoff mechanism is used instead if there are no EAP method 1443 * specific hints. 1444 * 1445 * SRTT = smoothed round-trip time 1446 * RTTVAR = round-trip time variation 1447 * RTO = retransmission timeout 1448 */ 1449 1450 /* 1451 * RFC 2988, 2.1: before RTT measurement, set RTO to 3 seconds for 1452 * initial retransmission and then double the RTO to provide back off 1453 * per 5.5. Limit the maximum RTO to 20 seconds per RFC 3748, 4.3 1454 * modified RTOmax. 1455 */ 1456 rto = 3; 1457 for (i = 0; i < retransCount; i++) { 1458 rto *= 2; 1459 if (rto >= 20) { 1460 rto = 20; 1461 break; 1462 } 1463 } 1464 1465 wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds " 1466 "(from dynamic back off; retransCount=%d)", 1467 rto, retransCount); 1468 1469 return rto; 1470 } 1471 1472 1473 static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp) 1474 { 1475 const struct eap_hdr *hdr; 1476 size_t plen; 1477 1478 /* parse rxResp, respId, respMethod */ 1479 sm->rxResp = FALSE; 1480 sm->rxInitiate = FALSE; 1481 sm->respId = -1; 1482 sm->respMethod = EAP_TYPE_NONE; 1483 sm->respVendor = EAP_VENDOR_IETF; 1484 sm->respVendorMethod = EAP_TYPE_NONE; 1485 1486 if (resp == NULL || wpabuf_len(resp) < sizeof(*hdr)) { 1487 wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p " 1488 "len=%lu", resp, 1489 resp ? (unsigned long) wpabuf_len(resp) : 0); 1490 return; 1491 } 1492 1493 hdr = wpabuf_head(resp); 1494 plen = be_to_host16(hdr->length); 1495 if (plen > wpabuf_len(resp)) { 1496 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet " 1497 "(len=%lu plen=%lu)", 1498 (unsigned long) wpabuf_len(resp), 1499 (unsigned long) plen); 1500 return; 1501 } 1502 1503 sm->respId = hdr->identifier; 1504 1505 if (hdr->code == EAP_CODE_RESPONSE) 1506 sm->rxResp = TRUE; 1507 else if (hdr->code == EAP_CODE_INITIATE) 1508 sm->rxInitiate = TRUE; 1509 1510 if (plen > sizeof(*hdr)) { 1511 u8 *pos = (u8 *) (hdr + 1); 1512 sm->respMethod = *pos++; 1513 if (sm->respMethod == EAP_TYPE_EXPANDED) { 1514 if (plen < sizeof(*hdr) + 8) { 1515 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated " 1516 "expanded EAP-Packet (plen=%lu)", 1517 (unsigned long) plen); 1518 return; 1519 } 1520 sm->respVendor = WPA_GET_BE24(pos); 1521 pos += 3; 1522 sm->respVendorMethod = WPA_GET_BE32(pos); 1523 } 1524 } 1525 1526 wpa_printf(MSG_DEBUG, 1527 "EAP: parseEapResp: rxResp=%d rxInitiate=%d respId=%d respMethod=%u respVendor=%u respVendorMethod=%u", 1528 sm->rxResp, sm->rxInitiate, sm->respId, sm->respMethod, 1529 sm->respVendor, sm->respVendorMethod); 1530 } 1531 1532 1533 static int eap_sm_getId(const struct wpabuf *data) 1534 { 1535 const struct eap_hdr *hdr; 1536 1537 if (data == NULL || wpabuf_len(data) < sizeof(*hdr)) 1538 return -1; 1539 1540 hdr = wpabuf_head(data); 1541 wpa_printf(MSG_DEBUG, "EAP: getId: id=%d", hdr->identifier); 1542 return hdr->identifier; 1543 } 1544 1545 1546 static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id) 1547 { 1548 struct wpabuf *msg; 1549 struct eap_hdr *resp; 1550 wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (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_SUCCESS; 1557 resp->identifier = id; 1558 resp->length = host_to_be16(sizeof(*resp)); 1559 1560 return msg; 1561 } 1562 1563 1564 static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id) 1565 { 1566 struct wpabuf *msg; 1567 struct eap_hdr *resp; 1568 wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id); 1569 1570 msg = wpabuf_alloc(sizeof(*resp)); 1571 if (msg == NULL) 1572 return NULL; 1573 resp = wpabuf_put(msg, sizeof(*resp)); 1574 resp->code = EAP_CODE_FAILURE; 1575 resp->identifier = id; 1576 resp->length = host_to_be16(sizeof(*resp)); 1577 1578 return msg; 1579 } 1580 1581 1582 static int eap_sm_nextId(struct eap_sm *sm, int id) 1583 { 1584 if (id < 0) { 1585 /* RFC 3748 Ch 4.1: recommended to initialize Identifier with a 1586 * random number */ 1587 id = rand() & 0xff; 1588 if (id != sm->lastId) 1589 return id; 1590 } 1591 return (id + 1) & 0xff; 1592 } 1593 1594 1595 /** 1596 * eap_sm_process_nak - Process EAP-Response/Nak 1597 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1598 * @nak_list: Nak list (allowed methods) from the supplicant 1599 * @len: Length of nak_list in bytes 1600 * 1601 * This function is called when EAP-Response/Nak is received from the 1602 * supplicant. This can happen for both phase 1 and phase 2 authentications. 1603 */ 1604 void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len) 1605 { 1606 int i; 1607 size_t j; 1608 1609 if (sm->user == NULL) 1610 return; 1611 1612 wpa_printf(MSG_MSGDUMP, "EAP: processing NAK (current EAP method " 1613 "index %d)", sm->user_eap_method_index); 1614 1615 wpa_hexdump(MSG_MSGDUMP, "EAP: configured methods", 1616 (u8 *) sm->user->methods, 1617 EAP_MAX_METHODS * sizeof(sm->user->methods[0])); 1618 wpa_hexdump(MSG_MSGDUMP, "EAP: list of methods supported by the peer", 1619 nak_list, len); 1620 1621 i = sm->user_eap_method_index; 1622 while (i < EAP_MAX_METHODS && 1623 (sm->user->methods[i].vendor != EAP_VENDOR_IETF || 1624 sm->user->methods[i].method != EAP_TYPE_NONE)) { 1625 if (sm->user->methods[i].vendor != EAP_VENDOR_IETF) 1626 goto not_found; 1627 for (j = 0; j < len; j++) { 1628 if (nak_list[j] == sm->user->methods[i].method) { 1629 break; 1630 } 1631 } 1632 1633 if (j < len) { 1634 /* found */ 1635 i++; 1636 continue; 1637 } 1638 1639 not_found: 1640 /* not found - remove from the list */ 1641 if (i + 1 < EAP_MAX_METHODS) { 1642 os_memmove(&sm->user->methods[i], 1643 &sm->user->methods[i + 1], 1644 (EAP_MAX_METHODS - i - 1) * 1645 sizeof(sm->user->methods[0])); 1646 } 1647 sm->user->methods[EAP_MAX_METHODS - 1].vendor = 1648 EAP_VENDOR_IETF; 1649 sm->user->methods[EAP_MAX_METHODS - 1].method = EAP_TYPE_NONE; 1650 } 1651 1652 wpa_hexdump(MSG_MSGDUMP, "EAP: new list of configured methods", 1653 (u8 *) sm->user->methods, EAP_MAX_METHODS * 1654 sizeof(sm->user->methods[0])); 1655 } 1656 1657 1658 static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list, 1659 size_t len) 1660 { 1661 if (nak_list == NULL || sm == NULL || sm->user == NULL) 1662 return; 1663 1664 if (sm->user->phase2) { 1665 wpa_printf(MSG_DEBUG, "EAP: EAP-Nak received after Phase2 user" 1666 " info was selected - reject"); 1667 sm->decision = DECISION_FAILURE; 1668 return; 1669 } 1670 1671 eap_sm_process_nak(sm, nak_list, len); 1672 } 1673 1674 1675 static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor) 1676 { 1677 EapType next; 1678 int idx = sm->user_eap_method_index; 1679 1680 /* In theory, there should be no problems with starting 1681 * re-authentication with something else than EAP-Request/Identity and 1682 * this does indeed work with wpa_supplicant. However, at least Funk 1683 * Supplicant seemed to ignore re-auth if it skipped 1684 * EAP-Request/Identity. 1685 * Re-auth sets currentId == -1, so that can be used here to select 1686 * whether Identity needs to be requested again. */ 1687 if (sm->identity == NULL || sm->currentId == -1) { 1688 *vendor = EAP_VENDOR_IETF; 1689 next = EAP_TYPE_IDENTITY; 1690 sm->update_user = TRUE; 1691 } else if (sm->user && idx < EAP_MAX_METHODS && 1692 (sm->user->methods[idx].vendor != EAP_VENDOR_IETF || 1693 sm->user->methods[idx].method != EAP_TYPE_NONE)) { 1694 *vendor = sm->user->methods[idx].vendor; 1695 next = sm->user->methods[idx].method; 1696 sm->user_eap_method_index++; 1697 } else { 1698 *vendor = EAP_VENDOR_IETF; 1699 next = EAP_TYPE_NONE; 1700 } 1701 wpa_printf(MSG_DEBUG, "EAP: getNextMethod: vendor %d type %d", 1702 *vendor, next); 1703 return next; 1704 } 1705 1706 1707 static int eap_sm_Policy_getDecision(struct eap_sm *sm) 1708 { 1709 if (!sm->eap_server && sm->identity && !sm->start_reauth) { 1710 wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH"); 1711 return DECISION_PASSTHROUGH; 1712 } 1713 1714 if (sm->m && sm->currentMethod != EAP_TYPE_IDENTITY && 1715 sm->m->isSuccess(sm, sm->eap_method_priv)) { 1716 wpa_printf(MSG_DEBUG, "EAP: getDecision: method succeeded -> " 1717 "SUCCESS"); 1718 sm->update_user = TRUE; 1719 return DECISION_SUCCESS; 1720 } 1721 1722 if (sm->m && sm->m->isDone(sm, sm->eap_method_priv) && 1723 !sm->m->isSuccess(sm, sm->eap_method_priv)) { 1724 wpa_printf(MSG_DEBUG, "EAP: getDecision: method failed -> " 1725 "FAILURE"); 1726 sm->update_user = TRUE; 1727 return DECISION_FAILURE; 1728 } 1729 1730 if ((sm->user == NULL || sm->update_user) && sm->identity && 1731 !sm->start_reauth) { 1732 /* 1733 * Allow Identity method to be started once to allow identity 1734 * selection hint to be sent from the authentication server, 1735 * but prevent a loop of Identity requests by only allowing 1736 * this to happen once. 1737 */ 1738 int id_req = 0; 1739 if (sm->user && sm->currentMethod == EAP_TYPE_IDENTITY && 1740 sm->user->methods[0].vendor == EAP_VENDOR_IETF && 1741 sm->user->methods[0].method == EAP_TYPE_IDENTITY) 1742 id_req = 1; 1743 if (eap_user_get(sm, sm->identity, sm->identity_len, 0) != 0) { 1744 wpa_printf(MSG_DEBUG, "EAP: getDecision: user not " 1745 "found from database -> FAILURE"); 1746 return DECISION_FAILURE; 1747 } 1748 if (id_req && sm->user && 1749 sm->user->methods[0].vendor == EAP_VENDOR_IETF && 1750 sm->user->methods[0].method == EAP_TYPE_IDENTITY) { 1751 wpa_printf(MSG_DEBUG, "EAP: getDecision: stop " 1752 "identity request loop -> FAILURE"); 1753 sm->update_user = TRUE; 1754 return DECISION_FAILURE; 1755 } 1756 sm->update_user = FALSE; 1757 } 1758 sm->start_reauth = FALSE; 1759 1760 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && 1761 (sm->user->methods[sm->user_eap_method_index].vendor != 1762 EAP_VENDOR_IETF || 1763 sm->user->methods[sm->user_eap_method_index].method != 1764 EAP_TYPE_NONE)) { 1765 wpa_printf(MSG_DEBUG, "EAP: getDecision: another method " 1766 "available -> CONTINUE"); 1767 return DECISION_CONTINUE; 1768 } 1769 1770 if (!sm->identity && eap_get_erp_send_reauth_start(sm) && 1771 !sm->initiate_reauth_start_sent) { 1772 wpa_printf(MSG_DEBUG, 1773 "EAP: getDecision: send EAP-Initiate/Re-auth-Start"); 1774 return DECISION_INITIATE_REAUTH_START; 1775 } 1776 1777 if (sm->identity == NULL || sm->currentId == -1) { 1778 wpa_printf(MSG_DEBUG, "EAP: getDecision: no identity known " 1779 "yet -> CONTINUE"); 1780 return DECISION_CONTINUE; 1781 } 1782 1783 wpa_printf(MSG_DEBUG, "EAP: getDecision: no more methods available -> " 1784 "FAILURE"); 1785 return DECISION_FAILURE; 1786 } 1787 1788 1789 static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method) 1790 { 1791 return method == EAP_TYPE_IDENTITY ? TRUE : FALSE; 1792 } 1793 1794 1795 /** 1796 * eap_server_sm_step - Step EAP server state machine 1797 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1798 * Returns: 1 if EAP state was changed or 0 if not 1799 * 1800 * This function advances EAP state machine to a new state to match with the 1801 * current variables. This should be called whenever variables used by the EAP 1802 * state machine have changed. 1803 */ 1804 int eap_server_sm_step(struct eap_sm *sm) 1805 { 1806 int res = 0; 1807 do { 1808 sm->changed = FALSE; 1809 SM_STEP_RUN(EAP); 1810 if (sm->changed) 1811 res = 1; 1812 } while (sm->changed); 1813 return res; 1814 } 1815 1816 1817 static void eap_user_free(struct eap_user *user) 1818 { 1819 if (user == NULL) 1820 return; 1821 bin_clear_free(user->password, user->password_len); 1822 user->password = NULL; 1823 bin_clear_free(user->salt, user->salt_len); 1824 user->salt = NULL; 1825 os_free(user); 1826 } 1827 1828 1829 /** 1830 * eap_server_sm_init - Allocate and initialize EAP server state machine 1831 * @eapol_ctx: Context data to be used with eapol_cb calls 1832 * @eapol_cb: Pointer to EAPOL callback functions 1833 * @conf: EAP configuration 1834 * Returns: Pointer to the allocated EAP state machine or %NULL on failure 1835 * 1836 * This function allocates and initializes an EAP state machine. 1837 */ 1838 struct eap_sm * eap_server_sm_init(void *eapol_ctx, 1839 const struct eapol_callbacks *eapol_cb, 1840 struct eap_config *conf) 1841 { 1842 struct eap_sm *sm; 1843 1844 sm = os_zalloc(sizeof(*sm)); 1845 if (sm == NULL) 1846 return NULL; 1847 sm->eapol_ctx = eapol_ctx; 1848 sm->eapol_cb = eapol_cb; 1849 sm->MaxRetrans = 5; /* RFC 3748: max 3-5 retransmissions suggested */ 1850 sm->ssl_ctx = conf->ssl_ctx; 1851 sm->msg_ctx = conf->msg_ctx; 1852 sm->eap_sim_db_priv = conf->eap_sim_db_priv; 1853 sm->backend_auth = conf->backend_auth; 1854 sm->eap_server = conf->eap_server; 1855 if (conf->pac_opaque_encr_key) { 1856 sm->pac_opaque_encr_key = os_malloc(16); 1857 if (sm->pac_opaque_encr_key) { 1858 os_memcpy(sm->pac_opaque_encr_key, 1859 conf->pac_opaque_encr_key, 16); 1860 } 1861 } 1862 if (conf->eap_fast_a_id) { 1863 sm->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len); 1864 if (sm->eap_fast_a_id) { 1865 os_memcpy(sm->eap_fast_a_id, conf->eap_fast_a_id, 1866 conf->eap_fast_a_id_len); 1867 sm->eap_fast_a_id_len = conf->eap_fast_a_id_len; 1868 } 1869 } 1870 if (conf->eap_fast_a_id_info) 1871 sm->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info); 1872 sm->eap_fast_prov = conf->eap_fast_prov; 1873 sm->pac_key_lifetime = conf->pac_key_lifetime; 1874 sm->pac_key_refresh_time = conf->pac_key_refresh_time; 1875 sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; 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 void eap_erp_update_identity(struct eap_sm *sm, const u8 *eap, size_t len) 2007 { 2008 #ifdef CONFIG_ERP 2009 const struct eap_hdr *hdr; 2010 const u8 *pos, *end; 2011 struct erp_tlvs parse; 2012 2013 if (len < sizeof(*hdr) + 1) 2014 return; 2015 hdr = (const struct eap_hdr *) eap; 2016 end = eap + len; 2017 pos = (const u8 *) (hdr + 1); 2018 if (hdr->code != EAP_CODE_INITIATE || *pos != EAP_ERP_TYPE_REAUTH) 2019 return; 2020 pos++; 2021 if (pos + 3 > end) 2022 return; 2023 2024 /* Skip Flags and SEQ */ 2025 pos += 3; 2026 2027 if (erp_parse_tlvs(pos, end, &parse, 1) < 0 || !parse.keyname) 2028 return; 2029 wpa_hexdump_ascii(MSG_DEBUG, 2030 "EAP: Update identity based on EAP-Initiate/Re-auth keyName-NAI", 2031 parse.keyname, parse.keyname_len); 2032 os_free(sm->identity); 2033 sm->identity = os_malloc(parse.keyname_len); 2034 if (sm->identity) { 2035 os_memcpy(sm->identity, parse.keyname, parse.keyname_len); 2036 sm->identity_len = parse.keyname_len; 2037 } else { 2038 sm->identity_len = 0; 2039 } 2040 #endif /* CONFIG_ERP */ 2041 } 2042 2043 2044 /** 2045 * eap_get_interface - Get pointer to EAP-EAPOL interface data 2046 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 2047 * Returns: Pointer to the EAP-EAPOL interface data 2048 */ 2049 struct eap_eapol_interface * eap_get_interface(struct eap_sm *sm) 2050 { 2051 return &sm->eap_if; 2052 } 2053 2054 2055 /** 2056 * eap_server_clear_identity - Clear EAP identity information 2057 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 2058 * 2059 * This function can be used to clear the EAP identity information in the EAP 2060 * server context. This allows the EAP/Identity method to be used again after 2061 * EAPOL-Start or EAPOL-Logoff. 2062 */ 2063 void eap_server_clear_identity(struct eap_sm *sm) 2064 { 2065 os_free(sm->identity); 2066 sm->identity = NULL; 2067 } 2068 2069 2070 #ifdef CONFIG_TESTING_OPTIONS 2071 void eap_server_mschap_rx_callback(struct eap_sm *sm, const char *source, 2072 const u8 *username, size_t username_len, 2073 const u8 *challenge, const u8 *response) 2074 { 2075 char hex_challenge[30], hex_response[90], user[100]; 2076 2077 /* Print out Challenge and Response in format supported by asleap. */ 2078 if (username) 2079 printf_encode(user, sizeof(user), username, username_len); 2080 else 2081 user[0] = '\0'; 2082 wpa_snprintf_hex_sep(hex_challenge, sizeof(hex_challenge), 2083 challenge, sizeof(challenge), ':'); 2084 wpa_snprintf_hex_sep(hex_response, sizeof(hex_response), response, 24, 2085 ':'); 2086 wpa_printf(MSG_DEBUG, "[%s/user=%s] asleap -C %s -R %s", 2087 source, user, hex_challenge, hex_response); 2088 } 2089 #endif /* CONFIG_TESTING_OPTIONS */ 2090