diff options
Diffstat (limited to 'src/eap_server/eap_server.c')
-rw-r--r-- | src/eap_server/eap_server.c | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c index fdc26f9343fb..15f7e22846ec 100644 --- a/src/eap_server/eap_server.c +++ b/src/eap_server/eap_server.c @@ -2,14 +2,8 @@ * hostapd / EAP Full Authenticator state machine (RFC 4137) * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. * * This state machine is based on the full authenticator state machine defined * in RFC 4137. However, to support backend authentication in RADIUS @@ -136,6 +130,14 @@ SM_STATE(EAP, INITIALIZE) { SM_ENTRY(EAP, INITIALIZE); + if (sm->eap_if.eapRestart && !sm->eap_server && sm->identity) { + /* + * Need to allow internal Identity method to be used instead + * of passthrough at the beginning of reauthentication. + */ + eap_server_clear_identity(sm); + } + sm->currentId = -1; sm->eap_if.eapSuccess = FALSE; sm->eap_if.eapFail = FALSE; @@ -273,6 +275,11 @@ SM_STATE(EAP, INTEGRITY_CHECK) { SM_ENTRY(EAP, INTEGRITY_CHECK); + if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) { + sm->ignore = TRUE; + return; + } + if (sm->m->check) { sm->ignore = sm->m->check(sm, sm->eap_method_priv, sm->eap_if.eapRespData); @@ -307,6 +314,9 @@ SM_STATE(EAP, METHOD_RESPONSE) { SM_ENTRY(EAP, METHOD_RESPONSE); + if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) + return; + sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData); if (sm->m->isDone(sm, sm->eap_method_priv)) { eap_sm_Policy_update(sm, NULL, 0); @@ -378,6 +388,9 @@ SM_STATE(EAP, NAK) } sm->m = NULL; + if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) + return; + nak = wpabuf_head(sm->eap_if.eapRespData); if (nak && wpabuf_len(sm->eap_if.eapRespData) > sizeof(*nak)) { len = be_to_host16(nak->length); @@ -1028,9 +1041,12 @@ void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len) not_found: /* not found - remove from the list */ - os_memmove(&sm->user->methods[i], &sm->user->methods[i + 1], - (EAP_MAX_METHODS - i - 1) * - sizeof(sm->user->methods[0])); + if (i + 1 < EAP_MAX_METHODS) { + os_memmove(&sm->user->methods[i], + &sm->user->methods[i + 1], + (EAP_MAX_METHODS - i - 1) * + sizeof(sm->user->methods[0])); + } sm->user->methods[EAP_MAX_METHODS - 1].vendor = EAP_VENDOR_IETF; sm->user->methods[EAP_MAX_METHODS - 1].method = EAP_TYPE_NONE; @@ -1255,8 +1271,13 @@ struct eap_sm * eap_server_sm_init(void *eapol_ctx, sm->wps = conf->wps; if (conf->assoc_wps_ie) sm->assoc_wps_ie = wpabuf_dup(conf->assoc_wps_ie); + if (conf->assoc_p2p_ie) + sm->assoc_p2p_ie = wpabuf_dup(conf->assoc_p2p_ie); if (conf->peer_addr) os_memcpy(sm->peer_addr, conf->peer_addr, ETH_ALEN); + sm->fragment_size = conf->fragment_size; + sm->pwd_group = conf->pwd_group; + sm->pbc_in_m1 = conf->pbc_in_m1; wpa_printf(MSG_DEBUG, "EAP: Server state machine created"); @@ -1291,6 +1312,7 @@ void eap_server_sm_deinit(struct eap_sm *sm) os_free(sm->eap_if.aaaEapKeyData); eap_user_free(sm->user); wpabuf_free(sm->assoc_wps_ie); + wpabuf_free(sm->assoc_p2p_ie); os_free(sm); } @@ -1362,3 +1384,18 @@ struct eap_eapol_interface * eap_get_interface(struct eap_sm *sm) { return &sm->eap_if; } + + +/** + * eap_server_clear_identity - Clear EAP identity information + * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() + * + * This function can be used to clear the EAP identity information in the EAP + * server context. This allows the EAP/Identity method to be used again after + * EAPOL-Start or EAPOL-Logoff. + */ +void eap_server_clear_identity(struct eap_sm *sm) +{ + os_free(sm->identity); + sm->identity = NULL; +} |