]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Fix group key rekeying when reauth happens during pending group key update
authorJouni Malinen <jouni.malinen@atheros.com>
Tue, 21 Oct 2008 10:54:54 +0000 (13:54 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 21 Oct 2008 10:54:54 +0000 (13:54 +0300)
We need to cancel the group key update for a STA if a reauthentication
request is received while the STA is in pending group key update. When
canceling the update, we will also need to make sure that the PTK Group Key
state machine ends up in the correct state (IDLE) to allow future updates
in case of WPA2.

hostapd/wpa.c
hostapd/wpa_auth_i.h

index bee3ffad4ca8e3bae995f848f275451aa7be90b7..c7bcac82a40a1930f67a7a9e108b9eb3bbee3b51 100644 (file)
@@ -1109,6 +1109,15 @@ void wpa_auth_sm_event(struct wpa_state_machine *sm, wpa_event event)
                break;
        case WPA_REAUTH:
        case WPA_REAUTH_EAPOL:
+               if (sm->GUpdateStationKeys) {
+                       /*
+                        * Reauthentication cancels the pending group key
+                        * update for this STA.
+                        */
+                       sm->group->GKeyDoneStations--;
+                       sm->GUpdateStationKeys = FALSE;
+                       sm->PtkGroupInit = TRUE;
+               }
                sm->ReAuthenticationRequest = TRUE;
                break;
        case WPA_ASSOC_FT:
@@ -1760,9 +1769,10 @@ SM_STATE(WPA_PTK_GROUP, KEYERROR)
 
 SM_STEP(WPA_PTK_GROUP)
 {
-       if (sm->Init)
+       if (sm->Init || sm->PtkGroupInit) {
                SM_ENTER(WPA_PTK_GROUP, IDLE);
-       else switch (sm->wpa_ptk_group_state) {
+               sm->PtkGroupInit = FALSE;
+       } else switch (sm->wpa_ptk_group_state) {
        case WPA_PTK_GROUP_IDLE:
                if (sm->GUpdateStationKeys ||
                    (sm->wpa == WPA_VERSION_WPA && sm->PInitAKeys))
@@ -1844,8 +1854,18 @@ static int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx)
                                "Not in PTKINITDONE; skip Group Key update");
                return 0;
        }
-       sm->group->GKeyDoneStations++;
-       sm->GUpdateStationKeys = TRUE;
+       if (sm->GUpdateStationKeys) {
+               /*
+                * This should not really happen, but just in case, make sure
+                * we do not count the same STA twice in GKeyDoneStations.
+                */
+               wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
+                               "GUpdateStationKeys already set - do not "
+                               "increment GKeyDoneStations");
+       } else {
+               sm->group->GKeyDoneStations++;
+               sm->GUpdateStationKeys = TRUE;
+       }
        wpa_sm_step(sm);
        return 0;
 }
index fd222387b98a49b844c79d9ae1ef87dfda30e2d2..7770d179d2a1ac52f17292d7058c75a6ee036bcd 100644 (file)
@@ -71,6 +71,7 @@ struct wpa_state_machine {
        Boolean PInitAKeys; /* WPA only, not in IEEE 802.11i */
        Boolean PTKRequest; /* not in IEEE 802.11i state machine */
        Boolean has_GTK;
+       Boolean PtkGroupInit; /* init request for PTK Group state machine */
 
        u8 *last_rx_eapol_key; /* starting from IEEE 802.1X header */
        size_t last_rx_eapol_key_len;