1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * hostapd / EAP Full Authenticator state machine (RFC 4137) 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This state machine is based on the full authenticator state machine defined 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * in RFC 4137. However, to support backend authentication in RADIUS 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * authentication server functionality, parts of backend authenticator (also 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * from RFC 4137) are mixed in. This functionality is enabled by setting 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * backend_auth configuration variable to TRUE. 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eap_i.h" 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "state_machine.h" 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define STATE_MACHINE_DATA struct eap_sm 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define STATE_MACHINE_DEBUG_PREFIX "EAP" 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define EAP_MAX_AUTH_ROUNDS 50 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_user_free(struct eap_user *user); 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* EAP state machines are described in RFC 4137 */ 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount, 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int eapSRTT, int eapRTTVAR, 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int methodTimeout); 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp); 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_sm_getId(const struct wpabuf *data); 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id); 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id); 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_sm_nextId(struct eap_sm *sm, int id); 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list, 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len); 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor); 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_sm_Policy_getDecision(struct eap_sm *sm); 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method); 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_copy_buf(struct wpabuf **dst, const struct wpabuf *src) 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (src == NULL) 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(*dst); 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *dst = wpabuf_dup(src); 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return *dst ? 0 : -1; 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_copy_data(u8 **dst, size_t *dst_len, 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *src, size_t src_len) 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (src == NULL) 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(*dst); 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *dst = os_malloc(src_len); 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (*dst) { 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(*dst, src, src_len); 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *dst_len = src_len; 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *dst_len = 0; 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define EAP_COPY(dst, src) \ 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_copy_data((dst), (dst ## Len), (src), (src ## Len)) 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * eap_user_get - Fetch user information from the database 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @identity: Identity (User-Name) of the user 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @identity_len: Length of identity in bytes 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @phase2: 0 = EAP phase1 user, 1 = EAP phase2 (tunneled) user 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, or -1 on failure 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is used to fetch user information for EAP. The user will be 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * selected based on the specified identity. sm->user and 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * sm->user_eap_method_index are updated for the new user when a matching user 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * is found. sm->user can be used to get user information (e.g., password). 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len, 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int phase2) 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_user *user; 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm == NULL || sm->eapol_cb == NULL || 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eapol_cb->get_eap_user == NULL) 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_user_free(sm->user); 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user = NULL; 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt user = os_zalloc(sizeof(*user)); 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (user == NULL) 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity, 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt identity_len, phase2, user) != 0) { 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_user_free(user); 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user = user; 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user_eap_method_index = 0; 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, DISABLED) 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, DISABLED); 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->num_rounds = 0; 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, INITIALIZE) 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, INITIALIZE); 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentId = -1; 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapSuccess = FALSE; 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapFail = FALSE; 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapTimeout = FALSE; 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sm->eap_if.eapKeyData); 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapKeyData = NULL; 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapKeyDataLen = 0; 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapKeyAvailable = FALSE; 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapRestart = FALSE; 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This is not defined in RFC 4137, but method state needs to be 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * reseted here so that it does not remain in success state when 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * re-authentication starts. 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m && sm->eap_method_priv) { 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m->reset(sm, sm->eap_method_priv); 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_method_priv = NULL; 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m = NULL; 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user_eap_method_index = 0; 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->backend_auth) { 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentMethod = EAP_TYPE_NONE; 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* parse rxResp, respId, respMethod */ 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->rxResp) { 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentId = sm->respId; 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->num_rounds = 0; 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->method_pending = METHOD_PENDING_NONE; 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, PICK_UP_METHOD) 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, PICK_UP_METHOD); 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_sm_Policy_doPickUp(sm, sm->respMethod)) { 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentMethod = sm->respMethod; 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m && sm->eap_method_priv) { 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m->reset(sm, sm->eap_method_priv); 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_method_priv = NULL; 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m = eap_server_get_eap_method(EAP_VENDOR_IETF, 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentMethod); 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m && sm->m->initPickUp) { 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_method_priv = sm->m->initPickUp(sm); 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_method_priv == NULL) { 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Failed to " 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "initialize EAP method %d", 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentMethod); 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m = NULL; 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentMethod = EAP_TYPE_NONE; 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m = NULL; 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentMethod = EAP_TYPE_NONE; 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, IDLE) 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, IDLE); 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.retransWhile = eap_sm_calculateTimeout( 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR, 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->methodTimeout); 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, RETRANSMIT) 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, RETRANSMIT); 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->retransCount++; 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) { 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0) 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReq = TRUE; 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, RECEIVED) 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, RECEIVED); 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* parse rxResp, respId, respMethod */ 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->num_rounds++; 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, DISCARD) 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, DISCARD); 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapResp = FALSE; 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapNoReq = TRUE; 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, SEND_REQUEST) 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, SEND_REQUEST); 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->retransCount = 0; 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_if.eapReqData) { 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0) 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapResp = FALSE; 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReq = TRUE; 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapResp = FALSE; 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReq = FALSE; 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP: SEND_REQUEST - no eapReqData"); 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapResp = FALSE; 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReq = FALSE; 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapNoReq = TRUE; 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, INTEGRITY_CHECK) 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, INTEGRITY_CHECK); 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m->check) { 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->ignore = sm->m->check(sm, sm->eap_method_priv, 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapRespData); 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, METHOD_REQUEST) 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, METHOD_REQUEST); 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m == NULL) { 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: method not initialized"); 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentId = eap_sm_nextId(sm, sm->currentId); 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: building EAP-Request: Identifier %d", 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentId); 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->lastId = sm->currentId; 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->eap_if.eapReqData); 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReqData = sm->m->buildReq(sm, sm->eap_method_priv, 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentId); 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m->getTimeout) 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->methodTimeout = sm->m->getTimeout(sm, sm->eap_method_priv); 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->methodTimeout = 0; 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, METHOD_RESPONSE) 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, METHOD_RESPONSE); 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData); 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m->isDone(sm, sm->eap_method_priv)) { 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sm_Policy_update(sm, NULL, 0); 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sm->eap_if.eapKeyData); 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m->getKey) { 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapKeyData = sm->m->getKey( 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm, sm->eap_method_priv, 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &sm->eap_if.eapKeyDataLen); 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapKeyData = NULL; 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapKeyDataLen = 0; 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->methodState = METHOD_END; 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->methodState = METHOD_CONTINUE; 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, PROPOSE_METHOD) 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int vendor; 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EapType type; 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, PROPOSE_METHOD); 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt type = eap_sm_Policy_getNextMethod(sm, &vendor); 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (vendor == EAP_VENDOR_IETF) 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentMethod = type; 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentMethod = EAP_TYPE_EXPANDED; 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m && sm->eap_method_priv) { 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m->reset(sm, sm->eap_method_priv); 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_method_priv = NULL; 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m = eap_server_get_eap_method(vendor, type); 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m) { 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_method_priv = sm->m->init(sm); 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_method_priv == NULL) { 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Failed to initialize EAP " 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "method %d", sm->currentMethod); 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m = NULL; 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentMethod = EAP_TYPE_NONE; 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->currentMethod == EAP_TYPE_IDENTITY || 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentMethod == EAP_TYPE_NOTIFICATION) 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->methodState = METHOD_CONTINUE; 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->methodState = METHOD_PROPOSED; 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, NAK) 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct eap_hdr *nak; 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len = 0; 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *pos; 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *nak_list = NULL; 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, NAK); 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_method_priv) { 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m->reset(sm, sm->eap_method_priv); 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_method_priv = NULL; 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m = NULL; 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt nak = wpabuf_head(sm->eap_if.eapRespData); 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (nak && wpabuf_len(sm->eap_if.eapRespData) > sizeof(*nak)) { 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len = be_to_host16(nak->length); 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (len > wpabuf_len(sm->eap_if.eapRespData)) 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len = wpabuf_len(sm->eap_if.eapRespData); 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = (const u8 *) (nak + 1); 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len -= sizeof(*nak); 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (*pos == EAP_TYPE_NAK) { 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos++; 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len--; 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt nak_list = pos; 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sm_Policy_update(sm, nak_list, len); 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, SELECT_ACTION) 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, SELECT_ACTION); 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->decision = eap_sm_Policy_getDecision(sm); 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, TIMEOUT_FAILURE) 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, TIMEOUT_FAILURE); 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapTimeout = TRUE; 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, FAILURE) 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, FAILURE); 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->eap_if.eapReqData); 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId); 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->lastReqData); 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->lastReqData = NULL; 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapFail = TRUE; 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, SUCCESS) 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, SUCCESS); 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->eap_if.eapReqData); 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId); 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->lastReqData); 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->lastReqData = NULL; 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_if.eapKeyData) 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapKeyAvailable = TRUE; 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapSuccess = TRUE; 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, INITIALIZE_PASSTHROUGH) 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH); 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->eap_if.aaaEapRespData); 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.aaaEapRespData = NULL; 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, IDLE2) 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, IDLE2); 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.retransWhile = eap_sm_calculateTimeout( 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR, 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->methodTimeout); 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, RETRANSMIT2) 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, RETRANSMIT2); 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->retransCount++; 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) { 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0) 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReq = TRUE; 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, RECEIVED2) 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, RECEIVED2); 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* parse rxResp, respId, respMethod */ 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sm_parseEapResp(sm, sm->eap_if.eapRespData); 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, DISCARD2) 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, DISCARD2); 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapResp = FALSE; 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapNoReq = TRUE; 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, SEND_REQUEST2) 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, SEND_REQUEST2); 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->retransCount = 0; 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_if.eapReqData) { 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0) 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapResp = FALSE; 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReq = TRUE; 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapResp = FALSE; 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReq = FALSE; 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP: SEND_REQUEST2 - no eapReqData"); 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapResp = FALSE; 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapReq = FALSE; 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapNoReq = TRUE; 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, AAA_REQUEST) 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, AAA_REQUEST); 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_if.eapRespData == NULL) { 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "EAP: AAA_REQUEST - no eapRespData"); 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * if (respMethod == IDENTITY) 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * aaaIdentity = eapRespData 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This is already taken care of by the EAP-Identity method which 514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * stores the identity into sm->identity. 515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_copy_buf(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData); 518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, AAA_RESPONSE) 522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, AAA_RESPONSE); 524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->currentId = eap_sm_getId(sm->eap_if.eapReqData); 527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->methodTimeout = sm->eap_if.aaaMethodTimeout; 528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, AAA_IDLE) 532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, AAA_IDLE); 534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 535526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.aaaFail = FALSE; 536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.aaaSuccess = FALSE; 537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.aaaEapReq = FALSE; 538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.aaaEapNoReq = FALSE; 539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.aaaEapResp = TRUE; 540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 543526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, TIMEOUT_FAILURE2) 544526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, TIMEOUT_FAILURE2); 546526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 547526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapTimeout = TRUE; 548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 549526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 551526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, FAILURE2) 552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 553526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, FAILURE2); 554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapFail = TRUE; 557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STATE(EAP, SUCCESS2) 561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTRY(EAP, SUCCESS2); 563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData); 565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapKeyAvailable = sm->eap_if.aaaEapKeyAvailable; 567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_if.aaaEapKeyAvailable) { 568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData); 569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sm->eap_if.eapKeyData); 571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapKeyData = NULL; 572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapKeyDataLen = 0; 573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_if.eapSuccess = TRUE; 576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Start reauthentication with identity request even though we know the 579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * previously used identity. This is needed to get reauthentication 580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * started properly. 581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->start_reauth = TRUE; 583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtSM_STEP(EAP) 587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_if.eapRestart && sm->eap_if.portEnabled) 589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER_GLOBAL(EAP, INITIALIZE); 590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!sm->eap_if.portEnabled) 591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER_GLOBAL(EAP, DISABLED); 592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { 593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { 594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: more than %d " 595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "authentication rounds - abort", 596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_MAX_AUTH_ROUNDS); 597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->num_rounds++; 598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER_GLOBAL(EAP, FAILURE); 599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else switch (sm->EAP_state) { 601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_INITIALIZE: 602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->backend_auth) { 603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!sm->rxResp) 604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, SELECT_ACTION); 605526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->rxResp && 606526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (sm->respMethod == EAP_TYPE_NAK || 607526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (sm->respMethod == EAP_TYPE_EXPANDED && 608526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendor == EAP_VENDOR_IETF && 609526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendorMethod == EAP_TYPE_NAK))) 610526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, NAK); 611526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 612526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, PICK_UP_METHOD); 613526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 614526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, SELECT_ACTION); 615526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 616526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 617526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_PICK_UP_METHOD: 618526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->currentMethod == EAP_TYPE_NONE) { 619526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, SELECT_ACTION); 620526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 621526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, METHOD_RESPONSE); 622526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 623526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 624526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_DISABLED: 625526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_if.portEnabled) 626526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, INITIALIZE); 627526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 628526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_IDLE: 629526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_if.retransWhile == 0) 630526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, RETRANSMIT); 631526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->eap_if.eapResp) 632526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, RECEIVED); 633526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 634526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_RETRANSMIT: 635526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->retransCount > sm->MaxRetrans) 636526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, TIMEOUT_FAILURE); 637526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 638526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, IDLE); 639526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 640526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_RECEIVED: 641526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->rxResp && (sm->respId == sm->currentId) && 642526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (sm->respMethod == EAP_TYPE_NAK || 643526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (sm->respMethod == EAP_TYPE_EXPANDED && 644526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendor == EAP_VENDOR_IETF && 645526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendorMethod == EAP_TYPE_NAK)) 646526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt && (sm->methodState == METHOD_PROPOSED)) 647526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, NAK); 648526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->rxResp && (sm->respId == sm->currentId) && 649526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ((sm->respMethod == sm->currentMethod) || 650526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (sm->respMethod == EAP_TYPE_EXPANDED && 651526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendor == EAP_VENDOR_IETF && 652526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendorMethod == sm->currentMethod))) 653526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, INTEGRITY_CHECK); 654526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else { 655526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: RECEIVED->DISCARD: " 656526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "rxResp=%d respId=%d currentId=%d " 657526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "respMethod=%d currentMethod=%d", 658526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->rxResp, sm->respId, sm->currentId, 659526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respMethod, sm->currentMethod); 660526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, DISCARD); 661526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 662526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 663526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_DISCARD: 664526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, IDLE); 665526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 666526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_SEND_REQUEST: 667526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, IDLE); 668526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 669526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_INTEGRITY_CHECK: 670526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->ignore) 671526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, DISCARD); 672526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 673526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, METHOD_RESPONSE); 674526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 675526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_METHOD_REQUEST: 676526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, SEND_REQUEST); 677526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 678526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_METHOD_RESPONSE: 679526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 680526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Note: Mechanism to allow EAP methods to wait while going 681526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * through pending processing is an extension to RFC 4137 682526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * which only defines the transits to SELECT_ACTION and 683526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * METHOD_REQUEST from this METHOD_RESPONSE state. 684526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 685526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->methodState == METHOD_END) 686526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, SELECT_ACTION); 687526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->method_pending == METHOD_PENDING_WAIT) { 688526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Method has pending " 689526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "processing - wait before proceeding to " 690526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "METHOD_REQUEST state"); 691526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (sm->method_pending == METHOD_PENDING_CONT) { 692526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Method has completed " 693526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "pending processing - reprocess pending " 694526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "EAP message"); 695526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->method_pending = METHOD_PENDING_NONE; 696526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, METHOD_RESPONSE); 697526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else 698526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, METHOD_REQUEST); 699526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 700526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_PROPOSE_METHOD: 701526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 702526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Note: Mechanism to allow EAP methods to wait while going 703526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * through pending processing is an extension to RFC 4137 704526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * which only defines the transit to METHOD_REQUEST from this 705526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * PROPOSE_METHOD state. 706526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 707526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->method_pending == METHOD_PENDING_WAIT) { 708526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Method has pending " 709526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "processing - wait before proceeding to " 710526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "METHOD_REQUEST state"); 711526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->user_eap_method_index > 0) 712526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user_eap_method_index--; 713526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (sm->method_pending == METHOD_PENDING_CONT) { 714526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Method has completed " 715526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "pending processing - reprocess pending " 716526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "EAP message"); 717526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->method_pending = METHOD_PENDING_NONE; 718526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, PROPOSE_METHOD); 719526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else 720526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, METHOD_REQUEST); 721526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 722526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_NAK: 723526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, SELECT_ACTION); 724526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 725526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_SELECT_ACTION: 726526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->decision == DECISION_FAILURE) 727526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, FAILURE); 728526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->decision == DECISION_SUCCESS) 729526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, SUCCESS); 730526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->decision == DECISION_PASSTHROUGH) 731526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, INITIALIZE_PASSTHROUGH); 732526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 733526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, PROPOSE_METHOD); 734526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 735526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_TIMEOUT_FAILURE: 736526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 737526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_FAILURE: 738526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 739526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_SUCCESS: 740526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 741526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 742526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_INITIALIZE_PASSTHROUGH: 743526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->currentId == -1) 744526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, AAA_IDLE); 745526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 746526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, AAA_REQUEST); 747526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 748526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_IDLE2: 749526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_if.eapResp) 750526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, RECEIVED2); 751526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->eap_if.retransWhile == 0) 752526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, RETRANSMIT2); 753526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 754526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_RETRANSMIT2: 755526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->retransCount > sm->MaxRetrans) 756526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, TIMEOUT_FAILURE2); 757526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 758526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, IDLE2); 759526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 760526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_RECEIVED2: 761526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->rxResp && (sm->respId == sm->currentId)) 762526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, AAA_REQUEST); 763526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 764526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, DISCARD2); 765526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 766526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_DISCARD2: 767526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, IDLE2); 768526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 769526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_SEND_REQUEST2: 770526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, IDLE2); 771526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 772526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_AAA_REQUEST: 773526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, AAA_IDLE); 774526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 775526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_AAA_RESPONSE: 776526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, SEND_REQUEST2); 777526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 778526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_AAA_IDLE: 779526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_if.aaaFail) 780526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, FAILURE2); 781526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->eap_if.aaaSuccess) 782526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, SUCCESS2); 783526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->eap_if.aaaEapReq) 784526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, AAA_RESPONSE); 785526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (sm->eap_if.aaaTimeout) 786526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_ENTER(EAP, TIMEOUT_FAILURE2); 787526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 788526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_TIMEOUT_FAILURE2: 789526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 790526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_FAILURE2: 791526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 792526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case EAP_SUCCESS2: 793526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 794526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 795526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 796526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 797526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 798526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount, 799526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int eapSRTT, int eapRTTVAR, 800526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int methodTimeout) 801526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 802526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int rto, i; 803526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 804526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (methodTimeout) { 805526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 806526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * EAP method (either internal or through AAA server, provided 807526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * timeout hint. Use that as-is as a timeout for retransmitting 808526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * the EAP request if no response is received. 809526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 810526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds " 811526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "(from EAP method hint)", methodTimeout); 812526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return methodTimeout; 813526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 814526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 815526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 816526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * RFC 3748 recommends algorithms described in RFC 2988 for estimation 817526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * of the retransmission timeout. This should be implemented once 818526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * round-trip time measurements are available. For nowm a simple 819526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * backoff mechanism is used instead if there are no EAP method 820526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * specific hints. 821526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 822526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * SRTT = smoothed round-trip time 823526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * RTTVAR = round-trip time variation 824526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * RTO = retransmission timeout 825526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 826526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 827526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 828526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * RFC 2988, 2.1: before RTT measurement, set RTO to 3 seconds for 829526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * initial retransmission and then double the RTO to provide back off 830526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * per 5.5. Limit the maximum RTO to 20 seconds per RFC 3748, 4.3 831526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * modified RTOmax. 832526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 833526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rto = 3; 834526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < retransCount; i++) { 835526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rto *= 2; 836526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (rto >= 20) { 837526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rto = 20; 838526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 839526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 840526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 841526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 842526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds " 843526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "(from dynamic back off; retransCount=%d)", 844526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rto, retransCount); 845526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 846526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return rto; 847526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 848526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 849526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 850526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp) 851526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 852526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct eap_hdr *hdr; 853526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t plen; 854526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 855526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* parse rxResp, respId, respMethod */ 856526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->rxResp = FALSE; 857526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respId = -1; 858526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respMethod = EAP_TYPE_NONE; 859526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendor = EAP_VENDOR_IETF; 860526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendorMethod = EAP_TYPE_NONE; 861526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 862526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (resp == NULL || wpabuf_len(resp) < sizeof(*hdr)) { 863526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p " 864526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "len=%lu", resp, 865526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt resp ? (unsigned long) wpabuf_len(resp) : 0); 866526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 867526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 868526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 869526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hdr = wpabuf_head(resp); 870526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt plen = be_to_host16(hdr->length); 871526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (plen > wpabuf_len(resp)) { 872526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet " 873526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "(len=%lu plen=%lu)", 874526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (unsigned long) wpabuf_len(resp), 875526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (unsigned long) plen); 876526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 877526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 878526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 879526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respId = hdr->identifier; 880526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 881526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (hdr->code == EAP_CODE_RESPONSE) 882526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->rxResp = TRUE; 883526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 884526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (plen > sizeof(*hdr)) { 885526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *pos = (u8 *) (hdr + 1); 886526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respMethod = *pos++; 887526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->respMethod == EAP_TYPE_EXPANDED) { 888526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (plen < sizeof(*hdr) + 8) { 889526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Ignored truncated " 890526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "expanded EAP-Packet (plen=%lu)", 891526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (unsigned long) plen); 892526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 893526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 894526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendor = WPA_GET_BE24(pos); 895526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += 3; 896526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendorMethod = WPA_GET_BE32(pos); 897526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 898526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 899526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 900526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: parseEapResp: rxResp=%d respId=%d " 901526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "respMethod=%u respVendor=%u respVendorMethod=%u", 902526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->rxResp, sm->respId, sm->respMethod, sm->respVendor, 903526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->respVendorMethod); 904526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 905526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 906526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 907526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_sm_getId(const struct wpabuf *data) 908526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 909526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct eap_hdr *hdr; 910526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 911526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data == NULL || wpabuf_len(data) < sizeof(*hdr)) 912526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 913526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 914526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hdr = wpabuf_head(data); 915526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getId: id=%d", hdr->identifier); 916526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return hdr->identifier; 917526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 918526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 919526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 920526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id) 921526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 922526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpabuf *msg; 923526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_hdr *resp; 924526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (id=%d)", id); 925526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 926526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg = wpabuf_alloc(sizeof(*resp)); 927526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (msg == NULL) 928526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 929526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt resp = wpabuf_put(msg, sizeof(*resp)); 930526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt resp->code = EAP_CODE_SUCCESS; 931526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt resp->identifier = id; 932526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt resp->length = host_to_be16(sizeof(*resp)); 933526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 934526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return msg; 935526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 936526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 937526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 938526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id) 939526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 940526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpabuf *msg; 941526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_hdr *resp; 942526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id); 943526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 944526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg = wpabuf_alloc(sizeof(*resp)); 945526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (msg == NULL) 946526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 947526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt resp = wpabuf_put(msg, sizeof(*resp)); 948526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt resp->code = EAP_CODE_FAILURE; 949526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt resp->identifier = id; 950526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt resp->length = host_to_be16(sizeof(*resp)); 951526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 952526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return msg; 953526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 954526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 955526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 956526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_sm_nextId(struct eap_sm *sm, int id) 957526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 958526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (id < 0) { 959526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* RFC 3748 Ch 4.1: recommended to initialize Identifier with a 960526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * random number */ 961526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id = rand() & 0xff; 962526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (id != sm->lastId) 963526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return id; 964526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 965526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return (id + 1) & 0xff; 966526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 967526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 968526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 969526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 970526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * eap_sm_process_nak - Process EAP-Response/Nak 971526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 972526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @nak_list: Nak list (allowed methods) from the supplicant 973526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @len: Length of nak_list in bytes 974526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 975526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is called when EAP-Response/Nak is received from the 976526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * supplicant. This can happen for both phase 1 and phase 2 authentications. 977526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 978526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len) 979526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 980526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i; 981526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t j; 982526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 983526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->user == NULL) 984526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 985526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 986526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "EAP: processing NAK (current EAP method " 987526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "index %d)", sm->user_eap_method_index); 988526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 989526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP: configured methods", 990526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (u8 *) sm->user->methods, 991526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_MAX_METHODS * sizeof(sm->user->methods[0])); 992526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP: list of methods supported by the peer", 993526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt nak_list, len); 994526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 995526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt i = sm->user_eap_method_index; 996526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (i < EAP_MAX_METHODS && 997526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (sm->user->methods[i].vendor != EAP_VENDOR_IETF || 998526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user->methods[i].method != EAP_TYPE_NONE)) { 999526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->user->methods[i].vendor != EAP_VENDOR_IETF) 1000526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto not_found; 1001526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (j = 0; j < len; j++) { 1002526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (nak_list[j] == sm->user->methods[i].method) { 1003526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 1004526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1005526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1006526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1007526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (j < len) { 1008526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* found */ 1009526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt i++; 1010526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt continue; 1011526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1012526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1013526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt not_found: 1014526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* not found - remove from the list */ 1015526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memmove(&sm->user->methods[i], &sm->user->methods[i + 1], 1016526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (EAP_MAX_METHODS - i - 1) * 1017526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(sm->user->methods[0])); 1018526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user->methods[EAP_MAX_METHODS - 1].vendor = 1019526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_VENDOR_IETF; 1020526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user->methods[EAP_MAX_METHODS - 1].method = EAP_TYPE_NONE; 1021526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1022526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1023526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP: new list of configured methods", 1024526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (u8 *) sm->user->methods, EAP_MAX_METHODS * 1025526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(sm->user->methods[0])); 1026526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1027526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1028526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1029526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list, 1030526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len) 1031526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1032526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (nak_list == NULL || sm == NULL || sm->user == NULL) 1033526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 1034526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1035526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->user->phase2) { 1036526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: EAP-Nak received after Phase2 user" 1037526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt " info was selected - reject"); 1038526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->decision = DECISION_FAILURE; 1039526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 1040526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1041526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1042526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_sm_process_nak(sm, nak_list, len); 1043526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1044526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1045526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1046526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor) 1047526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1048526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EapType next; 1049526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int idx = sm->user_eap_method_index; 1050526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1051526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* In theory, there should be no problems with starting 1052526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * re-authentication with something else than EAP-Request/Identity and 1053526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * this does indeed work with wpa_supplicant. However, at least Funk 1054526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Supplicant seemed to ignore re-auth if it skipped 1055526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * EAP-Request/Identity. 1056526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Re-auth sets currentId == -1, so that can be used here to select 1057526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * whether Identity needs to be requested again. */ 1058526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->identity == NULL || sm->currentId == -1) { 1059526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *vendor = EAP_VENDOR_IETF; 1060526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next = EAP_TYPE_IDENTITY; 1061526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->update_user = TRUE; 1062526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (sm->user && idx < EAP_MAX_METHODS && 1063526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (sm->user->methods[idx].vendor != EAP_VENDOR_IETF || 1064526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user->methods[idx].method != EAP_TYPE_NONE)) { 1065526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *vendor = sm->user->methods[idx].vendor; 1066526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next = sm->user->methods[idx].method; 1067526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user_eap_method_index++; 1068526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 1069526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *vendor = EAP_VENDOR_IETF; 1070526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next = EAP_TYPE_NONE; 1071526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1072526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getNextMethod: vendor %d type %d", 1073526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *vendor, next); 1074526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return next; 1075526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1076526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1077526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1078526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int eap_sm_Policy_getDecision(struct eap_sm *sm) 1079526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1080526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!sm->eap_server && sm->identity && !sm->start_reauth) { 1081526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH"); 1082526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return DECISION_PASSTHROUGH; 1083526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1084526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1085526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m && sm->currentMethod != EAP_TYPE_IDENTITY && 1086526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m->isSuccess(sm, sm->eap_method_priv)) { 1087526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: method succeeded -> " 1088526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "SUCCESS"); 1089526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->update_user = TRUE; 1090526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return DECISION_SUCCESS; 1091526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1092526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1093526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m && sm->m->isDone(sm, sm->eap_method_priv) && 1094526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt !sm->m->isSuccess(sm, sm->eap_method_priv)) { 1095526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: method failed -> " 1096526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "FAILURE"); 1097526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->update_user = TRUE; 1098526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return DECISION_FAILURE; 1099526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((sm->user == NULL || sm->update_user) && sm->identity && 1102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt !sm->start_reauth) { 1103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 1104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Allow Identity method to be started once to allow identity 1105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * selection hint to be sent from the authentication server, 1106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * but prevent a loop of Identity requests by only allowing 1107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * this to happen once. 1108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int id_req = 0; 1110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->user && sm->currentMethod == EAP_TYPE_IDENTITY && 1111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user->methods[0].vendor == EAP_VENDOR_IETF && 1112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user->methods[0].method == EAP_TYPE_IDENTITY) 1113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt id_req = 1; 1114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eap_user_get(sm, sm->identity, sm->identity_len, 0) != 0) { 1115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: user not " 1116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "found from database -> FAILURE"); 1117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return DECISION_FAILURE; 1118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (id_req && sm->user && 1120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user->methods[0].vendor == EAP_VENDOR_IETF && 1121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user->methods[0].method == EAP_TYPE_IDENTITY) { 1122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: stop " 1123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "identity request loop -> FAILURE"); 1124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->update_user = TRUE; 1125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return DECISION_FAILURE; 1126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->update_user = FALSE; 1128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->start_reauth = FALSE; 1130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && 1132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (sm->user->methods[sm->user_eap_method_index].vendor != 1133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_VENDOR_IETF || 1134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->user->methods[sm->user_eap_method_index].method != 1135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EAP_TYPE_NONE)) { 1136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: another method " 1137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "available -> CONTINUE"); 1138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return DECISION_CONTINUE; 1139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->identity == NULL || sm->currentId == -1) { 1142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: no identity known " 1143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "yet -> CONTINUE"); 1144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return DECISION_CONTINUE; 1145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: getDecision: no more methods available -> " 1148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "FAILURE"); 1149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return DECISION_FAILURE; 1150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method) 1154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return method == EAP_TYPE_IDENTITY ? TRUE : FALSE; 1156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * eap_server_sm_step - Step EAP server state machine 1161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 1 if EAP state was changed or 0 if not 1163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 1164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function advances EAP state machine to a new state to match with the 1165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * current variables. This should be called whenever variables used by the EAP 1166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * state machine have changed. 1167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eap_server_sm_step(struct eap_sm *sm) 1169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int res = 0; 1171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt do { 1172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->changed = FALSE; 1173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SM_STEP_RUN(EAP); 1174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->changed) 1175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = 1; 1176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } while (sm->changed); 1177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return res; 1178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eap_user_free(struct eap_user *user) 1182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (user == NULL) 1184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 1185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(user->password); 1186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt user->password = NULL; 1187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(user); 1188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * eap_server_sm_init - Allocate and initialize EAP server state machine 1193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @eapol_ctx: Context data to be used with eapol_cb calls 1194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @eapol_cb: Pointer to EAPOL callback functions 1195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @conf: EAP configuration 1196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: Pointer to the allocated EAP state machine or %NULL on failure 1197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 1198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function allocates and initializes an EAP state machine. 1199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct eap_sm * eap_server_sm_init(void *eapol_ctx, 1201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eapol_callbacks *eapol_cb, 1202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_config *conf) 1203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eap_sm *sm; 1205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm = os_zalloc(sizeof(*sm)); 1207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm == NULL) 1208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 1209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eapol_ctx = eapol_ctx; 1210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eapol_cb = eapol_cb; 1211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->MaxRetrans = 5; /* RFC 3748: max 3-5 retransmissions suggested */ 1212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->ssl_ctx = conf->ssl_ctx; 1213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_sim_db_priv = conf->eap_sim_db_priv; 1214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->backend_auth = conf->backend_auth; 1215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_server = conf->eap_server; 1216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conf->pac_opaque_encr_key) { 1217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->pac_opaque_encr_key = os_malloc(16); 1218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->pac_opaque_encr_key) { 1219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(sm->pac_opaque_encr_key, 1220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conf->pac_opaque_encr_key, 16); 1221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conf->eap_fast_a_id) { 1224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len); 1225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->eap_fast_a_id) { 1226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(sm->eap_fast_a_id, conf->eap_fast_a_id, 1227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conf->eap_fast_a_id_len); 1228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_fast_a_id_len = conf->eap_fast_a_id_len; 1229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conf->eap_fast_a_id_info) 1232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info); 1233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_fast_prov = conf->eap_fast_prov; 1234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->pac_key_lifetime = conf->pac_key_lifetime; 1235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->pac_key_refresh_time = conf->pac_key_refresh_time; 1236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; 1237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->tnc = conf->tnc; 1238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->wps = conf->wps; 1239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conf->assoc_wps_ie) 1240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->assoc_wps_ie = wpabuf_dup(conf->assoc_wps_ie); 1241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Server state machine created"); 1243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return sm; 1245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * eap_server_sm_deinit - Deinitialize and free an EAP server state machine 1250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 1252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function deinitializes EAP state machine and frees all allocated 1253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * resources. 1254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid eap_server_sm_deinit(struct eap_sm *sm) 1256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm == NULL) 1258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 1259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Server state machine removed"); 1260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->m && sm->eap_method_priv) 1261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->m->reset(sm, sm->eap_method_priv); 1262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->eap_if.eapReqData); 1263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sm->eap_if.eapKeyData); 1264dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt wpabuf_free(sm->lastReqData); 1265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->eap_if.eapRespData); 1266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sm->identity); 1267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sm->pac_opaque_encr_key); 1268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sm->eap_fast_a_id); 1269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sm->eap_fast_a_id_info); 1270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->eap_if.aaaEapReqData); 1271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->eap_if.aaaEapRespData); 1272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sm->eap_if.aaaEapKeyData); 1273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eap_user_free(sm->user); 1274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(sm->assoc_wps_ie); 1275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sm); 1276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * eap_sm_notify_cached - Notify EAP state machine of cached PMK 1281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 1283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is called when PMKSA caching is used to skip EAP 1284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * authentication. 1285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid eap_sm_notify_cached(struct eap_sm *sm) 1287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm == NULL) 1289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 1290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->EAP_state = EAP_SUCCESS; 1292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * eap_sm_pending_cb - EAP state machine callback for a pending EAP request 1297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 1299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is called when data for a pending EAP-Request is received. 1300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid eap_sm_pending_cb(struct eap_sm *sm) 1302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm == NULL) 1304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 1305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "EAP: Callback for pending request received"); 1306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm->method_pending == METHOD_PENDING_WAIT) 1307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sm->method_pending = METHOD_PENDING_CONT; 1308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * eap_sm_method_pending - Query whether EAP method is waiting for pending data 1313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 1 if method is waiting for pending data or 0 if not 1315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eap_sm_method_pending(struct eap_sm *sm) 1317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sm == NULL) 1319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 1320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return sm->method_pending == METHOD_PENDING_WAIT; 1321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * eap_get_identity - Get the user identity (from EAP-Response/Identity) 1326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @len: Buffer for returning identity length 1328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: Pointer to the user identity or %NULL if not available 1329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtconst u8 * eap_get_identity(struct eap_sm *sm, size_t *len) 1331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *len = sm->identity_len; 1333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return sm->identity; 1334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * eap_get_interface - Get pointer to EAP-EAPOL interface data 1339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() 1340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: Pointer to the EAP-EAPOL interface data 1341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct eap_eapol_interface * eap_get_interface(struct eap_sm *sm) 1343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return &sm->eap_if; 1345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1346