]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FT: Copy FT Capability and Policy to MDIE from target AP
authorJouni Malinen <jouni.malinen@atheros.com>
Fri, 9 Apr 2010 13:26:20 +0000 (16:26 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 9 Apr 2010 13:26:20 +0000 (16:26 +0300)
This sets the FT Capability and Policy field in the MDIE to the values
received from the target AP (if available). This fixes the MDIE contents
during FT Protocol, but the correct value may not yet be used in initial
mobility domain association.

src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_ft.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant.c

index 905bb4aa95dc86aa9acffdf498760a6fe108c546..f7b1fb72c477bab14b866a1edc2d92b06ca7288a 100644 (file)
@@ -459,7 +459,7 @@ static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
 #ifdef CONFIG_IEEE80211R
        if (wpa_key_mgmt_ft(sm->key_mgmt)) {
                /* Prepare for the next transition */
-               wpa_ft_prepare_auth_request(sm);
+               wpa_ft_prepare_auth_request(sm, NULL);
        }
 #endif /* CONFIG_IEEE80211R */
 }
@@ -1936,7 +1936,7 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
                wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
 
                /* Prepare for the next transition */
-               wpa_ft_prepare_auth_request(sm);
+               wpa_ft_prepare_auth_request(sm, NULL);
 
                clear_ptk = 0;
        }
index 5ff69062d3eb05d109e7ba2248043b8c3c4e47f5..0d4405b5340e98502cafcb374a8656dfc6baac6e 100644 (file)
@@ -281,14 +281,15 @@ static inline int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
 int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *mobility_domain,
                         const u8 *r0kh_id, size_t r0kh_id_len,
                         const u8 *r1kh_id);
-int wpa_ft_prepare_auth_request(struct wpa_sm *sm);
+int wpa_ft_prepare_auth_request(struct wpa_sm *sm, const u8 *mdie);
 int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
                            int ft_action, const u8 *target_ap,
                            const u8 *ric_ies, size_t ric_ies_len);
 int wpa_ft_is_completed(struct wpa_sm *sm);
 int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
                                 size_t ies_len, const u8 *src_addr);
-int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap);
+int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap,
+                        const u8 *mdie);
 
 #else /* CONFIG_IEEE80211R */
 
@@ -299,7 +300,8 @@ wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *mobility_domain,
        return 0;
 }
 
-static inline int wpa_ft_prepare_auth_request(struct wpa_sm *sm)
+static inline int wpa_ft_prepare_auth_request(struct wpa_sm *sm,
+                                             const u8 *mdie)
 {
        return 0;
 }
index eb68e262baa0123cb8f9f689034d1fc85865018d..7c89e9b78bed4a600667981f6fdcf5f2725b6180 100644 (file)
@@ -115,6 +115,7 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *mobility_domain,
  * @target_ap: Target AP address
  * @ric_ies: Optional IE(s), e.g., WMM TSPEC(s), for RIC-Request or %NULL
  * @ric_ies_len: Length of ric_ies buffer in octets
+ * @ap_mdie: Mobility Domain IE from the target AP
  * Returns: Pointer to buffer with IEs or %NULL on failure
  *
  * Caller is responsible for freeing the returned buffer with os_free();
@@ -122,7 +123,8 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *mobility_domain,
 static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
                               const u8 *anonce, const u8 *pmk_name,
                               const u8 *kck, const u8 *target_ap,
-                              const u8 *ric_ies, size_t ric_ies_len)
+                              const u8 *ric_ies, size_t ric_ies_len,
+                              const u8 *ap_mdie)
 {
        size_t buf_len;
        u8 *buf, *pos, *ftie_len, *ftie_pos;
@@ -227,7 +229,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
        pos += sizeof(*mdie);
        os_memcpy(mdie->mobility_domain, sm->mobility_domain,
                  MOBILITY_DOMAIN_ID_LEN);
-       mdie->ft_capab = 0; /* FIX: copy from the target AP's MDIE */
+       mdie->ft_capab = ap_mdie && ap_mdie[1] >= 3 ? ap_mdie[4] : 0;
 
        /* FTIE[SNonce, [R1KH-ID,] R0KH-ID ] */
        ftie_pos = pos;
@@ -497,9 +499,10 @@ static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid)
 /**
  * wpa_ft_prepare_auth_request - Generate over-the-air auth request
  * @sm: Pointer to WPA state machine data from wpa_sm_init()
+ * @mdie: Target AP MDIE
  * Returns: 0 on success, -1 on failure
  */
