Parcourir la source

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.
Jouni Malinen il y a 16 ans
Parent
commit
a8d05fca5f
5 fichiers modifiés avec 19 ajouts et 2 suppressions
  1. 2 1
      hostapd/hostapd.c
  2. 3 1
      hostapd/ieee802_11.c
  3. 1 0
      hostapd/ieee802_1x.c
  4. 12 0
      hostapd/wpa.c
  5. 1 0
      hostapd/wpa.h

+ 2 - 1
hostapd/hostapd.c

@@ -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);

+ 3 - 1
hostapd/ieee802_11.c

@@ -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;

+ 1 - 0
hostapd/ieee802_1x.c

@@ -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

+ 12 - 0
hostapd/wpa.c

@@ -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);

+ 1 - 0
hostapd/wpa.h

@@ -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,