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