📄 eapol_sm.c
字号:
sm->conf.fast_reauth = conf->fast_reauth; if (sm->eap) { eap_set_fast_reauth(sm->eap, conf->fast_reauth); eap_set_workaround(sm->eap, conf->workaround); eap_set_force_disabled(sm->eap, conf->eap_disabled); }}/** * eapol_sm_get_key - Get master session key (MSK) from EAP * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * @key: Pointer for key buffer * @len: Number of bytes to copy to key * Returns: 0 on success (len of key available), maximum available key len * (>0) if key is available but it is shorter than len, or -1 on failure. * * Fetch EAP keying material (MSK, eapKeyData) from EAP state machine. The key * is available only after a successful authentication. */int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len){ const u8 *eap_key; size_t eap_len; if (sm == NULL || !eap_key_available(sm->eap)) return -1; eap_key = eap_get_eapKeyData(sm->eap, &eap_len); if (eap_key == NULL) return -1; if (len > eap_len) return eap_len; memcpy(key, eap_key, len); return 0;}/** * eapol_sm_notify_logoff - Notification of logon/logoff commands * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * @logoff: Whether command was logoff * * Notify EAPOL state machines that user requested logon/logoff. */void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff){ if (sm) { sm->userLogoff = logoff; eapol_sm_step(sm); }}/** * eapol_sm_notify_pmkid_attempt - Notification of successful PMKSA caching * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * * Notify EAPOL state machines that PMKSA caching was successful. This is used * to move EAPOL and EAP state machines into authenticated/successful state. */void eapol_sm_notify_cached(struct eapol_sm *sm){ if (sm == NULL) return; sm->SUPP_PAE_state = SUPP_PAE_AUTHENTICATED; sm->suppPortStatus = Authorized; eap_notify_success(sm->eap);}/** * eapol_sm_notify_pmkid_attempt - Notification of PMKSA caching * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * @attempt: Whether PMKSA caching is tried * * Notify EAPOL state machines whether PMKSA caching is used. */void eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm, int attempt){ if (sm == NULL) return; if (attempt) { wpa_printf(MSG_DEBUG, "RSN: Trying to use cached PMKSA"); sm->cached_pmk = TRUE; } else { wpa_printf(MSG_DEBUG, "RSN: Do not try to use cached PMKSA"); sm->cached_pmk = FALSE; }}static void eapol_sm_abort_cached(struct eapol_sm *sm){ wpa_printf(MSG_DEBUG, "RSN: Authenticator did not accept PMKID, " "doing full EAP authentication"); if (sm == NULL) return; sm->cached_pmk = FALSE; sm->SUPP_PAE_state = SUPP_PAE_CONNECTING; sm->suppPortStatus = Unauthorized; /* Make sure we do not start sending EAPOL-Start frames first, but * instead move to RESTART state to start EAPOL authentication. */ sm->startWhen = 3; if (sm->ctx->aborted_cached) sm->ctx->aborted_cached(sm->ctx->ctx);}/** * eapol_sm_register_scard_ctx - Notification of smart card context * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * @ctx: Context data for smart card operations * * Notify EAPOL state machines of context data for smart card operations. This * context data will be used as a parameter for scard_*() functions. */void eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx){ if (sm) { sm->ctx->scard_ctx = ctx; eap_register_scard_ctx(sm->eap, ctx); }}/** * eapol_sm_notify_portControl - Notification of portControl changes * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * @portControl: New value for portControl variable * * Notify EAPOL state machines that portControl variable has changed. */void eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl){ if (sm == NULL) return; wpa_printf(MSG_DEBUG, "EAPOL: External notification - " "portControl=%s", eapol_port_control(portControl)); sm->portControl = portControl; eapol_sm_step(sm);}/** * eapol_sm_notify_ctrl_attached - Notification of attached monitor * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * * Notify EAPOL state machines that a monitor was attached to the control * interface to trigger re-sending of pending requests for user input. */void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm){ if (sm == NULL) return; eap_sm_notify_ctrl_attached(sm->eap);}/** * eapol_sm_notify_ctrl_response - Notification of received user input * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * * Notify EAPOL state machines that a control response, i.e., user * input, was received in order to trigger retrying of a pending EAP request. */void eapol_sm_notify_ctrl_response(struct eapol_sm *sm){ if (sm == NULL) return; if (sm->eapReqData && !sm->eapReq) { wpa_printf(MSG_DEBUG, "EAPOL: received control response (user " "input) notification - retrying pending EAP " "Request"); sm->eapolEap = TRUE; sm->eapReq = TRUE; eapol_sm_step(sm); }}/** * eapol_sm_request_reauth - Request reauthentication * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * * This function can be used to request EAPOL reauthentication, e.g., when the * current PMKSA entry is nearing expiration. */void eapol_sm_request_reauth(struct eapol_sm *sm){ if (sm == NULL || sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED) return; eapol_sm_txStart(sm);}/** * eapol_sm_notify_lower_layer_success - Notification of lower layer success * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * * Notify EAPOL (and EAP) state machines that a lower layer has detected a * successful authentication. This is used to recover from dropped EAP-Success * messages. */void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm){ if (sm == NULL) return; eap_notify_lower_layer_success(sm->eap);}/** * eapol_sm_invalidate_cached_session - Mark cached EAP session data invalid * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() */void eapol_sm_invalidate_cached_session(struct eapol_sm *sm){ if (sm) eap_invalidate_cached_session(sm->eap);}static struct wpa_ssid * eapol_sm_get_config(void *ctx){ struct eapol_sm *sm = ctx; return sm ? sm->config : NULL;}static u8 * eapol_sm_get_eapReqData(void *ctx, size_t *len){ struct eapol_sm *sm = ctx; if (sm == NULL || sm->eapReqData == NULL) { *len = 0; return NULL; } *len = sm->eapReqDataLen; return sm->eapReqData;}static Boolean eapol_sm_get_bool(void *ctx, enum eapol_bool_var variable){ struct eapol_sm *sm = ctx; if (sm == NULL) return FALSE; switch (variable) { case EAPOL_eapSuccess: return sm->eapSuccess; case EAPOL_eapRestart: return sm->eapRestart; case EAPOL_eapFail: return sm->eapFail; case EAPOL_eapResp: return sm->eapResp; case EAPOL_eapNoResp: return sm->eapNoResp; case EAPOL_eapReq: return sm->eapReq; case EAPOL_portEnabled: return sm->portEnabled; case EAPOL_altAccept: return sm->altAccept; case EAPOL_altReject: return sm->altReject; } return FALSE;}static void eapol_sm_set_bool(void *ctx, enum eapol_bool_var variable, Boolean value){ struct eapol_sm *sm = ctx; if (sm == NULL) return; switch (variable) { case EAPOL_eapSuccess: sm->eapSuccess = value; break; case EAPOL_eapRestart: sm->eapRestart = value; break; case EAPOL_eapFail: sm->eapFail = value; break; case EAPOL_eapResp: sm->eapResp = value; break; case EAPOL_eapNoResp: sm->eapNoResp = value; break; case EAPOL_eapReq: sm->eapReq = value; break; case EAPOL_portEnabled: sm->portEnabled = value; break; case EAPOL_altAccept: sm->altAccept = value; break; case EAPOL_altReject: sm->altReject = value; break; }}static unsigned int eapol_sm_get_int(void *ctx, enum eapol_int_var variable){ struct eapol_sm *sm = ctx; if (sm == NULL) return 0; switch (variable) { case EAPOL_idleWhile: return sm->idleWhile; } return 0;}static void eapol_sm_set_int(void *ctx, enum eapol_int_var variable, unsigned int value){ struct eapol_sm *sm = ctx; if (sm == NULL) return; switch (variable) { case EAPOL_idleWhile: sm->idleWhile = value; break; }}static void eapol_sm_set_config_blob(void *ctx, struct wpa_config_blob *blob){ struct eapol_sm *sm = ctx; if (sm && sm->ctx && sm->ctx->set_config_blob) sm->ctx->set_config_blob(sm->ctx->ctx, blob);}static const struct wpa_config_blob *eapol_sm_get_config_blob(void *ctx, const char *name){ struct eapol_sm *sm = ctx; if (sm && sm->ctx && sm->ctx->get_config_blob) return sm->ctx->get_config_blob(sm->ctx->ctx, name); else return NULL;}static struct eapol_callbacks eapol_cb ={ .get_config = eapol_sm_get_config, .get_bool = eapol_sm_get_bool, .set_bool = eapol_sm_set_bool, .get_int = eapol_sm_get_int, .set_int = eapol_sm_set_int, .get_eapReqData = eapol_sm_get_eapReqData, .set_config_blob = eapol_sm_set_config_blob, .get_config_blob = eapol_sm_get_config_blob,};/** * eapol_sm_init - Initialize EAPOL state machine * @ctx: Pointer to EAPOL context data; this needs to be an allocated buffer * and EAPOL state machine will free it in eapol_sm_deinit() * Returns: Pointer to the allocated EAPOL state machine or %NULL on failure * * Allocate and initialize an EAPOL state machine. */struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx){ struct eapol_sm *sm; struct eap_config conf; sm = malloc(sizeof(*sm)); if (sm == NULL) return NULL; memset(sm, 0, sizeof(*sm)); sm->ctx = ctx; sm->portControl = Auto; /* Supplicant PAE state machine */ sm->heldPeriod = 60; sm->startPeriod = 30; sm->maxStart = 3; /* Supplicant Backend state machine */ sm->authPeriod = 30; memset(&conf, 0, sizeof(conf)); conf.opensc_engine_path = ctx->opensc_engine_path; conf.pkcs11_engine_path = ctx->pkcs11_engine_path; conf.pkcs11_module_path = ctx->pkcs11_module_path; sm->eap = eap_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf); if (sm->eap == NULL) { free(sm); return NULL; } /* Initialize EAPOL state machines */ sm->initialize = TRUE; eapol_sm_step(sm); sm->initialize = FALSE; eapol_sm_step(sm); eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm); return sm;}/** * eapol_sm_deinit - Deinitialize EAPOL state machine * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() * * Deinitialize and free EAPOL state machine. */void eapol_sm_deinit(struct eapol_sm *sm){ if (sm == NULL) return; eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm); eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm); eap_sm_deinit(sm->eap); free(sm->last_rx_key); free(sm->eapReqData); free(sm->ctx); free(sm);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -