FT: Add a workaround to set PTK after reassociation
authorJouni Malinen <j@w1.fi>
Sat, 13 Mar 2010 15:15:38 +0000 (17:15 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 13 Mar 2010 15:15:38 +0000 (17:15 +0200)
If the PTK configuration prior to association fails, allow reassociation
attempt to continue and configure PTK after association. This is a
workaround for drivers that do not allow PTK to be configured before
association (e.g., current cfg80211/mac80211).

src/rsn_supp/wpa_ft.c
src/rsn_supp/wpa_i.h

index 964977f..556838b 100644 (file)
@@ -629,18 +629,29 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
        }
 
        ret = wpa_ft_install_ptk(sm, bssid);
+       if (ret) {
+               /*
+                * Some drivers do not support key configuration when we are
+                * not associated with the target AP. Work around this by
+                * trying again after the following reassociation gets
+                * completed.
+                */
+               wpa_printf(MSG_DEBUG, "FT: Failed to set PTK prior to "
+                          "association - try again after reassociation");
+               sm->set_ptk_after_assoc = 1;
+       } else
+               sm->set_ptk_after_assoc = 0;
 
-       if (ret == 0) {
-               sm->ft_completed = 1;
-               if (ft_action) {
-                       /* TODO: trigger re-association to the Target AP;
-                        * MLME is now doing this automatically, but it should
-                        * really be done only if we get here successfully. */
-                       os_memcpy(sm->bssid, target_ap, ETH_ALEN);
-               }
+       sm->ft_completed = 1;
+       if (ft_action) {
+               /*
+                * The caller is expected trigger re-association with the
+                * Target AP.
+                */
+               os_memcpy(sm->bssid, target_ap, ETH_ALEN);
        }
 
-       return ret;
+       return 0;
 }
 
 
@@ -896,6 +907,14 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
                return -1;
 #endif /* CONFIG_IEEE80211W */
 
+       if (sm->set_ptk_after_assoc) {
+               wpa_printf(MSG_DEBUG, "FT: Try to set PTK again now that we "
+                          "are associated");
+               if (wpa_ft_install_ptk(sm, src_addr) < 0)
+                       return -1;
+               sm->set_ptk_after_assoc = 0;
+       }
+
        if (parse.ric) {
                wpa_hexdump(MSG_MSGDUMP, "FT: RIC Response",
                            parse.ric, parse.ric_len);
index f1dcfdd..bb774f9 100644 (file)
@@ -106,6 +106,7 @@ struct wpa_sm {
        int ft_completed;
        int over_the_ds_in_progress;
        u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */
+       int set_ptk_after_assoc;
 #endif /* CONFIG_IEEE80211R */
 };