18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / EAP Full Authenticator state machine (RFC 4137) 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This state machine is based on the full authenticator state machine defined 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in RFC 4137. However, to support backend authentication in RADIUS 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication server functionality, parts of backend authenticator (also 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from RFC 4137) are mixed in. This functionality is enabled by setting 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * backend_auth configuration variable to TRUE. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_i.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "state_machine.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DATA struct eap_sm 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DEBUG_PREFIX "EAP" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_MAX_AUTH_ROUNDS 50 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_user_free(struct eap_user *user); 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* EAP state machines are described in RFC 4137 */ 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount, 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eapSRTT, int eapRTTVAR, 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int methodTimeout); 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp); 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_getId(const struct wpabuf *data); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id); 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id); 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_nextId(struct eap_sm *sm, int id); 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list, 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len); 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_Policy_getDecision(struct eap_sm *sm); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_copy_buf(struct wpabuf **dst, const struct wpabuf *src) 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (src == NULL) 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(*dst); 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *dst = wpabuf_dup(src); 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return *dst ? 0 : -1; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_copy_data(u8 **dst, size_t *dst_len, 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *src, size_t src_len) 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (src == NULL) 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(*dst); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *dst = os_malloc(src_len); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*dst) { 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(*dst, src, src_len); 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *dst_len = src_len; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *dst_len = 0; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_COPY(dst, src) \ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_copy_data((dst), (dst ## Len), (src), (src ## Len)) 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_user_get - Fetch user information from the database 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @identity: Identity (User-Name) of the user 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @identity_len: Length of identity in bytes 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @phase2: 0 = EAP phase1 user, 1 = EAP phase2 (tunneled) user 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, or -1 on failure 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to fetch user information for EAP. The user will be 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * selected based on the specified identity. sm->user and 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * sm->user_eap_method_index are updated for the new user when a matching user 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is found. sm->user can be used to get user information (e.g., password). 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len, 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int phase2) 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_user *user; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->eapol_cb == NULL || 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb->get_eap_user == NULL) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_user_free(sm->user); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user = NULL; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt user = os_zalloc(sizeof(*user)); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (user == NULL) 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity, 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity_len, phase2, user) != 0) { 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_user_free(user); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user = user; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user_eap_method_index = 0; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, DISABLED) 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, DISABLED); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds = 0; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, INITIALIZE) 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, INITIALIZE); 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sm->eap_if.eapRestart && !sm->eap_server && sm->identity) { 1341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 1351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Need to allow internal Identity method to be used instead 1361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * of passthrough at the beginning of reauthentication. 1371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 1381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_server_clear_identity(sm); 1391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 1401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentId = -1; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapSuccess = FALSE; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapFail = FALSE; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapTimeout = FALSE; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eap_if.eapKeyData); 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapKeyData = NULL; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapKeyDataLen = 0; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapKeyAvailable = FALSE; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapRestart = FALSE; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is not defined in RFC 4137, but method state needs to be 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * reseted here so that it does not remain in success state when 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * re-authentication starts. 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->eap_method_priv) { 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->reset(sm, sm->eap_method_priv); 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = NULL; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = NULL; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user_eap_method_index = 0; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->backend_auth) { 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentMethod = EAP_TYPE_NONE; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* parse rxResp, respId, respMethod */ 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->rxResp) { 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentId = sm->respId; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds = 0; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->method_pending = METHOD_PENDING_NONE; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(sm->peer_addr)); 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, PICK_UP_METHOD) 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, PICK_UP_METHOD); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sm_Policy_doPickUp(sm, sm->respMethod)) { 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentMethod = sm->respMethod; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->eap_method_priv) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->reset(sm, sm->eap_method_priv); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = NULL; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = eap_server_get_eap_method(EAP_VENDOR_IETF, 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentMethod); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->m->initPickUp) { 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = sm->m->initPickUp(sm); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_method_priv == NULL) { 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Failed to " 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "initialize EAP method %d", 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentMethod); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = NULL; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentMethod = EAP_TYPE_NONE; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = NULL; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentMethod = EAP_TYPE_NONE; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "method=%u", sm->currentMethod); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, IDLE) 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, IDLE); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.retransWhile = eap_sm_calculateTimeout( 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR, 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodTimeout); 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, RETRANSMIT) 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, RETRANSMIT); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->retransCount++; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) { 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0) 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReq = TRUE; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, RECEIVED) 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, RECEIVED); 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* parse rxResp, respId, respMethod */ 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds++; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, DISCARD) 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, DISCARD); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapResp = FALSE; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapNoReq = TRUE; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, SEND_REQUEST) 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, SEND_REQUEST); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->retransCount = 0; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if.eapReqData) { 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0) 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapResp = FALSE; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReq = TRUE; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapResp = FALSE; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReq = FALSE; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP: SEND_REQUEST - no eapReqData"); 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapResp = FALSE; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReq = FALSE; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapNoReq = TRUE; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, INTEGRITY_CHECK) 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, INTEGRITY_CHECK); 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) { 27961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sm->ignore = TRUE; 28061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 28161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 28261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m->check) { 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ignore = sm->m->check(sm, sm->eap_method_priv, 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapRespData); 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, METHOD_REQUEST) 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, METHOD_REQUEST); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m == NULL) { 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: method not initialized"); 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentId = eap_sm_nextId(sm, sm->currentId); 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: building EAP-Request: Identifier %d", 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentId); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastId = sm->currentId; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eap_if.eapReqData); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReqData = sm->m->buildReq(sm, sm->eap_method_priv, 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentId); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m->getTimeout) 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodTimeout = sm->m->getTimeout(sm, sm->eap_method_priv); 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodTimeout = 0; 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, METHOD_RESPONSE) 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, METHOD_RESPONSE); 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) 31861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 31961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m->isDone(sm, sm->eap_method_priv)) { 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_Policy_update(sm, NULL, 0); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eap_if.eapKeyData); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m->getKey) { 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapKeyData = sm->m->getKey( 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, sm->eap_method_priv, 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &sm->eap_if.eapKeyDataLen); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapKeyData = NULL; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapKeyDataLen = 0; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = METHOD_END; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = METHOD_CONTINUE; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, PROPOSE_METHOD) 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int vendor; 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType type; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, PROPOSE_METHOD); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = eap_sm_Policy_getNextMethod(sm, &vendor); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor == EAP_VENDOR_IETF) 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentMethod = type; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentMethod = EAP_TYPE_EXPANDED; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->eap_method_priv) { 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->reset(sm, sm->eap_method_priv); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = NULL; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = eap_server_get_eap_method(vendor, type); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m) { 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = sm->m->init(sm); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_method_priv == NULL) { 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Failed to initialize EAP " 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "method %d", sm->currentMethod); 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = NULL; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentMethod = EAP_TYPE_NONE; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->currentMethod == EAP_TYPE_IDENTITY || 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentMethod == EAP_TYPE_NOTIFICATION) 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = METHOD_CONTINUE; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodState = METHOD_PROPOSED; 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "vendor=%u method=%u", vendor, sm->currentMethod); 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, NAK) 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_hdr *nak; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len = 0; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *nak_list = NULL; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, NAK); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_method_priv) { 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->reset(sm, sm->eap_method_priv); 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_method_priv = NULL; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m = NULL; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) 39261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 39361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nak = wpabuf_head(sm->eap_if.eapRespData); 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nak && wpabuf_len(sm->eap_if.eapRespData) > sizeof(*nak)) { 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = be_to_host16(nak->length); 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > wpabuf_len(sm->eap_if.eapRespData)) 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = wpabuf_len(sm->eap_if.eapRespData); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (nak + 1); 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= sizeof(*nak); 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == EAP_TYPE_NAK) { 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len--; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nak_list = pos; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_Policy_update(sm, nak_list, len); 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, SELECT_ACTION) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, SELECT_ACTION); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision = eap_sm_Policy_getDecision(sm); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, TIMEOUT_FAILURE) 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, TIMEOUT_FAILURE); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapTimeout = TRUE; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, FAILURE) 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, FAILURE); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eap_if.eapReqData); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->lastReqData); 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastReqData = NULL; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapFail = TRUE; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(sm->peer_addr)); 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, SUCCESS) 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, SUCCESS); 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eap_if.eapReqData); 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->lastReqData); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->lastReqData = NULL; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if.eapKeyData) 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapKeyAvailable = TRUE; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapSuccess = TRUE; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(sm->peer_addr)); 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, INITIALIZE_PASSTHROUGH) 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH); 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eap_if.aaaEapRespData); 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.aaaEapRespData = NULL; 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, IDLE2) 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, IDLE2); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.retransWhile = eap_sm_calculateTimeout( 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR, 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodTimeout); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, RETRANSMIT2) 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, RETRANSMIT2); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->retransCount++; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) { 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0) 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReq = TRUE; 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, RECEIVED2) 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, RECEIVED2); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* parse rxResp, respId, respMethod */ 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, DISCARD2) 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, DISCARD2); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapResp = FALSE; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapNoReq = TRUE; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, SEND_REQUEST2) 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, SEND_REQUEST2); 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->retransCount = 0; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if.eapReqData) { 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0) 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapResp = FALSE; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReq = TRUE; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapResp = FALSE; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReq = FALSE; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP: SEND_REQUEST2 - no eapReqData"); 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapResp = FALSE; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapReq = FALSE; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapNoReq = TRUE; 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, AAA_REQUEST) 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, AAA_REQUEST); 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if.eapRespData == NULL) { 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP: AAA_REQUEST - no eapRespData"); 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * if (respMethod == IDENTITY) 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * aaaIdentity = eapRespData 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is already taken care of by the EAP-Identity method which 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * stores the identity into sm->identity. 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_copy_buf(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, AAA_RESPONSE) 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, AAA_RESPONSE); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->currentId = eap_sm_getId(sm->eap_if.eapReqData); 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->methodTimeout = sm->eap_if.aaaMethodTimeout; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, AAA_IDLE) 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, AAA_IDLE); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.aaaFail = FALSE; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.aaaSuccess = FALSE; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.aaaEapReq = FALSE; 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.aaaEapNoReq = FALSE; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.aaaEapResp = TRUE; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, TIMEOUT_FAILURE2) 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, TIMEOUT_FAILURE2); 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapTimeout = TRUE; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, FAILURE2) 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, FAILURE2); 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapFail = TRUE; 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(EAP, SUCCESS2) 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(EAP, SUCCESS2); 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapKeyAvailable = sm->eap_if.aaaEapKeyAvailable; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if.aaaEapKeyAvailable) { 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData); 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eap_if.eapKeyData); 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapKeyData = NULL; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapKeyDataLen = 0; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_if.eapSuccess = TRUE; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Start reauthentication with identity request even though we know the 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * previously used identity. This is needed to get reauthentication 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * started properly. 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->start_reauth = TRUE; 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(EAP) 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if.eapRestart && sm->eap_if.portEnabled) 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(EAP, INITIALIZE); 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (!sm->eap_if.portEnabled) 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(EAP, DISABLED); 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: more than %d " 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authentication rounds - abort", 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_MAX_AUTH_ROUNDS); 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->num_rounds++; 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(EAP, FAILURE); 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else switch (sm->EAP_state) { 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_INITIALIZE: 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->backend_auth) { 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->rxResp) 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SELECT_ACTION); 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxResp && 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->respMethod == EAP_TYPE_NAK || 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->respMethod == EAP_TYPE_EXPANDED && 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendor == EAP_VENDOR_IETF && 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendorMethod == EAP_TYPE_NAK))) 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, NAK); 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, PICK_UP_METHOD); 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SELECT_ACTION); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_PICK_UP_METHOD: 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->currentMethod == EAP_TYPE_NONE) { 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SELECT_ACTION); 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD_RESPONSE); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISABLED: 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if.portEnabled) 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, INITIALIZE); 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_IDLE: 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if.retransWhile == 0) 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, RETRANSMIT); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eap_if.eapResp) 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, RECEIVED); 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RETRANSMIT: 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->retransCount > sm->MaxRetrans) 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, TIMEOUT_FAILURE); 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE); 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RECEIVED: 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->rxResp && (sm->respId == sm->currentId) && 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->respMethod == EAP_TYPE_NAK || 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->respMethod == EAP_TYPE_EXPANDED && 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendor == EAP_VENDOR_IETF && 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendorMethod == EAP_TYPE_NAK)) 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt && (sm->methodState == METHOD_PROPOSED)) 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, NAK); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->rxResp && (sm->respId == sm->currentId) && 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((sm->respMethod == sm->currentMethod) || 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->respMethod == EAP_TYPE_EXPANDED && 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendor == EAP_VENDOR_IETF && 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendorMethod == sm->currentMethod))) 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, INTEGRITY_CHECK); 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: RECEIVED->DISCARD: " 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "rxResp=%d respId=%d currentId=%d " 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "respMethod=%d currentMethod=%d", 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxResp, sm->respId, sm->currentId, 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respMethod, sm->currentMethod); 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, DISCARD); 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISCARD: 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE); 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SEND_REQUEST: 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_INTEGRITY_CHECK: 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ignore) 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, DISCARD); 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD_RESPONSE); 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_METHOD_REQUEST: 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_REQUEST); 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_METHOD_RESPONSE: 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Mechanism to allow EAP methods to wait while going 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * through pending processing is an extension to RFC 4137 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * which only defines the transits to SELECT_ACTION and 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * METHOD_REQUEST from this METHOD_RESPONSE state. 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->methodState == METHOD_END) 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SELECT_ACTION); 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->method_pending == METHOD_PENDING_WAIT) { 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Method has pending " 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "processing - wait before proceeding to " 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "METHOD_REQUEST state"); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sm->method_pending == METHOD_PENDING_CONT) { 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Method has completed " 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pending processing - reprocess pending " 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP message"); 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->method_pending = METHOD_PENDING_NONE; 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD_RESPONSE); 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD_REQUEST); 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_PROPOSE_METHOD: 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Mechanism to allow EAP methods to wait while going 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * through pending processing is an extension to RFC 4137 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * which only defines the transit to METHOD_REQUEST from this 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PROPOSE_METHOD state. 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->method_pending == METHOD_PENDING_WAIT) { 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Method has pending " 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "processing - wait before proceeding to " 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "METHOD_REQUEST state"); 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user_eap_method_index > 0) 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user_eap_method_index--; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sm->method_pending == METHOD_PENDING_CONT) { 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Method has completed " 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pending processing - reprocess pending " 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP message"); 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->method_pending = METHOD_PENDING_NONE; 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, PROPOSE_METHOD); 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, METHOD_REQUEST); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_NAK: 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SELECT_ACTION); 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SELECT_ACTION: 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->decision == DECISION_FAILURE) 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, FAILURE); 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->decision == DECISION_SUCCESS) 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SUCCESS); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->decision == DECISION_PASSTHROUGH) 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, INITIALIZE_PASSTHROUGH); 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, PROPOSE_METHOD); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TIMEOUT_FAILURE: 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_FAILURE: 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SUCCESS: 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_INITIALIZE_PASSTHROUGH: 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->currentId == -1) 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, AAA_IDLE); 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, AAA_REQUEST); 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_IDLE2: 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if.eapResp) 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, RECEIVED2); 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eap_if.retransWhile == 0) 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, RETRANSMIT2); 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RETRANSMIT2: 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->retransCount > sm->MaxRetrans) 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, TIMEOUT_FAILURE2); 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE2); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_RECEIVED2: 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->rxResp && (sm->respId == sm->currentId)) 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, AAA_REQUEST); 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, DISCARD2); 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_DISCARD2: 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE2); 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SEND_REQUEST2: 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, IDLE2); 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_AAA_REQUEST: 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, AAA_IDLE); 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_AAA_RESPONSE: 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SEND_REQUEST2); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_AAA_IDLE: 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_if.aaaFail) 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, FAILURE2); 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eap_if.aaaSuccess) 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, SUCCESS2); 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eap_if.aaaEapReq) 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, AAA_RESPONSE); 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eap_if.aaaTimeout) 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(EAP, TIMEOUT_FAILURE2); 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TIMEOUT_FAILURE2: 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_FAILURE2: 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_SUCCESS2: 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount, 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eapSRTT, int eapRTTVAR, 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int methodTimeout) 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rto, i; 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (methodTimeout) { 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP method (either internal or through AAA server, provided 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * timeout hint. Use that as-is as a timeout for retransmitting 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the EAP request if no response is received. 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds " 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(from EAP method hint)", methodTimeout); 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return methodTimeout; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 3748 recommends algorithms described in RFC 2988 for estimation 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * of the retransmission timeout. This should be implemented once 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * round-trip time measurements are available. For nowm a simple 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * backoff mechanism is used instead if there are no EAP method 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * specific hints. 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SRTT = smoothed round-trip time 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RTTVAR = round-trip time variation 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RTO = retransmission timeout 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC 2988, 2.1: before RTT measurement, set RTO to 3 seconds for 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initial retransmission and then double the RTO to provide back off 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * per 5.5. Limit the maximum RTO to 20 seconds per RFC 3748, 4.3 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * modified RTOmax. 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rto = 3; 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < retransCount; i++) { 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rto *= 2; 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rto >= 20) { 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rto = 20; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds " 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(from dynamic back off; retransCount=%d)", 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rto, retransCount); 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return rto; 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp) 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_hdr *hdr; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t plen; 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* parse rxResp, respId, respMethod */ 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxResp = FALSE; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respId = -1; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respMethod = EAP_TYPE_NONE; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendor = EAP_VENDOR_IETF; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendorMethod = EAP_TYPE_NONE; 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL || wpabuf_len(resp) < sizeof(*hdr)) { 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p " 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "len=%lu", resp, 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp ? (unsigned long) wpabuf_len(resp) : 0); 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = wpabuf_head(resp); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = be_to_host16(hdr->length); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen > wpabuf_len(resp)) { 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet " 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu plen=%lu)", 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(resp), 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) plen); 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respId = hdr->identifier; 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->code == EAP_CODE_RESPONSE) 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxResp = TRUE; 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen > sizeof(*hdr)) { 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = (u8 *) (hdr + 1); 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respMethod = *pos++; 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->respMethod == EAP_TYPE_EXPANDED) { 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen < sizeof(*hdr) + 8) { 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored truncated " 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "expanded EAP-Packet (plen=%lu)", 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) plen); 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendor = WPA_GET_BE24(pos); 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendorMethod = WPA_GET_BE32(pos); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: parseEapResp: rxResp=%d respId=%d " 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "respMethod=%u respVendor=%u respVendorMethod=%u", 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxResp, sm->respId, sm->respMethod, sm->respVendor, 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->respVendorMethod); 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_getId(const struct wpabuf *data) 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_hdr *hdr; 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL || wpabuf_len(data) < sizeof(*hdr)) 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = wpabuf_head(data); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getId: id=%d", hdr->identifier); 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hdr->identifier; 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id) 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *msg; 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_hdr *resp; 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (id=%d)", id); 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = wpabuf_alloc(sizeof(*resp)); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_put(msg, sizeof(*resp)); 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->code = EAP_CODE_SUCCESS; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->identifier = id; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->length = host_to_be16(sizeof(*resp)); 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id) 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *msg; 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_hdr *resp; 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id); 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = wpabuf_alloc(sizeof(*resp)); 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpabuf_put(msg, sizeof(*resp)); 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->code = EAP_CODE_FAILURE; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->identifier = id; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->length = host_to_be16(sizeof(*resp)); 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_nextId(struct eap_sm *sm, int id) 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (id < 0) { 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 3748 Ch 4.1: recommended to initialize Identifier with a 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * random number */ 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id = rand() & 0xff; 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (id != sm->lastId) 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return id; 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (id + 1) & 0xff; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_process_nak - Process EAP-Response/Nak 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @nak_list: Nak list (allowed methods) from the supplicant 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of nak_list in bytes 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called when EAP-Response/Nak is received from the 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * supplicant. This can happen for both phase 1 and phase 2 authentications. 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len) 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user == NULL) 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "EAP: processing NAK (current EAP method " 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "index %d)", sm->user_eap_method_index); 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP: configured methods", 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) sm->user->methods, 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_MAX_METHODS * sizeof(sm->user->methods[0])); 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP: list of methods supported by the peer", 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nak_list, len); 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i = sm->user_eap_method_index; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (i < EAP_MAX_METHODS && 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->user->methods[i].vendor != EAP_VENDOR_IETF || 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->methods[i].method != EAP_TYPE_NONE)) { 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user->methods[i].vendor != EAP_VENDOR_IETF) 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto not_found; 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) { 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nak_list[j] == sm->user->methods[i].method) { 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j < len) { 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* found */ 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i++; 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt not_found: 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* not found - remove from the list */ 10441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (i + 1 < EAP_MAX_METHODS) { 10451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memmove(&sm->user->methods[i], 10461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &sm->user->methods[i + 1], 10471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (EAP_MAX_METHODS - i - 1) * 10481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sizeof(sm->user->methods[0])); 10491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->methods[EAP_MAX_METHODS - 1].vendor = 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_VENDOR_IETF; 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->methods[EAP_MAX_METHODS - 1].method = EAP_TYPE_NONE; 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP: new list of configured methods", 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) sm->user->methods, EAP_MAX_METHODS * 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(sm->user->methods[0])); 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list, 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nak_list == NULL || sm == NULL || sm->user == NULL) 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user->phase2) { 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: EAP-Nak received after Phase2 user" 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " info was selected - reject"); 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->decision = DECISION_FAILURE; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_process_nak(sm, nak_list, len); 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor) 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType next; 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int idx = sm->user_eap_method_index; 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* In theory, there should be no problems with starting 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * re-authentication with something else than EAP-Request/Identity and 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this does indeed work with wpa_supplicant. However, at least Funk 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Supplicant seemed to ignore re-auth if it skipped 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-Request/Identity. 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Re-auth sets currentId == -1, so that can be used here to select 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * whether Identity needs to be requested again. */ 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->identity == NULL || sm->currentId == -1) { 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = EAP_VENDOR_IETF; 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = EAP_TYPE_IDENTITY; 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->update_user = TRUE; 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sm->user && idx < EAP_MAX_METHODS && 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->user->methods[idx].vendor != EAP_VENDOR_IETF || 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->methods[idx].method != EAP_TYPE_NONE)) { 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = sm->user->methods[idx].vendor; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = sm->user->methods[idx].method; 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user_eap_method_index++; 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor = EAP_VENDOR_IETF; 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = EAP_TYPE_NONE; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getNextMethod: vendor %d type %d", 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *vendor, next); 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return next; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sm_Policy_getDecision(struct eap_sm *sm) 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->eap_server && sm->identity && !sm->start_reauth) { 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH"); 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return DECISION_PASSTHROUGH; 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->currentMethod != EAP_TYPE_IDENTITY && 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->isSuccess(sm, sm->eap_method_priv)) { 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: method succeeded -> " 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SUCCESS"); 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->update_user = TRUE; 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return DECISION_SUCCESS; 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->m->isDone(sm, sm->eap_method_priv) && 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sm->m->isSuccess(sm, sm->eap_method_priv)) { 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: method failed -> " 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "FAILURE"); 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->update_user = TRUE; 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return DECISION_FAILURE; 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sm->user == NULL || sm->update_user) && sm->identity && 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sm->start_reauth) { 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Allow Identity method to be started once to allow identity 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * selection hint to be sent from the authentication server, 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * but prevent a loop of Identity requests by only allowing 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this to happen once. 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int id_req = 0; 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user && sm->currentMethod == EAP_TYPE_IDENTITY && 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->methods[0].vendor == EAP_VENDOR_IETF && 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->methods[0].method == EAP_TYPE_IDENTITY) 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id_req = 1; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_user_get(sm, sm->identity, sm->identity_len, 0) != 0) { 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: user not " 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found from database -> FAILURE"); 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return DECISION_FAILURE; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (id_req && sm->user && 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->methods[0].vendor == EAP_VENDOR_IETF && 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->methods[0].method == EAP_TYPE_IDENTITY) { 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: stop " 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "identity request loop -> FAILURE"); 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->update_user = TRUE; 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return DECISION_FAILURE; 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->update_user = FALSE; 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->start_reauth = FALSE; 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->user->methods[sm->user_eap_method_index].vendor != 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_VENDOR_IETF || 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->methods[sm->user_eap_method_index].method != 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_TYPE_NONE)) { 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: another method " 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available -> CONTINUE"); 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return DECISION_CONTINUE; 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->identity == NULL || sm->currentId == -1) { 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: no identity known " 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "yet -> CONTINUE"); 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return DECISION_CONTINUE; 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: no more methods available -> " 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "FAILURE"); 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return DECISION_FAILURE; 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method) 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return method == EAP_TYPE_IDENTITY ? TRUE : FALSE; 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_sm_step - Step EAP server state machine 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if EAP state was changed or 0 if not 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function advances EAP state machine to a new state to match with the 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current variables. This should be called whenever variables used by the EAP 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine have changed. 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_server_sm_step(struct eap_sm *sm) 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = 0; 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->changed = FALSE; 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(EAP); 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->changed) 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = 1; 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (sm->changed); 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_user_free(struct eap_user *user) 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (user == NULL) 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(user->password); 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt user->password = NULL; 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(user); 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_sm_init - Allocate and initialize EAP server state machine 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eapol_ctx: Context data to be used with eapol_cb calls 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eapol_cb: Pointer to EAPOL callback functions 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: EAP configuration 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the allocated EAP state machine or %NULL on failure 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function allocates and initializes an EAP state machine. 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sm * eap_server_sm_init(void *eapol_ctx, 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_callbacks *eapol_cb, 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_config *conf) 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *sm; 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm = os_zalloc(sizeof(*sm)); 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_ctx = eapol_ctx; 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapol_cb = eapol_cb; 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->MaxRetrans = 5; /* RFC 3748: max 3-5 retransmissions suggested */ 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ssl_ctx = conf->ssl_ctx; 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->msg_ctx = conf->msg_ctx; 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_sim_db_priv = conf->eap_sim_db_priv; 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->backend_auth = conf->backend_auth; 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_server = conf->eap_server; 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->pac_opaque_encr_key) { 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pac_opaque_encr_key = os_malloc(16); 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->pac_opaque_encr_key) { 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->pac_opaque_encr_key, 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pac_opaque_encr_key, 16); 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->eap_fast_a_id) { 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len); 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap_fast_a_id) { 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->eap_fast_a_id, conf->eap_fast_a_id, 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->eap_fast_a_id_len); 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_fast_a_id_len = conf->eap_fast_a_id_len; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->eap_fast_a_id_info) 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info); 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_fast_prov = conf->eap_fast_prov; 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pac_key_lifetime = conf->pac_key_lifetime; 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pac_key_refresh_time = conf->pac_key_refresh_time; 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->tnc = conf->tnc; 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->wps = conf->wps; 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->assoc_wps_ie) 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_wps_ie = wpabuf_dup(conf->assoc_wps_ie); 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->assoc_p2p_ie) 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->assoc_p2p_ie = wpabuf_dup(conf->assoc_p2p_ie); 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->peer_addr) 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->peer_addr, conf->peer_addr, ETH_ALEN); 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->fragment_size = conf->fragment_size; 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->pwd_group = conf->pwd_group; 128087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen sm->pbc_in_m1 = conf->pbc_in_m1; 128134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt sm->server_id = conf->server_id; 128234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt sm->server_id_len = conf->server_id_len; 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Server state machine created"); 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm; 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_sm_deinit - Deinitialize and free an EAP server state machine 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitializes EAP state machine and frees all allocated 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * resources. 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_server_sm_deinit(struct eap_sm *sm) 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Server state machine removed"); 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->eap_method_priv) 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->reset(sm, sm->eap_method_priv); 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eap_if.eapReqData); 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eap_if.eapKeyData); 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->lastReqData); 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eap_if.eapRespData); 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->identity); 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->pac_opaque_encr_key); 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eap_fast_a_id); 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eap_fast_a_id_info); 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eap_if.aaaEapReqData); 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eap_if.aaaEapRespData); 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->eap_if.aaaEapKeyData); 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_user_free(sm->user); 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->assoc_wps_ie); 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->assoc_p2p_ie); 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_notify_cached - Notify EAP state machine of cached PMK 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called when PMKSA caching is used to skip EAP 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication. 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_notify_cached(struct eap_sm *sm) 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->EAP_state = EAP_SUCCESS; 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_pending_cb - EAP state machine callback for a pending EAP request 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called when data for a pending EAP-Request is received. 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sm_pending_cb(struct eap_sm *sm) 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Callback for pending request received"); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->method_pending == METHOD_PENDING_WAIT) 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->method_pending = METHOD_PENDING_CONT; 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sm_method_pending - Query whether EAP method is waiting for pending data 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if method is waiting for pending data or 0 if not 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_sm_method_pending(struct eap_sm *sm) 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->method_pending == METHOD_PENDING_WAIT; 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_identity - Get the user identity (from EAP-Response/Identity) 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for returning identity length 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the user identity or %NULL if not available 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_get_identity(struct eap_sm *sm, size_t *len) 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = sm->identity_len; 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->identity; 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_get_interface - Get pointer to EAP-EAPOL interface data 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the EAP-EAPOL interface data 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_eapol_interface * eap_get_interface(struct eap_sm *sm) 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return &sm->eap_if; 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_server_clear_identity - Clear EAP identity information 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to clear the EAP identity information in the EAP 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * server context. This allows the EAP/Identity method to be used again after 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAPOL-Start or EAPOL-Logoff. 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_server_clear_identity(struct eap_sm *sm) 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->identity); 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity = NULL; 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1404