Clear various flags on re-association to allow key_mgmt changes
authorJouni Malinen <j@w1.fi>
Sun, 30 Nov 2008 15:22:51 +0000 (17:22 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 30 Nov 2008 15:22:51 +0000 (17:22 +0200)
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.

hostapd/hostapd.c
hostapd/ieee802_11.c
hostapd/ieee802_1x.c
hostapd/wpa.c
hostapd/wpa.h

index 6efe13f..225ad3a 100644 (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 */
        ieee802_1x_new_station(hapd, sta);
        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);
        } else
                wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
index eac43cf..7a233a2 100644 (file)
@@ -833,6 +833,7 @@ static void handle_assoc(struct hostapd_data *hapd,
                wpa_ie_len = 0;
        }
 #ifdef CONFIG_WPS
+       sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
        if (hapd->conf->wps_state && wpa_ie == NULL) {
                if (elems.wps_ie) {
                        wpa_printf(MSG_DEBUG, "STA included WPS IE in "
@@ -930,7 +931,8 @@ static void handle_assoc(struct hostapd_data *hapd,
                                goto fail;
                }
 #endif /* CONFIG_IEEE80211R */
-       }
+       } else
+               wpa_auth_sta_no_wpa(sta->wpa_sm);
 
        if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
                sta->flags |= WLAN_STA_NONERP;
index 5d3cbfb..d0d8e09 100644 (file)
@@ -848,6 +848,7 @@ void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
        }
 
 #ifdef CONFIG_WPS
+       sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START;
        if (!hapd->conf->ieee802_1x && !(sta->flags & WLAN_STA_WPS)) {
                /*
                 * Delay EAPOL frame transmission until a possible WPS
index b1f35ad..946552c 100644 (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)
 {
        os_free(sm->last_rx_eapol_key);
index 153106e..e347923 100644 (file)
@@ -229,6 +229,7 @@ struct wpa_state_machine *
 wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr);
 void wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,
                             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_receive(struct wpa_authenticator *wpa_auth,
                 struct wpa_state_machine *sm,