18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAPOL supplicant state machines 361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "state_machine.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpabuf.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/crypto.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/md5.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/eapol_common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_peer/eap.h" 19f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "eap_peer/eap_proxy.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_supp_sm.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DATA struct eapol_sm 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DEBUG_PREFIX "EAPOL" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* IEEE 802.1X-2004 - Supplicant - EAPOL state machines */ 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct eapol_sm - Internal data for EAPOL state machines 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eapol_sm { 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Timers */ 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int authWhile; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int heldWhile; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int startWhen; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int idleWhile; /* for EAP state machine */ 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int timer_tick_enabled; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Global variables */ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapFail; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapolEap; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapSuccess; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean initialize; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean keyDone; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean keyRun; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PortControl portControl; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean portEnabled; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PortStatus suppPortStatus; /* dot1xSuppControlledPortStatus */ 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean portValid; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean suppAbort; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean suppFail; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean suppStart; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean suppSuccess; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean suppTimeout; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supplicant PAE state machine */ 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_UNKNOWN = 0, 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_DISCONNECTED = 1, 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_LOGOFF = 2, 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_CONNECTING = 3, 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_AUTHENTICATING = 4, 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_AUTHENTICATED = 5, 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* unused(6) */ 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_HELD = 7, 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_RESTART = 8, 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_S_FORCE_AUTH = 9, 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_S_FORCE_UNAUTH = 10 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } SUPP_PAE_state; /* dot1xSuppPaeState */ 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Variables */ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean userLogoff; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean logoffSent; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int startCount; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapRestart; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PortControl sPortMode; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Constants */ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int heldPeriod; /* dot1xSuppHeldPeriod */ 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int startPeriod; /* dot1xSuppStartPeriod */ 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int maxStart; /* dot1xSuppMaxStart */ 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Key Receive state machine */ 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt KEY_RX_UNKNOWN = 0, 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt KEY_RX_NO_KEY_RECEIVE, KEY_RX_KEY_RECEIVE 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } KEY_RX_state; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Variables */ 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean rxKey; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supplicant Backend state machine */ 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_UNKNOWN = 0, 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_INITIALIZE = 1, 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_IDLE = 2, 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_REQUEST = 3, 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_RECEIVE = 4, 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_RESPONSE = 5, 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_FAIL = 6, 98293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt SUPP_BE_TIMEOUT = 7, 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_SUCCESS = 8 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } SUPP_BE_state; /* dot1xSuppBackendPaeState */ 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Variables */ 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapNoResp; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapReq; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapResp; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Constants */ 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int authPeriod; /* dot1xSuppAuthPeriod */ 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Statistics */ 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolFramesRx; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolFramesTx; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolStartFramesTx; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolLogoffFramesTx; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolRespFramesTx; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolReqIdFramesRx; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolReqFramesRx; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppInvalidEapolFramesRx; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapLengthErrorFramesRx; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppLastEapolFrameVersion; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char dot1xSuppLastEapolFrameSource[6]; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Miscellaneous variables (not defined in IEEE 802.1X-2004) */ 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean changed; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *eap; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean initial_req; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *last_rx_key; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t last_rx_key_len; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *eapReqData; /* for EAP */ 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean altAccept; /* for EAP */ 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean altReject; /* for EAP */ 1316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt Boolean eapTriggerStart; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean replay_counter_valid; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 last_replay_counter[16]; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_config conf; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_ctx *ctx; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { EAPOL_CB_IN_PROGRESS = 0, EAPOL_CB_SUCCESS, EAPOL_CB_FAILURE } 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb_status; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean cached_pmk; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean unicast_key_received, broadcast_key_received; 141fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 142fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt Boolean force_authorized_update; 143fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 144f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 145f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt Boolean use_eap_proxy; 146f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct eap_proxy_sm *eap_proxy; 147f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txLogoff(struct eapol_sm *sm); 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txStart(struct eapol_sm *sm); 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_processKey(struct eapol_sm *sm); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_getSuppRsp(struct eapol_sm *sm); 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txSuppRsp(struct eapol_sm *sm); 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_abortSupp(struct eapol_sm *sm); 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_abort_cached(struct eapol_sm *sm); 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx); 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_port_authorized(struct eapol_sm *sm); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_port_unauthorized(struct eapol_sm *sm); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Port Timers state machine - implemented as a function that will be called 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * once a second as a registered event loop timeout */ 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx) 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = timeout_ctx; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->authWhile > 0) { 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authWhile--; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->authWhile == 0) 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: authWhile --> 0"); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->heldWhile > 0) { 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldWhile--; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->heldWhile == 0) 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: heldWhile --> 0"); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->startWhen > 0) { 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startWhen--; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->startWhen == 0) 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: startWhen --> 0"); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->idleWhile > 0) { 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->idleWhile--; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->idleWhile == 0) 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: idleWhile --> 0"); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->authWhile | sm->heldWhile | sm->startWhen | sm->idleWhile) { 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx, 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: disable timer tick"); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->timer_tick_enabled = 0; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_enable_timer_tick(struct eapol_sm *sm) 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->timer_tick_enabled) 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: enable timer tick"); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->timer_tick_enabled = 1; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, LOGOFF) 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, LOGOFF); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_txLogoff(sm); 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->logoffSent = TRUE; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_unauthorized(sm); 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, DISCONNECTED) 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, DISCONNECTED); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->sPortMode = Auto; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startCount = 0; 2266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapTriggerStart = FALSE; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->logoffSent = FALSE; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_unauthorized(sm); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppAbort = TRUE; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->unicast_key_received = FALSE; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->broadcast_key_received = FALSE; 233c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 234c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 235c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * IEEE Std 802.1X-2004 does not clear heldWhile here, but doing so 236c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * allows the timer tick to be stopped more quickly when the port is 237c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * not enabled. Since this variable is used only within HELD state, 238c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * clearing it on initialization does not change actual state machine 239c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * behavior. 240c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 241c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->heldWhile = 0; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, CONNECTING) 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 247d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int send_start = sm->SUPP_PAE_state == SUPP_PAE_CONNECTING || 248d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sm->SUPP_PAE_state == SUPP_PAE_HELD; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, CONNECTING); 2506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sm->eapTriggerStart) 2526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt send_start = 1; 253ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt if (sm->ctx->preauth) 254ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt send_start = 1; 2556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapTriggerStart = FALSE; 2566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (send_start) { 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startWhen = sm->startPeriod; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startCount++; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Do not send EAPOL-Start immediately since in most cases, 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Authenticator is going to start authentication immediately 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * after association and an extra EAPOL-Start is just going to 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * delay authentication. Use a short timeout to send the first 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAPOL-Start if Authenticator does not start authentication. 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sm->conf.wps && !(sm->conf.wps & EAPOL_PEER_IS_WPS20_AP)) { 269661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Reduce latency on starting WPS negotiation. */ 270661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_printf(MSG_DEBUG, 271661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt "EAPOL: Using shorter startWhen for WPS"); 272661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt sm->startWhen = 1; 273661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } else { 274661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt sm->startWhen = 2; 275661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_enable_timer_tick(sm); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = FALSE; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (send_start) 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_txStart(sm); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, AUTHENTICATING) 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, AUTHENTICATING); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startCount = 0; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppSuccess = FALSE; 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppFail = FALSE; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppTimeout = FALSE; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->keyRun = FALSE; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->keyDone = FALSE; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppStart = TRUE; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, HELD) 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, HELD); 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldWhile = sm->heldPeriod; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_enable_timer_tick(sm); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_unauthorized(sm); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cb_status = EAPOL_CB_FAILURE; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, AUTHENTICATED) 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, AUTHENTICATED); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_authorized(sm); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cb_status = EAPOL_CB_SUCCESS; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, RESTART) 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, RESTART); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRestart = TRUE; 319d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt if (sm->altAccept) { 320d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt /* 321d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt * Prevent EAP peer state machine from failing due to prior 322d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt * external EAP success notification (altSuccess=TRUE in the 323d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt * IDLE state could result in a transition to the FAILURE state. 324d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt */ 325d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Clearing prior altAccept TRUE"); 326d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt sm->eapSuccess = FALSE; 327d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt sm->altAccept = FALSE; 328d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, S_FORCE_AUTH) 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, S_FORCE_AUTH); 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_authorized(sm); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->sPortMode = ForceAuthorized; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, S_FORCE_UNAUTH) 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, S_FORCE_UNAUTH); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_unauthorized(sm); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->sPortMode = ForceUnauthorized; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_txLogoff(sm); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(SUPP_PAE) 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sm->userLogoff && !sm->logoffSent) && 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->initialize || !sm->portEnabled)) 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(SUPP_PAE, LOGOFF); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (((sm->portControl == Auto) && 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->sPortMode != sm->portControl)) || 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initialize || !sm->portEnabled) 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(SUPP_PAE, DISCONNECTED); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if ((sm->portControl == ForceAuthorized) && 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->sPortMode != sm->portControl) && 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->initialize || !sm->portEnabled)) 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(SUPP_PAE, S_FORCE_AUTH); 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if ((sm->portControl == ForceUnauthorized) && 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->sPortMode != sm->portControl) && 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->initialize || !sm->portEnabled)) 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(SUPP_PAE, S_FORCE_UNAUTH); 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else switch (sm->SUPP_PAE_state) { 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_UNKNOWN: 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_LOGOFF: 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->userLogoff) 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, DISCONNECTED); 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_DISCONNECTED: 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, CONNECTING); 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_CONNECTING: 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->startWhen == 0 && sm->startCount < sm->maxStart) 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, CONNECTING); 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->startWhen == 0 && 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startCount >= sm->maxStart && 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portValid) 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, AUTHENTICATED); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapSuccess || sm->eapFail) 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, AUTHENTICATING); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapolEap) 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, RESTART); 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->startWhen == 0 && 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startCount >= sm->maxStart && 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sm->portValid) 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, HELD); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_AUTHENTICATING: 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapSuccess && !sm->portValid && 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.accept_802_1x_keys && 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.required_keys == 0) { 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: IEEE 802.1X for " 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "plaintext connection; no EAPOL-Key frames " 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "required"); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portValid = TRUE; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->eapol_done_cb) 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eapol_done_cb(sm->ctx->ctx); 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapSuccess && sm->portValid) 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, AUTHENTICATED); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapFail || (sm->keyDone && !sm->portValid)) 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, HELD); 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->suppTimeout) 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, CONNECTING); 4096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else if (sm->eapTriggerStart) 4106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SM_ENTER(SUPP_PAE, CONNECTING); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_HELD: 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->heldWhile == 0) 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, CONNECTING); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapolEap) 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, RESTART); 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_AUTHENTICATED: 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapolEap && sm->portValid) 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, RESTART); 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (!sm->portValid) 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, DISCONNECTED); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_RESTART: 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->eapRestart) 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, AUTHENTICATING); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_S_FORCE_AUTH: 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_S_FORCE_UNAUTH: 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(KEY_RX, NO_KEY_RECEIVE) 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(KEY_RX, NO_KEY_RECEIVE); 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(KEY_RX, KEY_RECEIVE) 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(KEY_RX, KEY_RECEIVE); 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_processKey(sm); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxKey = FALSE; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(KEY_RX) 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->initialize || !sm->portEnabled) 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(KEY_RX, NO_KEY_RECEIVE); 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (sm->KEY_RX_state) { 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case KEY_RX_UNKNOWN: 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case KEY_RX_NO_KEY_RECEIVE: 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->rxKey) 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(KEY_RX, KEY_RECEIVE); 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case KEY_RX_KEY_RECEIVE: 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->rxKey) 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(KEY_RX, KEY_RECEIVE); 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, REQUEST) 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, REQUEST); 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authWhile = 0; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReq = TRUE; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_getSuppRsp(sm); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, RESPONSE) 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, RESPONSE); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_txSuppRsp(sm); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapResp = FALSE; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, SUCCESS) 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, SUCCESS); 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->keyRun = TRUE; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppSuccess = TRUE; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 492f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 493f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) { 494f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (eap_proxy_key_available(sm->eap_proxy)) { 495f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* New key received - clear IEEE 802.1X EAPOL-Key replay 496f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * counter */ 497f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->replay_counter_valid = FALSE; 498f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 499f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return; 500f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 501f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 502f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_key_available(sm->eap)) { 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* New key received - clear IEEE 802.1X EAPOL-Key replay 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * counter */ 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->replay_counter_valid = FALSE; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, FAIL) 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, FAIL); 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppFail = TRUE; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, TIMEOUT) 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, TIMEOUT); 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppTimeout = TRUE; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, IDLE) 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, IDLE); 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppStart = FALSE; 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initial_req = TRUE; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, INITIALIZE) 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, INITIALIZE); 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_abortSupp(sm); 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppAbort = FALSE; 538c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 539c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 540c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * IEEE Std 802.1X-2004 does not clear authWhile here, but doing so 541c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * allows the timer tick to be stopped more quickly when the port is 542c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * not enabled. Since this variable is used only within RECEIVE state, 543c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * clearing it on initialization does not change actual state machine 544c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * behavior. 545c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 546c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->authWhile = 0; 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, RECEIVE) 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, RECEIVE); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authWhile = sm->authPeriod; 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_enable_timer_tick(sm); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = FALSE; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapNoResp = FALSE; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initial_req = FALSE; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(SUPP_BE) 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->initialize || sm->suppAbort) 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(SUPP_BE, INITIALIZE); 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else switch (sm->SUPP_BE_state) { 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_UNKNOWN: 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_REQUEST: 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE Std 802.1X-2004 has transitions from REQUEST to FAIL 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and SUCCESS based on eapFail and eapSuccess, respectively. 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * However, IEEE Std 802.1X-2004 is also specifying that 5731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * eapNoResp should be set in conjunction with eapSuccess and 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapFail which would mean that more than one of the 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * transitions here would be activated at the same time. 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Skipping RESPONSE and/or RECEIVE states in these cases can 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cause problems and the direct transitions to do not seem 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * correct. Because of this, the conditions for these 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * transitions are verified only after eapNoResp. They are 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unlikely to be used since eapNoResp should always be set if 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * either of eapSuccess or eapFail is set. 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapResp && sm->eapNoResp) { 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: SUPP_BE REQUEST: both " 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "eapResp and eapNoResp set?!"); 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapResp) 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, RESPONSE); 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapNoResp) 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, RECEIVE); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapFail) 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, FAIL); 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapSuccess) 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, SUCCESS); 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_RESPONSE: 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, RECEIVE); 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_SUCCESS: 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, IDLE); 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_FAIL: 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, IDLE); 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_TIMEOUT: 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, IDLE); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_IDLE: 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapFail && sm->suppStart) 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, FAIL); 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapolEap && sm->suppStart) 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, REQUEST); 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapSuccess && sm->suppStart) 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, SUCCESS); 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_INITIALIZE: 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, IDLE); 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_RECEIVE: 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapolEap) 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, REQUEST); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapFail) 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, FAIL); 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->authWhile == 0) 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, TIMEOUT); 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapSuccess) 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, SUCCESS); 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txLogoff(struct eapol_sm *sm) 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: txLogoff"); 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eapol_send(sm->ctx->eapol_send_ctx, 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE802_1X_TYPE_EAPOL_LOGOFF, (u8 *) "", 0); 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolLogoffFramesTx++; 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesTx++; 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txStart(struct eapol_sm *sm) 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: txStart"); 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eapol_send(sm->ctx->eapol_send_ctx, 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE802_1X_TYPE_EAPOL_START, (u8 *) "", 0); 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolStartFramesTx++; 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesTx++; 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IEEE8021X_ENCR_KEY_LEN 32 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IEEE8021X_SIGN_KEY_LEN 32 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_key_data { 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 encr_key[IEEE8021X_ENCR_KEY_LEN]; 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 sign_key[IEEE8021X_SIGN_KEY_LEN]; 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_processKey(struct eapol_sm *sm) 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 66461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifndef CONFIG_FIPS 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *hdr; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_eapol_key *key; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_key_data keydata; 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 orig_key_sign[IEEE8021X_KEY_SIGN_LEN], datakey[32]; 669d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef CONFIG_NO_RC4 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ekey[IEEE8021X_KEY_IV_LEN + IEEE8021X_ENCR_KEY_LEN]; 671d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_NO_RC4 */ 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_len, res, sign_key_len, encr_key_len; 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 rx_key_length; 67461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t plen; 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: processKey"); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->last_rx_key == NULL) 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->conf.accept_802_1x_keys) { 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: Received IEEE 802.1X EAPOL-Key" 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " even though this was not accepted - " 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignoring this packet"); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 68761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->last_rx_key_len < sizeof(*hdr) + sizeof(*key)) 68861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct ieee802_1x_hdr *) sm->last_rx_key; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = (struct ieee802_1x_eapol_key *) (hdr + 1); 69161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt plen = be_to_host16(hdr->length); 69261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sizeof(*hdr) + plen > sm->last_rx_key_len || plen < sizeof(*key)) { 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: Too short EAPOL-Key frame"); 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_key_length = WPA_GET_BE16(key->key_length); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: RX IEEE 802.1X ver=%d type=%d len=%d " 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAPOL-Key: type=%d key_length=%d key_index=0x%x", 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->version, hdr->type, be_to_host16(hdr->length), 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->type, rx_key_length, key->key_index); 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_lower_layer_success(sm, 1); 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sign_key_len = IEEE8021X_SIGN_KEY_LEN; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_key_len = IEEE8021X_ENCR_KEY_LEN; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = eapol_sm_get_key(sm, (u8 *) &keydata, sizeof(keydata)); 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Could not get master key for " 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "decrypting EAPOL-Key keys"); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 16) { 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* LEAP derives only 16 bytes of keying material. */ 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = eapol_sm_get_key(sm, (u8 *) &keydata, 16); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Could not get LEAP " 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "master key for decrypting EAPOL-Key keys"); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sign_key_len = 16; 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_key_len = 16; 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(keydata.sign_key, keydata.encr_key, 16); 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (res) { 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Could not get enough master key " 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data for decrypting EAPOL-Key keys (res=%d)", res); 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* The key replay_counter must increase when same master key */ 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->replay_counter_valid && 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sm->last_replay_counter, key->replay_counter, 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE8021X_REPLAY_COUNTER_LEN) >= 0) { 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: EAPOL-Key replay counter did " 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not increase - ignoring key"); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAPOL: last replay counter", 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_replay_counter, 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE8021X_REPLAY_COUNTER_LEN); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAPOL: received replay counter", 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->replay_counter, IEEE8021X_REPLAY_COUNTER_LEN); 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Verify key signature (HMAC-MD5) */ 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(orig_key_sign, key->key_signature, IEEE8021X_KEY_SIGN_LEN); 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(key->key_signature, 0, IEEE8021X_KEY_SIGN_LEN); 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac_md5(keydata.sign_key, sign_key_len, 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_key, sizeof(*hdr) + be_to_host16(hdr->length), 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_signature); 748c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (os_memcmp_const(orig_key_sign, key->key_signature, 749c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt IEEE8021X_KEY_SIGN_LEN) != 0) { 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Invalid key signature in " 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAPOL-Key packet"); 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key->key_signature, orig_key_sign, 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE8021X_KEY_SIGN_LEN); 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: EAPOL-Key key signature verified"); 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 75861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt key_len = plen - sizeof(*key); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_len > 32 || rx_key_length > 32) { 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: Too long key data length %d", 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_len ? key_len : rx_key_length); 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_len == rx_key_length) { 765d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef CONFIG_NO_RC4 766d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (encr_key_len) { 767d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* otherwise unused */ 768d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 769d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_ERROR, "EAPOL: RC4 not supported in the build"); 770d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 771d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else /* CONFIG_NO_RC4 */ 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ekey, key->key_iv, IEEE8021X_KEY_IV_LEN); 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ekey + IEEE8021X_KEY_IV_LEN, keydata.encr_key, 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_key_len); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(datakey, key + 1, key_len); 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rc4_skip(ekey, IEEE8021X_KEY_IV_LEN + encr_key_len, 0, 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt datakey, key_len); 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAPOL: Decrypted(RC4) key", 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt datakey, key_len); 780d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_NO_RC4 */ 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (key_len == 0) { 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.1X-2004 specifies that least significant Key Length 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * octets from MS-MPPE-Send-Key are used as the key if the key 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data is not present. This seems to be meaning the beginning 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * of the MS-MPPE-Send-Key. In addition, MS-MPPE-Send-Key in 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Supplicant corresponds to MS-MPPE-Recv-Key in Authenticator. 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Anyway, taking the beginning of the keying material from EAP 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * seems to interoperate with Authenticators. 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_len = rx_key_length; 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(datakey, keydata.encr_key, key_len); 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAPOL: using part of EAP keying " 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "material data encryption key", 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt datakey, key_len); 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Invalid key data length %d " 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(key_length=%d)", key_len, rx_key_length); 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->replay_counter_valid = TRUE; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->last_replay_counter, key->replay_counter, 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE8021X_REPLAY_COUNTER_LEN); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Setting dynamic WEP key: %s keyidx %d " 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "len %d", 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index & IEEE8021X_KEY_INDEX_FLAG ? 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unicast" : "broadcast", 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index & IEEE8021X_KEY_INDEX_MASK, key_len); 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->set_wep_key && 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->set_wep_key(sm->ctx->ctx, 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index & IEEE8021X_KEY_INDEX_FLAG, 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index & IEEE8021X_KEY_INDEX_MASK, 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt datakey, key_len) < 0) { 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: Failed to set WEP key to the " 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " driver."); 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key->key_index & IEEE8021X_KEY_INDEX_FLAG) 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->unicast_key_received = TRUE; 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->broadcast_key_received = TRUE; 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sm->unicast_key_received || 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_UNICAST)) && 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->broadcast_key_received || 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_BROADCAST))) 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: all required EAPOL-Key " 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frames received"); 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portValid = TRUE; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->eapol_done_cb) 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eapol_done_cb(sm->ctx->ctx); 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 83761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_FIPS */ 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_getSuppRsp(struct eapol_sm *sm) 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: getSuppRsp"); 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* EAP layer processing; no special code is needed, since Supplicant 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Backend state machine is waiting for eapNoResp or eapResp to be set 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and these are only set in the EAP state machine when the processing 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has finished. */ 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txSuppRsp(struct eapol_sm *sm) 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: txSuppRsp"); 856f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 857f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 858f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) { 859f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* Get EAP Response from EAP Proxy */ 860f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt resp = eap_proxy_get_eapRespData(sm->eap_proxy); 861f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (resp == NULL) { 862f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP Proxy " 863f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "response data not available"); 864f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return; 865f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 866f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } else 867f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 868f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_get_eapRespData(sm->eap); 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) { 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP response data " 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not available"); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Send EAP-Packet from the EAP layer to the Authenticator */ 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eapol_send(sm->ctx->eapol_send_ctx, 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head(resp), 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(resp)); 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* eapRespData is not used anymore, so free it here */ 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->initial_req) 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolReqIdFramesRx++; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolReqFramesRx++; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolRespFramesTx++; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesTx++; 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_abortSupp(struct eapol_sm *sm) 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* release system resources that may have been allocated for the 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication session */ 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->last_rx_key); 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_key = NULL; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapReqData); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReqData = NULL; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_abort(sm->eap); 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx) 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(timeout_ctx); 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_port_authorized(struct eapol_sm *sm) 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 913fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int cb; 914fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 915fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cb = sm->suppPortStatus != Authorized || sm->force_authorized_update; 916fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->force_authorized_update = FALSE; 917fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->suppPortStatus = Authorized; 918fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cb && sm->ctx->port_cb) 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->port_cb(sm->ctx->ctx, 1); 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_port_unauthorized(struct eapol_sm *sm) 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 925fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int cb; 926fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 927fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cb = sm->suppPortStatus != Unauthorized || sm->force_authorized_update; 928fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->force_authorized_update = FALSE; 929fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->suppPortStatus = Unauthorized; 930fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cb && sm->ctx->port_cb) 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->port_cb(sm->ctx->ctx, 0); 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_step - EAPOL state machine step function 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called to notify the state machine about changed external 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * variables. It will step through the EAPOL state machines in loop to process 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * all triggered state changes. 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_step(struct eapol_sm *sm) 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* In theory, it should be ok to run this in loop until !changed. 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * However, it is better to use a limit on number of iterations to 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * allow events (e.g., SIGTERM) to stop the program cleanly if the 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine were to generate a busy loop. */ 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 100; i++) { 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->changed = FALSE; 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(SUPP_PAE); 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(KEY_RX); 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(SUPP_BE); 956f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 957f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) { 958f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* Drive the EAP proxy state machine */ 959f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (eap_proxy_sm_step(sm->eap_proxy, sm->eap)) 960f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->changed = TRUE; 961f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } else 962f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_peer_sm_step(sm->eap)) 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->changed = TRUE; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->changed) 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->changed) { 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* restart EAPOL state machine step from timeout call in order 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to allow other events to be processed. */ 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, eapol_sm_step_timeout, NULL, sm); 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->cb && sm->cb_status != EAPOL_CB_IN_PROGRESS) { 977344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt enum eapol_supp_result result; 978344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (sm->cb_status == EAPOL_CB_SUCCESS) 979344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt result = EAPOL_SUPP_RESULT_SUCCESS; 980344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt else if (eap_peer_was_failure_expected(sm->eap)) 981344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt result = EAPOL_SUPP_RESULT_EXPECTED_FAILURE; 982344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt else 983344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt result = EAPOL_SUPP_RESULT_FAILURE; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cb_status = EAPOL_CB_IN_PROGRESS; 985344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt sm->ctx->cb(sm, result, sm->ctx->cb_ctx); 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char *eapol_supp_pae_state(int state) 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_LOGOFF: 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "LOGOFF"; 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_DISCONNECTED: 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "DISCONNECTED"; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_CONNECTING: 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECTING"; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_AUTHENTICATING: 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "AUTHENTICATING"; 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_HELD: 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "HELD"; 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_AUTHENTICATED: 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "AUTHENTICATED"; 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_RESTART: 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "RESTART"; 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char *eapol_supp_be_state(int state) 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_REQUEST: 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "REQUEST"; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_RESPONSE: 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "RESPONSE"; 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_SUCCESS: 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SUCCESS"; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_FAIL: 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "FAIL"; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_TIMEOUT: 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "TIMEOUT"; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_IDLE: 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDLE"; 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_INITIALIZE: 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INITIALIZE"; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_RECEIVE: 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "RECEIVE"; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eapol_port_status(PortStatus status) 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status == Authorized) 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Authorized"; 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Unauthorized"; 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */ 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eapol_port_control(PortControl ctrl) 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ctrl) { 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Auto: 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Auto"; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case ForceUnauthorized: 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "ForceUnauthorized"; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case ForceAuthorized: 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "ForceAuthorized"; 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Unknown"; 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_configure - Set EAPOL variables 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @heldPeriod: dot1xSuppHeldPeriod 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @authPeriod: dot1xSuppAuthPeriod 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @startPeriod: dot1xSuppStartPeriod 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @maxStart: dot1xSuppMaxStart 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Set configurable EAPOL state machine variables. Each variable can be set to 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the given value or ignored if set to -1 (to set only some of the variables). 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod, 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int startPeriod, int maxStart) 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (heldPeriod >= 0) 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldPeriod = heldPeriod; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (authPeriod >= 0) 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authPeriod = authPeriod; 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (startPeriod >= 0) 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startPeriod = startPeriod; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (maxStart >= 0) 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->maxStart = maxStart; 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_get_method_name - Get EAPOL method name 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Static string containing name of current eap method or NULL 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * eapol_sm_get_method_name(struct eapol_sm *sm) 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED || 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppPortStatus != Authorized) 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_sm_get_method_name(sm->eap); 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_get_status - Get EAPOL state machine status 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for status information 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: Maximum buffer length 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @verbose: Whether to include verbose status information 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to buf. 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Query EAPOL state machine for status information. This function fills in a 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * text area with current status information from the EAPOL state machine. If 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the buffer (buf) is not large enough, status information will be truncated 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to fit the buffer. 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen, 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int verbose) 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, ret; 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(buf, buflen, 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Supplicant PAE state=%s\n" 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "suppPortStatus=%s\n", 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_supp_pae_state(sm->SUPP_PAE_state), 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_port_status(sm->suppPortStatus)); 11346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen, len)) 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (verbose) { 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "heldPeriod=%u\n" 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authPeriod=%u\n" 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "startPeriod=%u\n" 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "maxStart=%u\n" 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "portControl=%s\n" 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Supplicant Backend state=%s\n", 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldPeriod, 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authPeriod, 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startPeriod, 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->maxStart, 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_port_control(sm->portControl), 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_supp_be_state(sm->SUPP_BE_state)); 11516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1156f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 1157f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) 1158f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt len += eap_proxy_sm_get_status(sm->eap_proxy, 1159f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt buf + len, buflen - len, 1160f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt verbose); 1161f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt else 1162f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += eap_sm_get_status(sm->eap, buf + len, buflen - len, verbose); 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_get_mib - Get EAPOL state machine MIBs 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for MIB information 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: Maximum buffer length 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to buf. 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Query EAPOL state machine for MIB information. This function fills in a 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * text area with current MIB information from the EAPOL state machine. If 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the buffer (buf) is not large enough, MIB information will be truncated to 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * fit the buffer. 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen) 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf, buflen, 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppPaeState=%d\n" 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppHeldPeriod=%u\n" 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppAuthPeriod=%u\n" 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppStartPeriod=%u\n" 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppMaxStart=%u\n" 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppSuppControlledPortStatus=%s\n" 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppBackendPaeState=%d\n", 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->SUPP_PAE_state, 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldPeriod, 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authPeriod, 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startPeriod, 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->maxStart, 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppPortStatus == Authorized ? 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Authorized" : "Unauthorized", 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->SUPP_BE_state); 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen, ret)) 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ret; 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolFramesRx=%u\n" 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolFramesTx=%u\n" 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolStartFramesTx=%u\n" 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolLogoffFramesTx=%u\n" 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolRespFramesTx=%u\n" 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolReqIdFramesRx=%u\n" 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolReqFramesRx=%u\n" 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppInvalidEapolFramesRx=%u\n" 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapLengthErrorFramesRx=%u\n" 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppLastEapolFrameVersion=%u\n" 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppLastEapolFrameSource=" MACSTR "\n", 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesRx, 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesTx, 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolStartFramesTx, 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolLogoffFramesTx, 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolRespFramesTx, 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolReqIdFramesRx, 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolReqFramesRx, 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppInvalidEapolFramesRx, 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapLengthErrorFramesRx, 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppLastEapolFrameVersion, 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sm->dot1xSuppLastEapolFrameSource)); 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */ 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_rx_eapol - Process received EAPOL frames 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @src: Source MAC address of the EAPOL packet 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Pointer to the beginning of the EAPOL data (EAPOL header) 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the EAPOL frame 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 = EAPOL frame processed, 0 = not for EAPOL state machine, 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * -1 failure 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf, 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee802_1x_hdr *hdr; 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee802_1x_eapol_key *key; 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int data_len; 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = 1; 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t plen; 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesRx++; 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(*hdr)) { 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppInvalidEapolFramesRx++; 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (const struct ieee802_1x_hdr *) buf; 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppLastEapolFrameVersion = hdr->version; 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->dot1xSuppLastEapolFrameSource, src, ETH_ALEN); 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->version < EAPOL_VERSION) { 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: backwards compatibility */ 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = be_to_host16(hdr->length); 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen > len - sizeof(*hdr)) { 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapLengthErrorFramesRx++; 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 1279661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (sm->conf.wps && sm->conf.workaround && 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen < len - sizeof(*hdr) && 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->type == IEEE802_1X_TYPE_EAP_PACKET && 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len - sizeof(*hdr) > sizeof(struct eap_hdr)) { 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_hdr *ehdr = 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const struct eap_hdr *) (hdr + 1); 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 elen; 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elen = be_to_host16(ehdr->length); 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elen > plen && elen <= len - sizeof(*hdr)) { 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Buffalo WHR-G125 Ver.1.47 seems to send EAP-WPS 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * packets with too short EAPOL header length field 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (14 octets). This is fixed in firmware Ver.1.49. 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * As a workaround, fix the EAPOL header based on the 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * correct length in the EAP packet. 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Workaround - fix EAPOL " 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "payload length based on EAP header: " 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d -> %d", (int) plen, elen); 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = elen; 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len = plen + sizeof(*hdr); 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->type) { 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case IEEE802_1X_TYPE_EAP_PACKET: 13075605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (sm->conf.workaround) { 13085605286c30e1701491bd3af974ae423727750eddDmitry Shmidt /* 13095605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * An AP has been reported to send out EAP message with 13105605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * undocumented code 10 at some point near the 13115605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * completion of EAP authentication. This can result in 13125605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * issues with the unexpected EAP message triggering 13135605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * restart of EAPOL authentication. Avoid this by 13145605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * skipping the message without advancing the state 13155605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * machine. 13165605286c30e1701491bd3af974ae423727750eddDmitry Shmidt */ 13175605286c30e1701491bd3af974ae423727750eddDmitry Shmidt const struct eap_hdr *ehdr = 13185605286c30e1701491bd3af974ae423727750eddDmitry Shmidt (const struct eap_hdr *) (hdr + 1); 13195605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (plen >= sizeof(*ehdr) && ehdr->code == 10) { 13205605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Ignore EAP packet with unknown code 10"); 13215605286c30e1701491bd3af974ae423727750eddDmitry Shmidt break; 13225605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 13235605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 13245605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->cached_pmk) { 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Trying to use PMKSA caching, but Authenticator did 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not seem to have a matching entry. Need to restart 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAPOL state machines. 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_abort_cached(sm); 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapReqData); 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReqData = wpabuf_alloc_copy(hdr + 1, plen); 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapReqData) { 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Received EAP-Packet " 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame"); 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = TRUE; 1338f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 1339f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) { 1340f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt eap_proxy_packet_update( 1341f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->eap_proxy, 1342f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpabuf_mhead_u8(sm->eapReqData), 1343f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpabuf_len(sm->eapReqData)); 1344f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: eap_proxy " 1345f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "EAP Req updated"); 1346f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 1347f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case IEEE802_1X_TYPE_EAPOL_KEY: 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen < sizeof(*key)) { 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Too short EAPOL-Key " 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame received"); 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = (const struct ieee802_1x_eapol_key *) (hdr + 1); 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key->type == EAPOL_KEY_TYPE_WPA || 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->type == EAPOL_KEY_TYPE_RSN) { 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPA Supplicant takes care of this frame. */ 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Ignoring WPA EAPOL-Key " 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame in EAPOL state machines"); 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = 0; 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key->type != EAPOL_KEY_TYPE_RC4) { 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Ignored unknown " 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAPOL-Key type %d", key->type); 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->last_rx_key); 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_key = os_malloc(data_len); 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->last_rx_key) { 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Received EAPOL-Key " 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame"); 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->last_rx_key, buf, data_len); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_key_len = data_len; 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxKey = TRUE; 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#ifdef CONFIG_MACSEC 13835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt case IEEE802_1X_TYPE_EAPOL_MKA: 13845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_EXCESSIVE, 13855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "EAPOL type %d will be handled by MKA", 13865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr->type); 13875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 13885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif /* CONFIG_MACSEC */ 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Received unknown EAPOL type %d", 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->type); 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppInvalidEapolFramesRx++; 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_tx_eapol_key - Notification about transmitted EAPOL packet 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machine about transmitted EAPOL packet from an external 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * component, e.g., WPA. This will update the statistics. 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm) 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesTx++; 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_portEnabled - Notification about portEnabled change 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @enabled: New portEnabled value 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machine about new portEnabled value. 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled) 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "portEnabled=%d", enabled); 1427fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (sm->portEnabled != enabled) 1428fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->force_authorized_update = TRUE; 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portEnabled = enabled; 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_portValid - Notification about portValid change 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @valid: New portValid value 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machine about new portValid value. 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid) 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "portValid=%d", valid); 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portValid = valid; 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_eap_success - Notification of external EAP success trigger 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @success: %TRUE = set success, %FALSE = clear success 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify the EAPOL state machine that external event has forced EAP state to 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * success (success = %TRUE). This can be cleared by setting success = %FALSE. 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called to update EAP state when WPA-PSK key handshake has 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * been completed successfully since WPA-PSK does not use EAP state machine. 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_eap_success(struct eapol_sm *sm, Boolean success) 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP success=%d", success); 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapSuccess = success; 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->altAccept = success; 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (success) 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_notify_success(sm->eap); 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_eap_fail - Notification of external EAP failure trigger 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @fail: %TRUE = set failure, %FALSE = clear failure 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machine that external event has forced EAP state to 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * failure (fail = %TRUE). This can be cleared by setting fail = %FALSE. 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail) 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP fail=%d", fail); 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapFail = fail; 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->altReject = fail; 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_config - Notification of EAPOL configuration change 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config: Pointer to current network EAP configuration 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Pointer to EAPOL configuration data 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machine that configuration has changed. config will be 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * stored as a backpointer to network configuration. This can be %NULL to clear 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the stored pointed. conf will be copied to local EAPOL/EAP configuration 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data. If conf is %NULL, this part of the configuration change will be 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * skipped. 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_config(struct eapol_sm *sm, 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config, 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eapol_config *conf) 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->config = config; 1517f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 1518f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->use_eap_proxy = eap_proxy_notify_config(sm->eap_proxy, config) > 0; 1519f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf == NULL) 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.accept_802_1x_keys = conf->accept_802_1x_keys; 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.required_keys = conf->required_keys; 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.fast_reauth = conf->fast_reauth; 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.workaround = conf->workaround; 1528661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt sm->conf.wps = conf->wps; 1529f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 1530f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) { 1531f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* Using EAP Proxy, so skip EAP state machine update */ 1532f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return; 1533f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 1534f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap) { 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_set_fast_reauth(sm->eap, conf->fast_reauth); 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_set_workaround(sm->eap, conf->workaround); 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_set_force_disabled(sm->eap, conf->eap_disabled); 1539051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt eap_set_external_sim(sm->eap, conf->external_sim); 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_get_key - Get master session key (MSK) from EAP 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @key: Pointer for key buffer 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Number of bytes to copy to key 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success (len of key available), maximum available key len 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (>0) if key is available but it is shorter than len, or -1 on failure. 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fetch EAP keying material (MSK, eapKeyData) from EAP state machine. The key 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is available only after a successful authentication. 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len) 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *eap_key; 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t eap_len; 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1560f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 156109f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt if (sm && sm->use_eap_proxy) { 1562f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* Get key from EAP proxy */ 1563f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm == NULL || !eap_proxy_key_available(sm->eap_proxy)) { 1564f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available"); 1565f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return -1; 1566f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 1567f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt eap_key = eap_proxy_get_eapKeyData(sm->eap_proxy, &eap_len); 1568f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (eap_key == NULL) { 1569f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Failed to get " 1570f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "eapKeyData"); 1571f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return -1; 1572f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 1573f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt goto key_fetched; 1574f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 1575f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || !eap_key_available(sm->eap)) { 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available"); 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_key = eap_get_eapKeyData(sm->eap, &eap_len); 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_key == NULL) { 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Failed to get eapKeyData"); 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1585f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 1586f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtkey_fetched: 1587f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > eap_len) { 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Requested key length (%lu) not " 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available (len=%lu)", 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) eap_len); 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_len; 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key, eap_key, len); 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Successfully fetched key (len=%lu)", 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * eapol_sm_get_session_id - Get EAP Session-Id 16035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 16045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * @len: Pointer to variable that will be set to number of bytes in the session 16055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Returns: Pointer to the EAP Session-Id or %NULL on failure 16065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * 16075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * The Session-Id is available only after a successful authentication. 16085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 16095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst u8 * eapol_sm_get_session_id(struct eapol_sm *sm, size_t *len) 16105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 16115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (sm == NULL || !eap_key_available(sm->eap)) { 16125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: EAP Session-Id not available"); 16135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 16145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 16155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return eap_get_eapSessionId(sm->eap, len); 16165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 16175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_logoff - Notification of logon/logoff commands 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @logoff: Whether command was logoff 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines that user requested logon/logoff. 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff) 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) { 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->userLogoff = logoff; 16308da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (!logoff) { 16318da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt /* If there is a delayed txStart queued, start now. */ 16328da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt sm->startWhen = 0; 16338da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_pmkid_attempt - Notification of successful PMKSA caching 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines that PMKSA caching was successful. This is used 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to move EAPOL and EAP state machines into authenticated/successful state. 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_cached(struct eapol_sm *sm) 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: PMKSA caching was used - skip EAPOL"); 1651d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sm->eapSuccess = TRUE; 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_notify_success(sm->eap); 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_pmkid_attempt - Notification of PMKSA caching 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1661216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * Notify EAPOL state machines if PMKSA caching is used. 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1663216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtvoid eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm) 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1667216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "RSN: Trying to use cached PMKSA"); 1668216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt sm->cached_pmk = TRUE; 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_abort_cached(struct eapol_sm *sm) 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "RSN: Authenticator did not accept PMKID, " 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "doing full EAP authentication"); 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cached_pmk = FALSE; 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->SUPP_PAE_state = SUPP_PAE_CONNECTING; 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_unauthorized(sm); 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we do not start sending EAPOL-Start frames first, but 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * instead move to RESTART state to start EAPOL authentication. */ 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startWhen = 3; 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_enable_timer_tick(sm); 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->aborted_cached) 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->aborted_cached(sm->ctx->ctx); 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_register_scard_ctx - Notification of smart card context 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context data for smart card operations 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines of context data for smart card operations. This 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * context data will be used as a parameter for scard_*() functions. 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx) 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) { 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->scard_ctx = ctx; 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_register_scard_ctx(sm->eap, ctx); 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_portControl - Notification of portControl changes 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @portControl: New value for portControl variable 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines that portControl variable has changed. 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl) 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "portControl=%s", eapol_port_control(portControl)); 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portControl = portControl; 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_ctrl_attached - Notification of attached monitor 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines that a monitor was attached to the control 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface to trigger re-sending of pending requests for user input. 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_ctrl_attached(struct eapol_sm *sm) 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_notify_ctrl_attached(sm->eap); 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_ctrl_response - Notification of received user input 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines that a control response, i.e., user 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input, was received in order to trigger retrying of a pending EAP request. 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_ctrl_response(struct eapol_sm *sm) 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapReqData && !sm->eapReq) { 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: received control response (user " 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "input) notification - retrying pending EAP " 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request"); 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = TRUE; 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReq = TRUE; 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_request_reauth - Request reauthentication 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to request EAPOL reauthentication, e.g., when the 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current PMKSA entry is nearing expiration. 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_request_reauth(struct eapol_sm *sm) 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED) 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_txStart(sm); 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_lower_layer_success - Notification of lower layer success 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_eapol_sm: Whether the caller is already running inside EAPOL state 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * machine loop (eapol_sm_step()) 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL (and EAP) state machines that a lower layer has detected a 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * successful authentication. This is used to recover from dropped EAP-Success 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * messages. 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, int in_eapol_sm) 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_notify_lower_layer_success(sm->eap); 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!in_eapol_sm) 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_invalidate_cached_session - Mark cached EAP session data invalid 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_invalidate_cached_session(struct eapol_sm *sm) 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_invalidate_cached_session(sm->eap); 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eap_peer_config * eapol_sm_get_config(void *ctx) 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm ? sm->config : NULL; 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eapol_sm_get_eapReqData(void *ctx) 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->eapReqData == NULL) 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapReqData; 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eapol_sm_get_bool(void *ctx, enum eapol_bool_var variable) 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FALSE; 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (variable) { 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapSuccess: 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapSuccess; 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapRestart: 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapRestart; 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapFail: 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapFail; 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapResp: 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapResp; 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapNoResp: 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapNoResp; 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapReq: 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapReq; 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_portEnabled: 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->portEnabled; 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_altAccept: 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->altAccept; 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_altReject: 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->altReject; 18516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case EAPOL_eapTriggerStart: 18526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return sm->eapTriggerStart; 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FALSE; 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_bool(void *ctx, enum eapol_bool_var variable, 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean value) 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (variable) { 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapSuccess: 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapSuccess = value; 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapRestart: 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRestart = value; 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapFail: 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapFail = value; 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapResp: 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapResp = value; 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapNoResp: 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapNoResp = value; 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapReq: 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReq = value; 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_portEnabled: 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portEnabled = value; 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_altAccept: 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->altAccept = value; 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_altReject: 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->altReject = value; 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case EAPOL_eapTriggerStart: 18936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapTriggerStart = value; 18946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned int eapol_sm_get_int(void *ctx, enum eapol_int_var variable) 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (variable) { 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_idleWhile: 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->idleWhile; 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_int(void *ctx, enum eapol_int_var variable, 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int value) 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (variable) { 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_idleWhile: 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->idleWhile = value; 192161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->idleWhile > 0) 192261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eapol_enable_timer_tick(sm); 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_config_blob(void *ctx, struct wpa_config_blob *blob) 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm && sm->ctx && sm->ctx->set_config_blob) 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->set_config_blob(sm->ctx->ctx, blob); 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const struct wpa_config_blob * 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidteapol_sm_get_config_blob(void *ctx, const char *name) 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm && sm->ctx && sm->ctx->get_config_blob) 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->ctx->get_config_blob(sm->ctx->ctx, name); 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NO_CONFIG_BLOBS */ 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_notify_pending(void *ctx) 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapReqData && !sm->eapReq) { 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: received notification from EAP " 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state machine - retrying pending EAP Request"); 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = TRUE; 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReq = TRUE; 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 19691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void eapol_sm_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field, 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *txt) 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: EAP parameter needed"); 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->eap_param_needed) 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eap_param_needed(sm->ctx->ctx, field, txt); 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define eapol_sm_eap_param_needed NULL 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1981c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidtstatic void eapol_sm_notify_cert(void *ctx, int depth, const char *subject, 19822f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt const char *altsubject[], 19832f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int num_altsubject, const char *cert_hash, 1984c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt const struct wpabuf *cert) 1985c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt{ 1986c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt struct eapol_sm *sm = ctx; 1987c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (sm->ctx->cert_cb) 19882f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sm->ctx->cert_cb(sm->ctx->ctx, depth, subject, altsubject, 19892f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_altsubject, cert_hash, cert); 1990c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt} 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 199204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 199304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void eapol_sm_notify_status(void *ctx, const char *status, 199404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *parameter) 199504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 199604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct eapol_sm *sm = ctx; 199704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 199804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm->ctx->status_cb) 199904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sm->ctx->status_cb(sm->ctx->ctx, status, parameter); 200004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 200104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 200204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2003203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#ifdef CONFIG_EAP_PROXY 2004293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2005203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidtstatic void eapol_sm_eap_proxy_cb(void *ctx) 2006203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt{ 2007203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt struct eapol_sm *sm = ctx; 2008203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 2009203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (sm->ctx->eap_proxy_cb) 2010203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt sm->ctx->eap_proxy_cb(sm->ctx->ctx); 2011203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt} 2012293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2013293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2014293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidtstatic void 2015293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidteapol_sm_eap_proxy_notify_sim_status(void *ctx, 2016293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt enum eap_proxy_sim_state sim_state) 2017293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt{ 2018293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt struct eapol_sm *sm = ctx; 2019293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2020293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt if (sm->ctx->eap_proxy_notify_sim_status) 2021293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt sm->ctx->eap_proxy_notify_sim_status(sm->ctx->ctx, sim_state); 2022293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt} 2023293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2024203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 2025203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 2026203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 20274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic void eapol_sm_set_anon_id(void *ctx, const u8 *id, size_t len) 20284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 20294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eapol_sm *sm = ctx; 20304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 20314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sm->ctx->set_anon_id) 20324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sm->ctx->set_anon_id(sm->ctx->ctx, id, len); 20334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 20344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 20354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 20361d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidtstatic const struct eapol_callbacks eapol_cb = 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_config, 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_bool, 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_bool, 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_int, 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_int, 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_eapReqData, 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_config_blob, 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_config_blob, 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_pending, 2047c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt eapol_sm_eap_param_needed, 204804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eapol_sm_notify_cert, 20494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt eapol_sm_notify_status, 2050203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#ifdef CONFIG_EAP_PROXY 2051203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt eapol_sm_eap_proxy_cb, 2052293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt eapol_sm_eap_proxy_notify_sim_status, 2053203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 20544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt eapol_sm_set_anon_id 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_init - Initialize EAPOL state machine 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Pointer to EAPOL context data; this needs to be an allocated buffer 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and EAPOL state machine will free it in eapol_sm_deinit() 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the allocated EAPOL state machine or %NULL on failure 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Allocate and initialize an EAPOL state machine. 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx) 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm; 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_config conf; 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm = os_zalloc(sizeof(*sm)); 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx = ctx; 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portControl = Auto; 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supplicant PAE state machine */ 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldPeriod = 60; 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startPeriod = 30; 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->maxStart = 3; 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supplicant Backend state machine */ 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authPeriod = 30; 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&conf, 0, sizeof(conf)); 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.opensc_engine_path = ctx->opensc_engine_path; 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.pkcs11_engine_path = ctx->pkcs11_engine_path; 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.pkcs11_module_path = ctx->pkcs11_module_path; 20896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt conf.openssl_ciphers = ctx->openssl_ciphers; 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.wps = ctx->wps; 20911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conf.cert_in_cb = ctx->cert_in_cb; 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap = eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf); 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap == NULL) { 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2099f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 2100f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->use_eap_proxy = FALSE; 2101f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->eap_proxy = eap_proxy_init(sm, &eapol_cb, sm->ctx->msg_ctx); 2102f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->eap_proxy == NULL) { 2103f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_ERROR, "Unable to initialize EAP Proxy"); 2104f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 2105f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 2106f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Initialize EAPOL state machines */ 2108fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->force_authorized_update = TRUE; 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initialize = TRUE; 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initialize = FALSE; 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->timer_tick_enabled = 1; 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm); 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm; 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_deinit - Deinitialize EAPOL state machine 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Deinitialize and free EAPOL state machine. 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_deinit(struct eapol_sm *sm) 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm); 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm); 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_sm_deinit(sm->eap); 2134f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 2135f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt eap_proxy_deinit(sm->eap_proxy); 2136f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->last_rx_key); 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapReqData); 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->ctx); 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 214261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 214361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 214461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm, 214561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct ext_password_data *ext) 214661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 214761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm && sm->eap) 214861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eap_sm_set_ext_pw_ctx(sm->eap, ext); 214961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 215061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 215161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 215261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint eapol_sm_failed(struct eapol_sm *sm) 215361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 215461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm == NULL) 215561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 215661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return !sm->eapSuccess && sm->eapFail; 215761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 21584ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 21594ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 2160ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#ifdef CONFIG_EAP_PROXY 21614ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtint eapol_sm_get_eap_proxy_imsi(struct eapol_sm *sm, char *imsi, size_t *len) 21624ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 21634ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (sm->eap_proxy == NULL) 21644ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return -1; 21654ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return eap_proxy_get_imsi(sm->eap_proxy, imsi, len); 21664ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 2167ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 21686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid eapol_sm_erp_flush(struct eapol_sm *sm) 21716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 21726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sm) 21736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_peer_erp_free_keys(sm->eap); 21746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 21759839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt 21769839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt 21779839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstruct wpabuf * eapol_sm_build_erp_reauth_start(struct eapol_sm *sm) 21789839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{ 21799839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_ERP 21809839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt if (!sm) 21819839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt return NULL; 21829839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt return eap_peer_build_erp_reauth_start(sm->eap, 0); 21839839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#else /* CONFIG_ERP */ 21849839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt return NULL; 21859839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_ERP */ 21869839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt} 21879839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt 21889839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt 21899839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtvoid eapol_sm_process_erp_finish(struct eapol_sm *sm, const u8 *buf, 21909839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt size_t len) 21919839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{ 21929839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_ERP 21939839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt if (!sm) 21949839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt return; 21959839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt eap_peer_finish(sm->eap, (const struct eap_hdr *) buf, len); 21969839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_ERP */ 21979839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt} 2198