Clear various flags on re-association to allow key_mgmt changes

If a STA reassociates and changes key_mgmt (e.g., from WPA-PSK to WPS),
hostapd needs to reset some of the existing STA and WPA state machine
variables to allow correct processing for the new association.
This commit is contained in:
Jouni Malinen 2008-11-30 17:22:51 +02:00
parent 0a40ec6a90
commit a8d05fca5f
5 changed files with 19 additions and 2 deletions

View file

@ -254,7 +254,8 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
/* Start IEEE 802.1X authentication process for new stations */ /* Start IEEE 802.1X authentication process for new stations */
ieee802_1x_new_station(hapd, sta); ieee802_1x_new_station(hapd, sta);
if (reassoc) { if (reassoc) {
if (sta->auth_alg != WLAN_AUTH_FT) if (sta->auth_alg != WLAN_AUTH_FT &&
!(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH); wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
} else } else
wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);

View file

@ -833,6 +833,7 @@ static void handle_assoc(struct hostapd_data *hapd,
wpa_ie_len = 0; wpa_ie_len = 0;
} }
#ifdef CONFIG_WPS #ifdef CONFIG_WPS
sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
if (hapd->conf->wps_state && wpa_ie == NULL) { if (hapd->conf->wps_state && wpa_ie == NULL) {
if (elems.wps_ie) { if (elems.wps_ie) {
wpa_printf(MSG_DEBUG, "STA included WPS IE in " wpa_printf(MSG_DEBUG, "STA included WPS IE in "
@ -930,7 +931,8 @@ static void handle_assoc(struct hostapd_data *hapd,
goto fail; goto fail;
} }
#endif /* CONFIG_IEEE80211R */ #endif /* CONFIG_IEEE80211R */
} } else
wpa_auth_sta_no_wpa(sta->wpa_sm);
if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
sta->flags |= WLAN_STA_NONERP; sta->flags |= WLAN_STA_NONERP;

View file

@ -848,6 +848,7 @@ void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
} }
#ifdef CONFIG_WPS #ifdef CONFIG_WPS
sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START;
if (!hapd->conf->ieee802_1x && !(sta->flags & WLAN_STA_WPS)) { if (!hapd->conf->ieee802_1x && !(sta->flags & WLAN_STA_WPS)) {
/* /*
* Delay EAPOL frame transmission until a possible WPS * Delay EAPOL frame transmission until a possible WPS

View file

@ -516,6 +516,18 @@ void wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,
} }
void wpa_auth_sta_no_wpa(struct wpa_state_machine *sm)
{
/* WPA/RSN was not used - clear WPA state. This is needed if the STA
* reassociates back to the same AP while the previous entry for the
* STA has not yet been removed. */
if (sm == NULL)
return;
sm->wpa_key_mgmt = 0;
}
static void wpa_free_sta_sm(struct wpa_state_machine *sm) static void wpa_free_sta_sm(struct wpa_state_machine *sm)
{ {
os_free(sm->last_rx_eapol_key); os_free(sm->last_rx_eapol_key);

View file

@ -229,6 +229,7 @@ struct wpa_state_machine *
wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr); wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr);
void wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth, void wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm); struct wpa_state_machine *sm);
void wpa_auth_sta_no_wpa(struct wpa_state_machine *sm);
void wpa_auth_sta_deinit(struct wpa_state_machine *sm); void wpa_auth_sta_deinit(struct wpa_state_machine *sm);
void wpa_receive(struct wpa_authenticator *wpa_auth, void wpa_receive(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm, struct wpa_state_machine *sm,