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" 19d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#include "eap_peer/eap_config.h" 20f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "eap_peer/eap_proxy.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_supp_sm.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DATA struct eapol_sm 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define STATE_MACHINE_DEBUG_PREFIX "EAPOL" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* IEEE 802.1X-2004 - Supplicant - EAPOL state machines */ 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct eapol_sm - Internal data for EAPOL state machines 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eapol_sm { 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Timers */ 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int authWhile; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int heldWhile; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int startWhen; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int idleWhile; /* for EAP state machine */ 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int timer_tick_enabled; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Global variables */ 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapFail; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapolEap; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapSuccess; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean initialize; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean keyDone; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean keyRun; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PortControl portControl; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean portEnabled; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PortStatus suppPortStatus; /* dot1xSuppControlledPortStatus */ 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean portValid; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean suppAbort; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean suppFail; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean suppStart; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean suppSuccess; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean suppTimeout; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supplicant PAE state machine */ 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_UNKNOWN = 0, 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_DISCONNECTED = 1, 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_LOGOFF = 2, 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_CONNECTING = 3, 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_AUTHENTICATING = 4, 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_AUTHENTICATED = 5, 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* unused(6) */ 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_HELD = 7, 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_RESTART = 8, 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_S_FORCE_AUTH = 9, 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_PAE_S_FORCE_UNAUTH = 10 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } SUPP_PAE_state; /* dot1xSuppPaeState */ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Variables */ 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean userLogoff; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean logoffSent; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int startCount; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapRestart; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PortControl sPortMode; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Constants */ 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int heldPeriod; /* dot1xSuppHeldPeriod */ 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int startPeriod; /* dot1xSuppStartPeriod */ 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int maxStart; /* dot1xSuppMaxStart */ 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Key Receive state machine */ 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt KEY_RX_UNKNOWN = 0, 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt KEY_RX_NO_KEY_RECEIVE, KEY_RX_KEY_RECEIVE 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } KEY_RX_state; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Variables */ 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean rxKey; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supplicant Backend state machine */ 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_UNKNOWN = 0, 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_INITIALIZE = 1, 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_IDLE = 2, 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_REQUEST = 3, 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_RECEIVE = 4, 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_RESPONSE = 5, 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_FAIL = 6, 99293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt SUPP_BE_TIMEOUT = 7, 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SUPP_BE_SUCCESS = 8 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } SUPP_BE_state; /* dot1xSuppBackendPaeState */ 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Variables */ 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapNoResp; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapReq; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean eapResp; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Constants */ 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int authPeriod; /* dot1xSuppAuthPeriod */ 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Statistics */ 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolFramesRx; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolFramesTx; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolStartFramesTx; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolLogoffFramesTx; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolRespFramesTx; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolReqIdFramesRx; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapolReqFramesRx; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppInvalidEapolFramesRx; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppEapLengthErrorFramesRx; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int dot1xSuppLastEapolFrameVersion; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char dot1xSuppLastEapolFrameSource[6]; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Miscellaneous variables (not defined in IEEE 802.1X-2004) */ 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean changed; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *eap; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean initial_req; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *last_rx_key; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t last_rx_key_len; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *eapReqData; /* for EAP */ 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean altAccept; /* for EAP */ 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean altReject; /* for EAP */ 1326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt Boolean eapTriggerStart; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean replay_counter_valid; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 last_replay_counter[16]; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_config conf; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_ctx *ctx; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { EAPOL_CB_IN_PROGRESS = 0, EAPOL_CB_SUCCESS, EAPOL_CB_FAILURE } 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb_status; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean cached_pmk; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean unicast_key_received, broadcast_key_received; 142fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 143fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt Boolean force_authorized_update; 144fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 145f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 146f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt Boolean use_eap_proxy; 147f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct eap_proxy_sm *eap_proxy; 148f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txLogoff(struct eapol_sm *sm); 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txStart(struct eapol_sm *sm); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_processKey(struct eapol_sm *sm); 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_getSuppRsp(struct eapol_sm *sm); 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txSuppRsp(struct eapol_sm *sm); 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_abortSupp(struct eapol_sm *sm); 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_abort_cached(struct eapol_sm *sm); 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_port_authorized(struct eapol_sm *sm); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_port_unauthorized(struct eapol_sm *sm); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Port Timers state machine - implemented as a function that will be called 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * once a second as a registered event loop timeout */ 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx) 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = timeout_ctx; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->authWhile > 0) { 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authWhile--; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->authWhile == 0) 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: authWhile --> 0"); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->heldWhile > 0) { 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldWhile--; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->heldWhile == 0) 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: heldWhile --> 0"); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->startWhen > 0) { 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startWhen--; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->startWhen == 0) 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: startWhen --> 0"); 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->idleWhile > 0) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->idleWhile--; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->idleWhile == 0) 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: idleWhile --> 0"); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->authWhile | sm->heldWhile | sm->startWhen | sm->idleWhile) { 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx, 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: disable timer tick"); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->timer_tick_enabled = 0; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_enable_timer_tick(struct eapol_sm *sm) 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->timer_tick_enabled) 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: enable timer tick"); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->timer_tick_enabled = 1; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, LOGOFF) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, LOGOFF); 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_txLogoff(sm); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->logoffSent = TRUE; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_unauthorized(sm); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, DISCONNECTED) 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, DISCONNECTED); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->sPortMode = Auto; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startCount = 0; 2276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapTriggerStart = FALSE; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->logoffSent = FALSE; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_unauthorized(sm); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppAbort = TRUE; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->unicast_key_received = FALSE; 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->broadcast_key_received = FALSE; 234c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 235c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 236c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * IEEE Std 802.1X-2004 does not clear heldWhile here, but doing so 237c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * allows the timer tick to be stopped more quickly when the port is 238c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * not enabled. Since this variable is used only within HELD state, 239c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * clearing it on initialization does not change actual state machine 240c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * behavior. 241c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 242c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->heldWhile = 0; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, CONNECTING) 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 248d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int send_start = sm->SUPP_PAE_state == SUPP_PAE_CONNECTING || 249d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sm->SUPP_PAE_state == SUPP_PAE_HELD; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, CONNECTING); 2516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sm->eapTriggerStart) 2536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt send_start = 1; 254ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt if (sm->ctx->preauth) 255ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt send_start = 1; 2566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapTriggerStart = FALSE; 2576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (send_start) { 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startWhen = sm->startPeriod; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startCount++; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Do not send EAPOL-Start immediately since in most cases, 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Authenticator is going to start authentication immediately 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * after association and an extra EAPOL-Start is just going to 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * delay authentication. Use a short timeout to send the first 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAPOL-Start if Authenticator does not start authentication. 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sm->conf.wps && !(sm->conf.wps & EAPOL_PEER_IS_WPS20_AP)) { 270661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Reduce latency on starting WPS negotiation. */ 271661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_printf(MSG_DEBUG, 272661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt "EAPOL: Using shorter startWhen for WPS"); 273661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt sm->startWhen = 1; 274661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } else { 275661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt sm->startWhen = 2; 276661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_enable_timer_tick(sm); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = FALSE; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (send_start) 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_txStart(sm); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, AUTHENTICATING) 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, AUTHENTICATING); 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startCount = 0; 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppSuccess = FALSE; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppFail = FALSE; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppTimeout = FALSE; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->keyRun = FALSE; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->keyDone = FALSE; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppStart = TRUE; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, HELD) 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, HELD); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldWhile = sm->heldPeriod; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_enable_timer_tick(sm); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_unauthorized(sm); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cb_status = EAPOL_CB_FAILURE; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, AUTHENTICATED) 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, AUTHENTICATED); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_authorized(sm); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cb_status = EAPOL_CB_SUCCESS; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, RESTART) 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, RESTART); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRestart = TRUE; 320d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt if (sm->altAccept) { 321d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt /* 322d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt * Prevent EAP peer state machine from failing due to prior 323d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt * external EAP success notification (altSuccess=TRUE in the 324d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt * IDLE state could result in a transition to the FAILURE state. 325d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt */ 326d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Clearing prior altAccept TRUE"); 327d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt sm->eapSuccess = FALSE; 328d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt sm->altAccept = FALSE; 329d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt } 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, S_FORCE_AUTH) 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, S_FORCE_AUTH); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_authorized(sm); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->sPortMode = ForceAuthorized; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_PAE, S_FORCE_UNAUTH) 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_PAE, S_FORCE_UNAUTH); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_unauthorized(sm); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->sPortMode = ForceUnauthorized; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_txLogoff(sm); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(SUPP_PAE) 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sm->userLogoff && !sm->logoffSent) && 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->initialize || !sm->portEnabled)) 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(SUPP_PAE, LOGOFF); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (((sm->portControl == Auto) && 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->sPortMode != sm->portControl)) || 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initialize || !sm->portEnabled) 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(SUPP_PAE, DISCONNECTED); 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if ((sm->portControl == ForceAuthorized) && 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->sPortMode != sm->portControl) && 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->initialize || !sm->portEnabled)) 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(SUPP_PAE, S_FORCE_AUTH); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if ((sm->portControl == ForceUnauthorized) && 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->sPortMode != sm->portControl) && 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->initialize || !sm->portEnabled)) 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(SUPP_PAE, S_FORCE_UNAUTH); 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else switch (sm->SUPP_PAE_state) { 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_UNKNOWN: 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_LOGOFF: 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->userLogoff) 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, DISCONNECTED); 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_DISCONNECTED: 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, CONNECTING); 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_CONNECTING: 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->startWhen == 0 && sm->startCount < sm->maxStart) 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, CONNECTING); 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->startWhen == 0 && 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startCount >= sm->maxStart && 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portValid) 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, AUTHENTICATED); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapSuccess || sm->eapFail) 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, AUTHENTICATING); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapolEap) 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, RESTART); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->startWhen == 0 && 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startCount >= sm->maxStart && 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sm->portValid) 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, HELD); 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_AUTHENTICATING: 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapSuccess && !sm->portValid && 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.accept_802_1x_keys && 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.required_keys == 0) { 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: IEEE 802.1X for " 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "plaintext connection; no EAPOL-Key frames " 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "required"); 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portValid = TRUE; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->eapol_done_cb) 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eapol_done_cb(sm->ctx->ctx); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapSuccess && sm->portValid) 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, AUTHENTICATED); 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapFail || (sm->keyDone && !sm->portValid)) 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, HELD); 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->suppTimeout) 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, CONNECTING); 4106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else if (sm->eapTriggerStart) 4116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SM_ENTER(SUPP_PAE, CONNECTING); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_HELD: 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->heldWhile == 0) 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, CONNECTING); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapolEap) 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, RESTART); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_AUTHENTICATED: 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapolEap && sm->portValid) 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, RESTART); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (!sm->portValid) 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, DISCONNECTED); 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_RESTART: 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->eapRestart) 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_PAE, AUTHENTICATING); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_S_FORCE_AUTH: 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_S_FORCE_UNAUTH: 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(KEY_RX, NO_KEY_RECEIVE) 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(KEY_RX, NO_KEY_RECEIVE); 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(KEY_RX, KEY_RECEIVE) 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(KEY_RX, KEY_RECEIVE); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_processKey(sm); 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxKey = FALSE; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(KEY_RX) 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->initialize || !sm->portEnabled) 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(KEY_RX, NO_KEY_RECEIVE); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (sm->KEY_RX_state) { 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case KEY_RX_UNKNOWN: 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case KEY_RX_NO_KEY_RECEIVE: 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->rxKey) 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(KEY_RX, KEY_RECEIVE); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case KEY_RX_KEY_RECEIVE: 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->rxKey) 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(KEY_RX, KEY_RECEIVE); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, REQUEST) 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, REQUEST); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authWhile = 0; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReq = TRUE; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_getSuppRsp(sm); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, RESPONSE) 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, RESPONSE); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_txSuppRsp(sm); 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapResp = FALSE; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, SUCCESS) 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, SUCCESS); 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->keyRun = TRUE; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppSuccess = TRUE; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 493f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 494f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) { 495f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (eap_proxy_key_available(sm->eap_proxy)) { 496d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt u8 *session_id, *emsk; 497d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt size_t session_id_len, emsk_len; 498d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 499f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* New key received - clear IEEE 802.1X EAPOL-Key replay 500f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * counter */ 501f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->replay_counter_valid = FALSE; 502d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 503d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt session_id = eap_proxy_get_eap_session_id( 504d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt sm->eap_proxy, &session_id_len); 505d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt emsk = eap_proxy_get_emsk(sm->eap_proxy, &emsk_len); 506d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (sm->config->erp && session_id && emsk) 507d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt eap_peer_erp_init(sm->eap, session_id, 508d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt session_id_len, emsk, 509d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt emsk_len); 510f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 511f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return; 512f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 513f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 514f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_key_available(sm->eap)) { 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* New key received - clear IEEE 802.1X EAPOL-Key replay 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * counter */ 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->replay_counter_valid = FALSE; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, FAIL) 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, FAIL); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppFail = TRUE; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, TIMEOUT) 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, TIMEOUT); 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppTimeout = TRUE; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, IDLE) 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, IDLE); 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppStart = FALSE; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initial_req = TRUE; 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, INITIALIZE) 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, INITIALIZE); 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_abortSupp(sm); 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppAbort = FALSE; 550c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 551c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 552c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * IEEE Std 802.1X-2004 does not clear authWhile here, but doing so 553c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * allows the timer tick to be stopped more quickly when the port is 554c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * not enabled. Since this variable is used only within RECEIVE state, 555c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * clearing it on initialization does not change actual state machine 556c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * behavior. 557c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 558c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt sm->authWhile = 0; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STATE(SUPP_BE, RECEIVE) 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTRY(SUPP_BE, RECEIVE); 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authWhile = sm->authPeriod; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_enable_timer_tick(sm); 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = FALSE; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapNoResp = FALSE; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initial_req = FALSE; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtSM_STEP(SUPP_BE) 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->initialize || sm->suppAbort) 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER_GLOBAL(SUPP_BE, INITIALIZE); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else switch (sm->SUPP_BE_state) { 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_UNKNOWN: 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_REQUEST: 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE Std 802.1X-2004 has transitions from REQUEST to FAIL 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and SUCCESS based on eapFail and eapSuccess, respectively. 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * However, IEEE Std 802.1X-2004 is also specifying that 5851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * eapNoResp should be set in conjunction with eapSuccess and 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapFail which would mean that more than one of the 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * transitions here would be activated at the same time. 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Skipping RESPONSE and/or RECEIVE states in these cases can 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cause problems and the direct transitions to do not seem 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * correct. Because of this, the conditions for these 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * transitions are verified only after eapNoResp. They are 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unlikely to be used since eapNoResp should always be set if 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * either of eapSuccess or eapFail is set. 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapResp && sm->eapNoResp) { 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: SUPP_BE REQUEST: both " 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "eapResp and eapNoResp set?!"); 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapResp) 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, RESPONSE); 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapNoResp) 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, RECEIVE); 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapFail) 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, FAIL); 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapSuccess) 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, SUCCESS); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_RESPONSE: 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, RECEIVE); 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_SUCCESS: 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, IDLE); 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_FAIL: 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, IDLE); 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_TIMEOUT: 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, IDLE); 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_IDLE: 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapFail && sm->suppStart) 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, FAIL); 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapolEap && sm->suppStart) 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, REQUEST); 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapSuccess && sm->suppStart) 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, SUCCESS); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_INITIALIZE: 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, IDLE); 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_RECEIVE: 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapolEap) 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, REQUEST); 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapFail) 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, FAIL); 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->authWhile == 0) 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, TIMEOUT); 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (sm->eapSuccess) 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_ENTER(SUPP_BE, SUCCESS); 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txLogoff(struct eapol_sm *sm) 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: txLogoff"); 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eapol_send(sm->ctx->eapol_send_ctx, 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE802_1X_TYPE_EAPOL_LOGOFF, (u8 *) "", 0); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolLogoffFramesTx++; 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesTx++; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txStart(struct eapol_sm *sm) 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: txStart"); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eapol_send(sm->ctx->eapol_send_ctx, 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE802_1X_TYPE_EAPOL_START, (u8 *) "", 0); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolStartFramesTx++; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesTx++; 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IEEE8021X_ENCR_KEY_LEN 32 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IEEE8021X_SIGN_KEY_LEN 32 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_key_data { 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 encr_key[IEEE8021X_ENCR_KEY_LEN]; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 sign_key[IEEE8021X_SIGN_KEY_LEN]; 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_processKey(struct eapol_sm *sm) 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 67661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifndef CONFIG_FIPS 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *hdr; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_eapol_key *key; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_key_data keydata; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 orig_key_sign[IEEE8021X_KEY_SIGN_LEN], datakey[32]; 681d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef CONFIG_NO_RC4 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ekey[IEEE8021X_KEY_IV_LEN + IEEE8021X_ENCR_KEY_LEN]; 683d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_NO_RC4 */ 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_len, res, sign_key_len, encr_key_len; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 rx_key_length; 68661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t plen; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: processKey"); 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->last_rx_key == NULL) 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->conf.accept_802_1x_keys) { 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: Received IEEE 802.1X EAPOL-Key" 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " even though this was not accepted - " 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignoring this packet"); 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 69961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->last_rx_key_len < sizeof(*hdr) + sizeof(*key)) 70061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct ieee802_1x_hdr *) sm->last_rx_key; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = (struct ieee802_1x_eapol_key *) (hdr + 1); 70361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt plen = be_to_host16(hdr->length); 70461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sizeof(*hdr) + plen > sm->last_rx_key_len || plen < sizeof(*key)) { 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: Too short EAPOL-Key frame"); 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_key_length = WPA_GET_BE16(key->key_length); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: RX IEEE 802.1X ver=%d type=%d len=%d " 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAPOL-Key: type=%d key_length=%d key_index=0x%x", 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->version, hdr->type, be_to_host16(hdr->length), 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->type, rx_key_length, key->key_index); 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_lower_layer_success(sm, 1); 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sign_key_len = IEEE8021X_SIGN_KEY_LEN; 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_key_len = IEEE8021X_ENCR_KEY_LEN; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = eapol_sm_get_key(sm, (u8 *) &keydata, sizeof(keydata)); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Could not get master key for " 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "decrypting EAPOL-Key keys"); 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 16) { 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* LEAP derives only 16 bytes of keying material. */ 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = eapol_sm_get_key(sm, (u8 *) &keydata, 16); 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Could not get LEAP " 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "master key for decrypting EAPOL-Key keys"); 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sign_key_len = 16; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_key_len = 16; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(keydata.sign_key, keydata.encr_key, 16); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (res) { 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Could not get enough master key " 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data for decrypting EAPOL-Key keys (res=%d)", res); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* The key replay_counter must increase when same master key */ 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->replay_counter_valid && 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sm->last_replay_counter, key->replay_counter, 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE8021X_REPLAY_COUNTER_LEN) >= 0) { 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: EAPOL-Key replay counter did " 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not increase - ignoring key"); 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAPOL: last replay counter", 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_replay_counter, 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE8021X_REPLAY_COUNTER_LEN); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAPOL: received replay counter", 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->replay_counter, IEEE8021X_REPLAY_COUNTER_LEN); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Verify key signature (HMAC-MD5) */ 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(orig_key_sign, key->key_signature, IEEE8021X_KEY_SIGN_LEN); 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(key->key_signature, 0, IEEE8021X_KEY_SIGN_LEN); 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac_md5(keydata.sign_key, sign_key_len, 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_key, sizeof(*hdr) + be_to_host16(hdr->length), 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_signature); 760c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (os_memcmp_const(orig_key_sign, key->key_signature, 761c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt IEEE8021X_KEY_SIGN_LEN) != 0) { 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Invalid key signature in " 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAPOL-Key packet"); 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key->key_signature, orig_key_sign, 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE8021X_KEY_SIGN_LEN); 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: EAPOL-Key key signature verified"); 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 77061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt key_len = plen - sizeof(*key); 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_len > 32 || rx_key_length > 32) { 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: Too long key data length %d", 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_len ? key_len : rx_key_length); 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_len == rx_key_length) { 777d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef CONFIG_NO_RC4 778d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (encr_key_len) { 779d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* otherwise unused */ 780d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 781d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_ERROR, "EAPOL: RC4 not supported in the build"); 782d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 783d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else /* CONFIG_NO_RC4 */ 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ekey, key->key_iv, IEEE8021X_KEY_IV_LEN); 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ekey + IEEE8021X_KEY_IV_LEN, keydata.encr_key, 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_key_len); 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(datakey, key + 1, key_len); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rc4_skip(ekey, IEEE8021X_KEY_IV_LEN + encr_key_len, 0, 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt datakey, key_len); 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAPOL: Decrypted(RC4) key", 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt datakey, key_len); 792d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_NO_RC4 */ 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (key_len == 0) { 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.1X-2004 specifies that least significant Key Length 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * octets from MS-MPPE-Send-Key are used as the key if the key 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data is not present. This seems to be meaning the beginning 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * of the MS-MPPE-Send-Key. In addition, MS-MPPE-Send-Key in 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Supplicant corresponds to MS-MPPE-Recv-Key in Authenticator. 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Anyway, taking the beginning of the keying material from EAP 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * seems to interoperate with Authenticators. 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_len = rx_key_length; 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(datakey, keydata.encr_key, key_len); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAPOL: using part of EAP keying " 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "material data encryption key", 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt datakey, key_len); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Invalid key data length %d " 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(key_length=%d)", key_len, rx_key_length); 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->replay_counter_valid = TRUE; 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->last_replay_counter, key->replay_counter, 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE8021X_REPLAY_COUNTER_LEN); 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Setting dynamic WEP key: %s keyidx %d " 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "len %d", 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index & IEEE8021X_KEY_INDEX_FLAG ? 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unicast" : "broadcast", 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index & IEEE8021X_KEY_INDEX_MASK, key_len); 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->set_wep_key && 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->set_wep_key(sm->ctx->ctx, 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index & IEEE8021X_KEY_INDEX_FLAG, 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->key_index & IEEE8021X_KEY_INDEX_MASK, 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt datakey, key_len) < 0) { 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: Failed to set WEP key to the " 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " driver."); 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key->key_index & IEEE8021X_KEY_INDEX_FLAG) 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->unicast_key_received = TRUE; 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->broadcast_key_received = TRUE; 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sm->unicast_key_received || 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_UNICAST)) && 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->broadcast_key_received || 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_BROADCAST))) 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: all required EAPOL-Key " 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frames received"); 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portValid = TRUE; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->eapol_done_cb) 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eapol_done_cb(sm->ctx->ctx); 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 84961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_FIPS */ 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_getSuppRsp(struct eapol_sm *sm) 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: getSuppRsp"); 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* EAP layer processing; no special code is needed, since Supplicant 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Backend state machine is waiting for eapNoResp or eapResp to be set 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and these are only set in the EAP state machine when the processing 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has finished. */ 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_txSuppRsp(struct eapol_sm *sm) 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: txSuppRsp"); 868f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 869f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 870f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) { 871f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* Get EAP Response from EAP Proxy */ 872f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt resp = eap_proxy_get_eapRespData(sm->eap_proxy); 873f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (resp == NULL) { 874f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP Proxy " 875f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "response data not available"); 876f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return; 877f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 878f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } else 879f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 880f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_get_eapRespData(sm->eap); 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) { 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP response data " 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not available"); 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Send EAP-Packet from the EAP layer to the Authenticator */ 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eapol_send(sm->ctx->eapol_send_ctx, 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head(resp), 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(resp)); 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* eapRespData is not used anymore, so free it here */ 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->initial_req) 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolReqIdFramesRx++; 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolReqFramesRx++; 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolRespFramesTx++; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesTx++; 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_abortSupp(struct eapol_sm *sm) 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* release system resources that may have been allocated for the 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication session */ 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->last_rx_key); 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_key = NULL; 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapReqData); 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReqData = NULL; 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_abort(sm->eap); 914d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 915d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt eap_proxy_sm_abort(sm->eap_proxy); 916d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx) 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(timeout_ctx); 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_port_authorized(struct eapol_sm *sm) 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 928fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int cb; 929fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 930fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cb = sm->suppPortStatus != Authorized || sm->force_authorized_update; 931fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->force_authorized_update = FALSE; 932fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->suppPortStatus = Authorized; 933fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cb && sm->ctx->port_cb) 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->port_cb(sm->ctx->ctx, 1); 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_port_unauthorized(struct eapol_sm *sm) 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 940fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int cb; 941fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 942fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cb = sm->suppPortStatus != Unauthorized || sm->force_authorized_update; 943fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->force_authorized_update = FALSE; 944fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->suppPortStatus = Unauthorized; 945fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cb && sm->ctx->port_cb) 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->port_cb(sm->ctx->ctx, 0); 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_step - EAPOL state machine step function 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called to notify the state machine about changed external 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * variables. It will step through the EAPOL state machines in loop to process 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * all triggered state changes. 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_step(struct eapol_sm *sm) 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* In theory, it should be ok to run this in loop until !changed. 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * However, it is better to use a limit on number of iterations to 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * allow events (e.g., SIGTERM) to stop the program cleanly if the 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state machine were to generate a busy loop. */ 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 100; i++) { 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->changed = FALSE; 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(SUPP_PAE); 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(KEY_RX); 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SM_STEP_RUN(SUPP_BE); 971f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 972f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) { 973f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* Drive the EAP proxy state machine */ 974f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (eap_proxy_sm_step(sm->eap_proxy, sm->eap)) 975f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->changed = TRUE; 976f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } else 977f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_peer_sm_step(sm->eap)) 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->changed = TRUE; 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->changed) 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->changed) { 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* restart EAPOL state machine step from timeout call in order 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to allow other events to be processed. */ 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm); 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, eapol_sm_step_timeout, NULL, sm); 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->cb && sm->cb_status != EAPOL_CB_IN_PROGRESS) { 992344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt enum eapol_supp_result result; 993344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (sm->cb_status == EAPOL_CB_SUCCESS) 994344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt result = EAPOL_SUPP_RESULT_SUCCESS; 995344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt else if (eap_peer_was_failure_expected(sm->eap)) 996344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt result = EAPOL_SUPP_RESULT_EXPECTED_FAILURE; 997344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt else 998344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt result = EAPOL_SUPP_RESULT_FAILURE; 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cb_status = EAPOL_CB_IN_PROGRESS; 1000344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt sm->ctx->cb(sm, result, sm->ctx->cb_ctx); 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char *eapol_supp_pae_state(int state) 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_LOGOFF: 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "LOGOFF"; 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_DISCONNECTED: 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "DISCONNECTED"; 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_CONNECTING: 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "CONNECTING"; 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_AUTHENTICATING: 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "AUTHENTICATING"; 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_HELD: 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "HELD"; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_AUTHENTICATED: 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "AUTHENTICATED"; 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_PAE_RESTART: 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "RESTART"; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char *eapol_supp_be_state(int state) 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_REQUEST: 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "REQUEST"; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_RESPONSE: 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "RESPONSE"; 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_SUCCESS: 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SUCCESS"; 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_FAIL: 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "FAIL"; 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_TIMEOUT: 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "TIMEOUT"; 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_IDLE: 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "IDLE"; 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_INITIALIZE: 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "INITIALIZE"; 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUPP_BE_RECEIVE: 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "RECEIVE"; 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "UNKNOWN"; 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eapol_port_status(PortStatus status) 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status == Authorized) 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Authorized"; 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Unauthorized"; 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */ 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eapol_port_control(PortControl ctrl) 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ctrl) { 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Auto: 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Auto"; 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case ForceUnauthorized: 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "ForceUnauthorized"; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case ForceAuthorized: 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "ForceAuthorized"; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Unknown"; 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_configure - Set EAPOL variables 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @heldPeriod: dot1xSuppHeldPeriod 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @authPeriod: dot1xSuppAuthPeriod 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @startPeriod: dot1xSuppStartPeriod 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @maxStart: dot1xSuppMaxStart 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Set configurable EAPOL state machine variables. Each variable can be set to 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the given value or ignored if set to -1 (to set only some of the variables). 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod, 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int startPeriod, int maxStart) 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (heldPeriod >= 0) 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldPeriod = heldPeriod; 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (authPeriod >= 0) 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authPeriod = authPeriod; 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (startPeriod >= 0) 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startPeriod = startPeriod; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (maxStart >= 0) 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->maxStart = maxStart; 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_get_method_name - Get EAPOL method name 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Static string containing name of current eap method or NULL 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * eapol_sm_get_method_name(struct eapol_sm *sm) 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED || 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppPortStatus != Authorized) 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_sm_get_method_name(sm->eap); 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_get_status - Get EAPOL state machine status 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for status information 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: Maximum buffer length 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @verbose: Whether to include verbose status information 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to buf. 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Query EAPOL state machine for status information. This function fills in a 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * text area with current status information from the EAPOL state machine. If 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the buffer (buf) is not large enough, status information will be truncated 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to fit the buffer. 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen, 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int verbose) 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, ret; 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(buf, buflen, 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Supplicant PAE state=%s\n" 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "suppPortStatus=%s\n", 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_supp_pae_state(sm->SUPP_PAE_state), 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_port_status(sm->suppPortStatus)); 11496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen, len)) 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (verbose) { 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "heldPeriod=%u\n" 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authPeriod=%u\n" 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "startPeriod=%u\n" 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "maxStart=%u\n" 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "portControl=%s\n" 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Supplicant Backend state=%s\n", 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldPeriod, 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authPeriod, 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startPeriod, 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->maxStart, 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_port_control(sm->portControl), 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_supp_be_state(sm->SUPP_BE_state)); 11666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1171f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 1172f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) 1173f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt len += eap_proxy_sm_get_status(sm->eap_proxy, 1174f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt buf + len, buflen - len, 1175f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt verbose); 1176f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt else 1177f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += eap_sm_get_status(sm->eap, buf + len, buflen - len, verbose); 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_get_mib - Get EAPOL state machine MIBs 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for MIB information 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: Maximum buffer length 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to buf. 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Query EAPOL state machine for MIB information. This function fills in a 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * text area with current MIB information from the EAPOL state machine. If 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the buffer (buf) is not large enough, MIB information will be truncated to 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * fit the buffer. 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen) 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf, buflen, 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppPaeState=%d\n" 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppHeldPeriod=%u\n" 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppAuthPeriod=%u\n" 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppStartPeriod=%u\n" 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppMaxStart=%u\n" 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppSuppControlledPortStatus=%s\n" 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppBackendPaeState=%d\n", 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->SUPP_PAE_state, 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldPeriod, 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authPeriod, 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startPeriod, 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->maxStart, 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->suppPortStatus == Authorized ? 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Authorized" : "Unauthorized", 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->SUPP_BE_state); 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen, ret)) 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ret; 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolFramesRx=%u\n" 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolFramesTx=%u\n" 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolStartFramesTx=%u\n" 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolLogoffFramesTx=%u\n" 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolRespFramesTx=%u\n" 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolReqIdFramesRx=%u\n" 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapolReqFramesRx=%u\n" 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppInvalidEapolFramesRx=%u\n" 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppEapLengthErrorFramesRx=%u\n" 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppLastEapolFrameVersion=%u\n" 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dot1xSuppLastEapolFrameSource=" MACSTR "\n", 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesRx, 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesTx, 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolStartFramesTx, 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolLogoffFramesTx, 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolRespFramesTx, 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolReqIdFramesRx, 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolReqFramesRx, 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppInvalidEapolFramesRx, 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapLengthErrorFramesRx, 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppLastEapolFrameVersion, 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sm->dot1xSuppLastEapolFrameSource)); 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */ 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_rx_eapol - Process received EAPOL frames 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @src: Source MAC address of the EAPOL packet 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Pointer to the beginning of the EAPOL data (EAPOL header) 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the EAPOL frame 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 = EAPOL frame processed, 0 = not for EAPOL state machine, 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * -1 failure 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf, 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee802_1x_hdr *hdr; 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee802_1x_eapol_key *key; 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int data_len; 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = 1; 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t plen; 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesRx++; 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(*hdr)) { 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppInvalidEapolFramesRx++; 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (const struct ieee802_1x_hdr *) buf; 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppLastEapolFrameVersion = hdr->version; 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->dot1xSuppLastEapolFrameSource, src, ETH_ALEN); 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->version < EAPOL_VERSION) { 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: backwards compatibility */ 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = be_to_host16(hdr->length); 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen > len - sizeof(*hdr)) { 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapLengthErrorFramesRx++; 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 1294661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (sm->conf.wps && sm->conf.workaround && 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen < len - sizeof(*hdr) && 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->type == IEEE802_1X_TYPE_EAP_PACKET && 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len - sizeof(*hdr) > sizeof(struct eap_hdr)) { 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_hdr *ehdr = 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const struct eap_hdr *) (hdr + 1); 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 elen; 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elen = be_to_host16(ehdr->length); 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elen > plen && elen <= len - sizeof(*hdr)) { 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Buffalo WHR-G125 Ver.1.47 seems to send EAP-WPS 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * packets with too short EAPOL header length field 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (14 octets). This is fixed in firmware Ver.1.49. 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * As a workaround, fix the EAPOL header based on the 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * correct length in the EAP packet. 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Workaround - fix EAPOL " 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "payload length based on EAP header: " 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d -> %d", (int) plen, elen); 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = elen; 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len = plen + sizeof(*hdr); 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->type) { 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case IEEE802_1X_TYPE_EAP_PACKET: 13225605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (sm->conf.workaround) { 13235605286c30e1701491bd3af974ae423727750eddDmitry Shmidt /* 13245605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * An AP has been reported to send out EAP message with 13255605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * undocumented code 10 at some point near the 13265605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * completion of EAP authentication. This can result in 13275605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * issues with the unexpected EAP message triggering 13285605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * restart of EAPOL authentication. Avoid this by 13295605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * skipping the message without advancing the state 13305605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * machine. 13315605286c30e1701491bd3af974ae423727750eddDmitry Shmidt */ 13325605286c30e1701491bd3af974ae423727750eddDmitry Shmidt const struct eap_hdr *ehdr = 13335605286c30e1701491bd3af974ae423727750eddDmitry Shmidt (const struct eap_hdr *) (hdr + 1); 13345605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (plen >= sizeof(*ehdr) && ehdr->code == 10) { 13355605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Ignore EAP packet with unknown code 10"); 13365605286c30e1701491bd3af974ae423727750eddDmitry Shmidt break; 13375605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 13385605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 13395605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->cached_pmk) { 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Trying to use PMKSA caching, but Authenticator did 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * not seem to have a matching entry. Need to restart 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAPOL state machines. 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_abort_cached(sm); 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapReqData); 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReqData = wpabuf_alloc_copy(hdr + 1, plen); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapReqData) { 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Received EAP-Packet " 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame"); 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = TRUE; 1353f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 1354f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) { 1355f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt eap_proxy_packet_update( 1356f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->eap_proxy, 1357f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpabuf_mhead_u8(sm->eapReqData), 1358f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpabuf_len(sm->eapReqData)); 1359f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: eap_proxy " 1360f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "EAP Req updated"); 1361f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 1362f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case IEEE802_1X_TYPE_EAPOL_KEY: 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plen < sizeof(*key)) { 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Too short EAPOL-Key " 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame received"); 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = (const struct ieee802_1x_eapol_key *) (hdr + 1); 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key->type == EAPOL_KEY_TYPE_WPA || 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key->type == EAPOL_KEY_TYPE_RSN) { 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPA Supplicant takes care of this frame. */ 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Ignoring WPA EAPOL-Key " 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame in EAPOL state machines"); 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = 0; 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key->type != EAPOL_KEY_TYPE_RC4) { 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Ignored unknown " 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAPOL-Key type %d", key->type); 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->last_rx_key); 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_key = os_malloc(data_len); 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->last_rx_key) { 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Received EAPOL-Key " 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame"); 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->last_rx_key, buf, data_len); 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->last_rx_key_len = data_len; 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->rxKey = TRUE; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#ifdef CONFIG_MACSEC 13985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt case IEEE802_1X_TYPE_EAPOL_MKA: 13995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_EXCESSIVE, 14005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "EAPOL type %d will be handled by MKA", 14015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr->type); 14025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 14035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif /* CONFIG_MACSEC */ 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Received unknown EAPOL type %d", 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->type); 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppInvalidEapolFramesRx++; 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_tx_eapol_key - Notification about transmitted EAPOL packet 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machine about transmitted EAPOL packet from an external 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * component, e.g., WPA. This will update the statistics. 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm) 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->dot1xSuppEapolFramesTx++; 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_portEnabled - Notification about portEnabled change 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @enabled: New portEnabled value 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machine about new portEnabled value. 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled) 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "portEnabled=%d", enabled); 1442fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (sm->portEnabled != enabled) 1443fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->force_authorized_update = TRUE; 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portEnabled = enabled; 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_portValid - Notification about portValid change 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @valid: New portValid value 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machine about new portValid value. 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid) 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "portValid=%d", valid); 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portValid = valid; 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_eap_success - Notification of external EAP success trigger 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @success: %TRUE = set success, %FALSE = clear success 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify the EAPOL state machine that external event has forced EAP state to 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * success (success = %TRUE). This can be cleared by setting success = %FALSE. 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called to update EAP state when WPA-PSK key handshake has 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * been completed successfully since WPA-PSK does not use EAP state machine. 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_eap_success(struct eapol_sm *sm, Boolean success) 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP success=%d", success); 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapSuccess = success; 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->altAccept = success; 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (success) 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_notify_success(sm->eap); 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_eap_fail - Notification of external EAP failure trigger 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @fail: %TRUE = set failure, %FALSE = clear failure 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machine that external event has forced EAP state to 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * failure (fail = %TRUE). This can be cleared by setting fail = %FALSE. 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail) 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP fail=%d", fail); 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapFail = fail; 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->altReject = fail; 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_config - Notification of EAPOL configuration change 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config: Pointer to current network EAP configuration 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Pointer to EAPOL configuration data 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machine that configuration has changed. config will be 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * stored as a backpointer to network configuration. This can be %NULL to clear 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the stored pointed. conf will be copied to local EAPOL/EAP configuration 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data. If conf is %NULL, this part of the configuration change will be 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * skipped. 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_config(struct eapol_sm *sm, 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config, 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eapol_config *conf) 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->config = config; 1532f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 1533f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->use_eap_proxy = eap_proxy_notify_config(sm->eap_proxy, config) > 0; 1534f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf == NULL) 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.accept_802_1x_keys = conf->accept_802_1x_keys; 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.required_keys = conf->required_keys; 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.fast_reauth = conf->fast_reauth; 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->conf.workaround = conf->workaround; 1543661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt sm->conf.wps = conf->wps; 1544f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 1545f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->use_eap_proxy) { 1546f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* Using EAP Proxy, so skip EAP state machine update */ 1547f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return; 1548f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 1549f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap) { 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_set_fast_reauth(sm->eap, conf->fast_reauth); 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_set_workaround(sm->eap, conf->workaround); 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_set_force_disabled(sm->eap, conf->eap_disabled); 1554051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt eap_set_external_sim(sm->eap, conf->external_sim); 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_get_key - Get master session key (MSK) from EAP 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @key: Pointer for key buffer 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Number of bytes to copy to key 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success (len of key available), maximum available key len 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (>0) if key is available but it is shorter than len, or -1 on failure. 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fetch EAP keying material (MSK, eapKeyData) from EAP state machine. The key 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is available only after a successful authentication. 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len) 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *eap_key; 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t eap_len; 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1575f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 157609f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt if (sm && sm->use_eap_proxy) { 1577f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* Get key from EAP proxy */ 1578f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm == NULL || !eap_proxy_key_available(sm->eap_proxy)) { 1579f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available"); 1580f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return -1; 1581f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 1582f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt eap_key = eap_proxy_get_eapKeyData(sm->eap_proxy, &eap_len); 1583f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (eap_key == NULL) { 1584f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Failed to get " 1585f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "eapKeyData"); 1586f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return -1; 1587f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 1588f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt goto key_fetched; 1589f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 1590f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || !eap_key_available(sm->eap)) { 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available"); 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_key = eap_get_eapKeyData(sm->eap, &eap_len); 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_key == NULL) { 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Failed to get eapKeyData"); 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1600f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 1601f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtkey_fetched: 1602f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > eap_len) { 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Requested key length (%lu) not " 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available (len=%lu)", 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) eap_len); 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_len; 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key, eap_key, len); 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: Successfully fetched key (len=%lu)", 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * eapol_sm_get_session_id - Get EAP Session-Id 16185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 16195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * @len: Pointer to variable that will be set to number of bytes in the session 16205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Returns: Pointer to the EAP Session-Id or %NULL on failure 16215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * 16225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * The Session-Id is available only after a successful authentication. 16235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 16245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst u8 * eapol_sm_get_session_id(struct eapol_sm *sm, size_t *len) 16255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 16265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (sm == NULL || !eap_key_available(sm->eap)) { 16275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: EAP Session-Id not available"); 16285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 16295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 16305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return eap_get_eapSessionId(sm->eap, len); 16315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 16325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_logoff - Notification of logon/logoff commands 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @logoff: Whether command was logoff 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines that user requested logon/logoff. 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff) 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) { 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->userLogoff = logoff; 16458da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (!logoff) { 16468da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt /* If there is a delayed txStart queued, start now. */ 16478da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt sm->startWhen = 0; 16488da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_pmkid_attempt - Notification of successful PMKSA caching 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines that PMKSA caching was successful. This is used 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to move EAPOL and EAP state machines into authenticated/successful state. 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_cached(struct eapol_sm *sm) 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: PMKSA caching was used - skip EAPOL"); 1666d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sm->eapSuccess = TRUE; 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_notify_success(sm->eap); 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_pmkid_attempt - Notification of PMKSA caching 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1676216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * Notify EAPOL state machines if PMKSA caching is used. 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1678216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtvoid eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm) 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1682216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "RSN: Trying to use cached PMKSA"); 1683216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt sm->cached_pmk = TRUE; 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_abort_cached(struct eapol_sm *sm) 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "RSN: Authenticator did not accept PMKID, " 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "doing full EAP authentication"); 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->cached_pmk = FALSE; 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->SUPP_PAE_state = SUPP_PAE_CONNECTING; 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_port_unauthorized(sm); 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure we do not start sending EAPOL-Start frames first, but 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * instead move to RESTART state to start EAPOL authentication. */ 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startWhen = 3; 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_enable_timer_tick(sm); 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->aborted_cached) 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->aborted_cached(sm->ctx->ctx); 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_register_scard_ctx - Notification of smart card context 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context data for smart card operations 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines of context data for smart card operations. This 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * context data will be used as a parameter for scard_*() functions. 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx) 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) { 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->scard_ctx = ctx; 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_register_scard_ctx(sm->eap, ctx); 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_portControl - Notification of portControl changes 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @portControl: New value for portControl variable 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines that portControl variable has changed. 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl) 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "portControl=%s", eapol_port_control(portControl)); 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portControl = portControl; 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_ctrl_attached - Notification of attached monitor 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines that a monitor was attached to the control 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface to trigger re-sending of pending requests for user input. 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_ctrl_attached(struct eapol_sm *sm) 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_notify_ctrl_attached(sm->eap); 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_ctrl_response - Notification of received user input 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL state machines that a control response, i.e., user 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input, was received in order to trigger retrying of a pending EAP request. 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_ctrl_response(struct eapol_sm *sm) 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapReqData && !sm->eapReq) { 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: received control response (user " 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "input) notification - retrying pending EAP " 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request"); 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = TRUE; 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReq = TRUE; 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_request_reauth - Request reauthentication 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to request EAPOL reauthentication, e.g., when the 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current PMKSA entry is nearing expiration. 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_request_reauth(struct eapol_sm *sm) 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED) 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_txStart(sm); 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_notify_lower_layer_success - Notification of lower layer success 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_eapol_sm: Whether the caller is already running inside EAPOL state 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * machine loop (eapol_sm_step()) 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Notify EAPOL (and EAP) state machines that a lower layer has detected a 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * successful authentication. This is used to recover from dropped EAP-Success 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * messages. 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, int in_eapol_sm) 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_notify_lower_layer_success(sm->eap); 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!in_eapol_sm) 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_invalidate_cached_session - Mark cached EAP session data invalid 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_invalidate_cached_session(struct eapol_sm *sm) 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm) 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_invalidate_cached_session(sm->eap); 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eap_peer_config * eapol_sm_get_config(void *ctx) 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm ? sm->config : NULL; 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eapol_sm_get_eapReqData(void *ctx) 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL || sm->eapReqData == NULL) 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapReqData; 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eapol_sm_get_bool(void *ctx, enum eapol_bool_var variable) 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FALSE; 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (variable) { 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapSuccess: 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapSuccess; 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapRestart: 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapRestart; 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapFail: 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapFail; 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapResp: 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapResp; 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapNoResp: 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapNoResp; 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapReq: 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->eapReq; 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_portEnabled: 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->portEnabled; 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_altAccept: 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->altAccept; 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_altReject: 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->altReject; 18666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case EAPOL_eapTriggerStart: 18676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return sm->eapTriggerStart; 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FALSE; 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_bool(void *ctx, enum eapol_bool_var variable, 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Boolean value) 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (variable) { 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapSuccess: 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapSuccess = value; 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapRestart: 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapRestart = value; 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapFail: 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapFail = value; 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapResp: 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapResp = value; 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapNoResp: 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapNoResp = value; 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_eapReq: 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReq = value; 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_portEnabled: 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portEnabled = value; 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_altAccept: 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->altAccept = value; 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_altReject: 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->altReject = value; 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case EAPOL_eapTriggerStart: 19086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sm->eapTriggerStart = value; 19096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned int eapol_sm_get_int(void *ctx, enum eapol_int_var variable) 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (variable) { 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_idleWhile: 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->idleWhile; 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_int(void *ctx, enum eapol_int_var variable, 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int value) 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (variable) { 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAPOL_idleWhile: 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->idleWhile = value; 193661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->idleWhile > 0) 193761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eapol_enable_timer_tick(sm); 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_set_config_blob(void *ctx, struct wpa_config_blob *blob) 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm && sm->ctx && sm->ctx->set_config_blob) 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->set_config_blob(sm->ctx->ctx, blob); 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const struct wpa_config_blob * 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidteapol_sm_get_config_blob(void *ctx, const char *name) 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CONFIG_BLOBS 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm && sm->ctx && sm->ctx->get_config_blob) 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm->ctx->get_config_blob(sm->ctx->ctx, name); 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NO_CONFIG_BLOBS */ 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CONFIG_BLOBS */ 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_notify_pending(void *ctx) 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eapReqData && !sm->eapReq) { 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: received notification from EAP " 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state machine - retrying pending EAP Request"); 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapolEap = TRUE; 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eapReq = TRUE; 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 19841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void eapol_sm_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field, 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *txt) 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm = ctx; 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAPOL: EAP parameter needed"); 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->ctx->eap_param_needed) 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx->eap_param_needed(sm->ctx->ctx, field, txt); 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define eapol_sm_eap_param_needed NULL 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1996c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidtstatic void eapol_sm_notify_cert(void *ctx, int depth, const char *subject, 19972f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt const char *altsubject[], 19982f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int num_altsubject, const char *cert_hash, 1999c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt const struct wpabuf *cert) 2000c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt{ 2001c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt struct eapol_sm *sm = ctx; 2002c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (sm->ctx->cert_cb) 20032f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sm->ctx->cert_cb(sm->ctx->ctx, depth, subject, altsubject, 20042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_altsubject, cert_hash, cert); 2005c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt} 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 200704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 200804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void eapol_sm_notify_status(void *ctx, const char *status, 200904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const char *parameter) 201004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 201104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct eapol_sm *sm = ctx; 201204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 201304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sm->ctx->status_cb) 201404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sm->ctx->status_cb(sm->ctx->ctx, status, parameter); 201504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 201604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 20179c86a7f3b4994b1346418f183a9e71c82c87de65Ahmed ElArabawystatic void eapol_sm_notify_eap_error(void *ctx, int error_code) 20189c86a7f3b4994b1346418f183a9e71c82c87de65Ahmed ElArabawy{ 20199c86a7f3b4994b1346418f183a9e71c82c87de65Ahmed ElArabawy struct eapol_sm *sm = ctx; 20209c86a7f3b4994b1346418f183a9e71c82c87de65Ahmed ElArabawy 20219c86a7f3b4994b1346418f183a9e71c82c87de65Ahmed ElArabawy if (sm->ctx->eap_error_cb) 20229c86a7f3b4994b1346418f183a9e71c82c87de65Ahmed ElArabawy sm->ctx->eap_error_cb(sm->ctx->ctx, error_code); 20239c86a7f3b4994b1346418f183a9e71c82c87de65Ahmed ElArabawy} 202404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2025203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#ifdef CONFIG_EAP_PROXY 2026293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2027203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidtstatic void eapol_sm_eap_proxy_cb(void *ctx) 2028203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt{ 2029203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt struct eapol_sm *sm = ctx; 2030203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 2031203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (sm->ctx->eap_proxy_cb) 2032203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt sm->ctx->eap_proxy_cb(sm->ctx->ctx); 2033203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt} 2034293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2035293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2036293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidtstatic void 2037293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidteapol_sm_eap_proxy_notify_sim_status(void *ctx, 2038293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt enum eap_proxy_sim_state sim_state) 2039293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt{ 2040293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt struct eapol_sm *sm = ctx; 2041293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2042293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt if (sm->ctx->eap_proxy_notify_sim_status) 2043293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt sm->ctx->eap_proxy_notify_sim_status(sm->ctx->ctx, sim_state); 2044293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt} 2045293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 2046203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 2047203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 2048203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 20494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic void eapol_sm_set_anon_id(void *ctx, const u8 *id, size_t len) 20504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 20514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eapol_sm *sm = ctx; 20524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 20534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sm->ctx->set_anon_id) 20544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sm->ctx->set_anon_id(sm->ctx->ctx, id, len); 20554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 20564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 20574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 20581d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidtstatic const struct eapol_callbacks eapol_cb = 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_config, 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_bool, 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_bool, 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_int, 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_int, 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_eapReqData, 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_set_config_blob, 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_config_blob, 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_pending, 2069c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt eapol_sm_eap_param_needed, 207004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eapol_sm_notify_cert, 20714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt eapol_sm_notify_status, 20729c86a7f3b4994b1346418f183a9e71c82c87de65Ahmed ElArabawy eapol_sm_notify_eap_error, 2073203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#ifdef CONFIG_EAP_PROXY 2074203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt eapol_sm_eap_proxy_cb, 2075293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt eapol_sm_eap_proxy_notify_sim_status, 2076d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt eapol_sm_get_eap_proxy_imsi, 2077203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 20784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt eapol_sm_set_anon_id 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_init - Initialize EAPOL state machine 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Pointer to EAPOL context data; this needs to be an allocated buffer 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and EAPOL state machine will free it in eapol_sm_deinit() 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the allocated EAPOL state machine or %NULL on failure 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Allocate and initialize an EAPOL state machine. 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx) 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_sm *sm; 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_config conf; 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm = os_zalloc(sizeof(*sm)); 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ctx = ctx; 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->portControl = Auto; 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supplicant PAE state machine */ 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->heldPeriod = 60; 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->startPeriod = 30; 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->maxStart = 3; 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supplicant Backend state machine */ 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->authPeriod = 30; 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&conf, 0, sizeof(conf)); 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.opensc_engine_path = ctx->opensc_engine_path; 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.pkcs11_engine_path = ctx->pkcs11_engine_path; 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.pkcs11_module_path = ctx->pkcs11_module_path; 21136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt conf.openssl_ciphers = ctx->openssl_ciphers; 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf.wps = ctx->wps; 21151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conf.cert_in_cb = ctx->cert_in_cb; 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->eap = eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf); 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->eap == NULL) { 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2123f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 2124f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->use_eap_proxy = FALSE; 2125f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt sm->eap_proxy = eap_proxy_init(sm, &eapol_cb, sm->ctx->msg_ctx); 2126f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (sm->eap_proxy == NULL) { 2127f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_printf(MSG_ERROR, "Unable to initialize EAP Proxy"); 2128f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 2129f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 2130f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Initialize EAPOL state machines */ 2132fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sm->force_authorized_update = TRUE; 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initialize = TRUE; 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->initialize = FALSE; 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_step(sm); 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->timer_tick_enabled = 1; 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm); 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sm; 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eapol_sm_deinit - Deinitialize EAPOL state machine 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Deinitialize and free EAPOL state machine. 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eapol_sm_deinit(struct eapol_sm *sm) 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm == NULL) 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm); 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm); 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_sm_deinit(sm->eap); 2158f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_EAP_PROXY 2159f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt eap_proxy_deinit(sm->eap_proxy); 2160f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->last_rx_key); 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sm->eapReqData); 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->ctx); 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm); 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 216661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 216761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 216861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm, 216961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct ext_password_data *ext) 217061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 217161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm && sm->eap) 217261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eap_sm_set_ext_pw_ctx(sm->eap, ext); 217361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 217461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 217561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 217661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint eapol_sm_failed(struct eapol_sm *sm) 217761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 217861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm == NULL) 217961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 218061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return !sm->eapSuccess && sm->eapFail; 218161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 21824ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 21834ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 2184ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#ifdef CONFIG_EAP_PROXY 2185d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidtint eapol_sm_get_eap_proxy_imsi(void *ctx, int sim_num, char *imsi, size_t *len) 21864ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 2187d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt struct eapol_sm *sm = ctx; 2188d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 21894ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (sm->eap_proxy == NULL) 21904ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return -1; 2191d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return eap_proxy_get_imsi(sm->eap_proxy, sim_num, imsi, len); 21924ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 2193ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#endif /* CONFIG_EAP_PROXY */ 21946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid eapol_sm_erp_flush(struct eapol_sm *sm) 21976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 21986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sm) 21996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_peer_erp_free_keys(sm->eap); 22006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 22019839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt 22029839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt 22039839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstruct wpabuf * eapol_sm_build_erp_reauth_start(struct eapol_sm *sm) 22049839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{ 22059839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_ERP 22069839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt if (!sm) 22079839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt return NULL; 22089839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt return eap_peer_build_erp_reauth_start(sm->eap, 0); 22099839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#else /* CONFIG_ERP */ 22109839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt return NULL; 22119839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_ERP */ 22129839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt} 22139839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt 22149839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt 22159839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtvoid eapol_sm_process_erp_finish(struct eapol_sm *sm, const u8 *buf, 22169839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt size_t len) 22179839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{ 22189839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_ERP 22199839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt if (!sm) 22209839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt return; 22219839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt eap_peer_finish(sm->eap, (const struct eap_hdr *) buf, len); 22229839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_ERP */ 22239839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt} 2224d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2225d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2226d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidtint eapol_sm_update_erp_next_seq_num(struct eapol_sm *sm, u16 next_seq_num) 2227d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt{ 2228d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#ifdef CONFIG_ERP 2229d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (!sm) 2230d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2231d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return eap_peer_update_erp_next_seq_num(sm->eap, next_seq_num); 2232d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#else /* CONFIG_ERP */ 2233d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2234d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* CONFIG_ERP */ 2235d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt} 2236d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2237d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2238d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidtint eapol_sm_get_erp_info(struct eapol_sm *sm, struct eap_peer_config *config, 2239d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt const u8 **username, size_t *username_len, 2240d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt const u8 **realm, size_t *realm_len, 2241d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt u16 *erp_next_seq_num, const u8 **rrk, 2242d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt size_t *rrk_len) 2243d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt{ 2244d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#ifdef CONFIG_ERP 2245d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (!sm) 2246d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2247d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return eap_peer_get_erp_info(sm->eap, config, username, username_len, 2248d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt realm, realm_len, erp_next_seq_num, rrk, 2249d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt rrk_len); 2250d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#else /* CONFIG_ERP */ 2251d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2252d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* CONFIG_ERP */ 2253d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt} 2254