-int wpa_ft_prepare_auth_request(struct wpa_sm *sm)
+int wpa_ft_prepare_auth_request(struct wpa_sm *sm, const u8 *mdie)
 {
        u8 *ft_ies;
        size_t ft_ies_len;
@@ -511,7 +514,7 @@ int wpa_ft_prepare_auth_request(struct wpa_sm *sm)
        }
 
        ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, NULL, sm->pmk_r0_name,
-                                   NULL, sm->bssid, NULL, 0);
+                                   NULL, sm->bssid, NULL, 0, mdie);
        if (ft_ies) {
                wpa_sm_update_ft_ies(sm, sm->mobility_domain,
                                     ft_ies, ft_ies_len);
@@ -628,7 +631,8 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
 
        ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, ftie->anonce,
                                    sm->pmk_r1_name, sm->ptk.kck, bssid,
-                                   ric_ies, ric_ies_len);
+                                   ric_ies, ric_ies_len,
+                                   parse.mdie ? parse.mdie - 2 : NULL);
        if (ft_ies) {
                wpa_sm_update_ft_ies(sm, sm->mobility_domain,
                                     ft_ies, ft_ies_len);
@@ -936,9 +940,12 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
 /**
  * wpa_ft_start_over_ds - Generate over-the-DS auth request
  * @sm: Pointer to WPA state machine data from wpa_sm_init()
+ * @target_ap: Target AP Address
+ * @mdie: Mobility Domain IE from the target AP
  * Returns: 0 on success, -1 on failure
  */
-int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap)
+int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap,
+                        const u8 *mdie)
 {
        u8 *ft_ies;
        size_t ft_ies_len;
@@ -953,7 +960,7 @@ int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap)
        }
 
        ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, NULL, sm->pmk_r0_name,
-                                   NULL, target_ap, NULL, 0);
+                                   NULL, target_ap, NULL, 0, mdie);
        if (ft_ies) {
                sm->over_the_ds_in_progress = 1;
                os_memcpy(sm->target_ap, target_ap, ETH_ALEN);
index c7d34276281eb6136cf3fad1213c7ffdeae877e0..969cc8a0825888bcdb14f43a3df658181df269c0 100644 (file)
@@ -136,6 +136,8 @@ static int wpa_supplicant_ctrl_iface_ft_ds(
        struct wpa_supplicant *wpa_s, char *addr)
 {
        u8 target_ap[ETH_ALEN];
+       struct wpa_bss *bss;
+       const u8 *mdie;
 
        if (hwaddr_aton(addr, target_ap)) {
                wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
@@ -145,7 +147,13 @@ static int wpa_supplicant_ctrl_iface_ft_ds(
 
        wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
 
-       return wpa_ft_start_over_ds(wpa_s->wpa, target_ap);
+       bss = wpa_bss_get_bssid(wpa_s, target_ap);
+       if (bss)
+               mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
+       else
+               mdie = NULL;
+
+       return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie);
 }
 #endif /* CONFIG_IEEE80211R */
 
index f04295a71569f2fe8de0ac96827f281a15c42fb5..814837549931c8483beff44c5cd5fe8bc6eb24cd 100644 (file)
@@ -163,7 +163,7 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
        wpa_sm_set_ft_params(wpa_s->wpa, md, NULL, 0, NULL);
        if (md) {
                /* Prepare for the next transition */
-               wpa_ft_prepare_auth_request(wpa_s->wpa);
+               wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
        }
 
        if (md && ssid->key_mgmt & (WPA_KEY_MGMT_FT_PSK |
index 6748735c02ef9ee0fa7bdf6ae1ea71898638cc1d..c5387bfd6985e19ae6d991c79c4ee58e58a41b59 100644 (file)
@@ -1040,7 +1040,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
                wpa_sm_set_ft_params(wpa_s->wpa, md, NULL, 0, NULL);
                if (md) {
                        /* Prepare for the next transition */
-                       wpa_ft_prepare_auth_request(wpa_s->wpa);
+                       wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
                }
 #endif /* CONFIG_IEEE80211R */
 #ifdef CONFIG_WPS