Disable AP PIN on all interfaces controlled by the same process
[libeap.git] / wpa_supplicant / sme.c
index f04295a..985c900 100644 (file)
@@ -26,6 +26,7 @@
 #include "driver_i.h"
 #include "wpas_glue.h"
 #include "wps_supplicant.h"
+#include "p2p_supplicant.h"
 #include "notify.h"
 #include "blacklist.h"
 #include "bss.h"
@@ -160,10 +161,10 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
        ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
        if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
                md = ie + 2;
-       wpa_sm_set_ft_params(wpa_s->wpa, md, NULL, 0, NULL);
+       wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
        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 |
@@ -178,12 +179,13 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
                        mdie = (struct rsn_mdie *) pos;
                        os_memcpy(mdie->mobility_domain, md,
                                  MOBILITY_DOMAIN_ID_LEN);
-                       mdie->ft_capab = 0;
+                       mdie->ft_capab = md[MOBILITY_DOMAIN_ID_LEN];
                        wpa_s->sme.assoc_req_ie_len += 5;
                }
 
                if (wpa_s->sme.ft_used &&
-                   os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0) {
+                   os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 &&
+                   wpa_sm_has_ptk(wpa_s->wpa)) {
                        wpa_printf(MSG_DEBUG, "SME: Trying to use FT "
                                   "over-the-air");
                        params.auth_alg = WPA_AUTH_ALG_FT;
@@ -208,6 +210,22 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_IEEE80211W */
 
+#ifdef CONFIG_P2P
+       if (wpa_s->global->p2p) {
+               u8 *pos;
+               size_t len;
+               int res;
+               int p2p_group;
+               p2p_group = wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE;
+               pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
+               len = sizeof(wpa_s->sme.assoc_req_ie) -
+                       wpa_s->sme.assoc_req_ie_len;
+               res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len, p2p_group);
+               if (res >= 0)
+                       wpa_s->sme.assoc_req_ie_len += res;
+       }
+#endif /* CONFIG_P2P */
+
        wpa_supplicant_cancel_scan(wpa_s);
 
        wpa_msg(wpa_s, MSG_INFO, "Trying to authenticate with " MACSTR
@@ -227,6 +245,7 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
        if (wpa_drv_authenticate(wpa_s, &params) < 0) {
                wpa_msg(wpa_s, MSG_INFO, "Authentication request to the "
                        "driver failed");
+               wpa_supplicant_req_scan(wpa_s, 1, 0);
                return;
        }
 
@@ -272,7 +291,33 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
        if (data->auth.status_code != WLAN_STATUS_SUCCESS) {
                wpa_printf(MSG_DEBUG, "SME: Authentication failed (status "
                           "code %d)", data->auth.status_code);
-               return;
+
+               if (data->auth.status_code !=
+                   WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG ||
+                   wpa_s->sme.auth_alg == data->auth.auth_type ||
+                   wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP)
+                       return;
+
+               switch (data->auth.auth_type) {
+               case WLAN_AUTH_OPEN:
+                       wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED;
+
+                       wpa_printf(MSG_DEBUG, "SME: Trying SHARED auth");
+                       wpa_supplicant_associate(wpa_s, wpa_s->current_bss,
+                                                wpa_s->current_ssid);
+                       return;
+
+               case WLAN_AUTH_SHARED_KEY:
+                       wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP;
+
+                       wpa_printf(MSG_DEBUG, "SME: Trying LEAP auth");
+                       wpa_supplicant_associate(wpa_s, wpa_s->current_bss,
+                                                wpa_s->current_ssid);
+                       return;
+
+               default:
+                       return;
+               }
        }
 
 #ifdef CONFIG_IEEE80211R
@@ -323,7 +368,8 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
 
        wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
 
-       if (ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0)
+       if (params.wpa_ie == NULL ||
+           ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0)
            < 0) {
                wpa_printf(MSG_DEBUG, "SME: Could not parse own IEs?!");
                os_memset(&elems, 0, sizeof(elems));
@@ -336,6 +382,14 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
                                        elems.wpa_ie_len + 2);
        else
                wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
+       if (elems.p2p &&
+           (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
+               params.p2p = 1;
+
+       if (wpa_s->parent->set_sta_uapsd)
+               params.uapsd = wpa_s->parent->sta_uapsd;
+       else
+               params.uapsd = -1;
 
        if (wpa_drv_associate(wpa_s, &params) < 0) {
                wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
@@ -445,7 +499,7 @@ void sme_event_disassoc(struct wpa_supplicant *wpa_s,
                        union wpa_event_data *data)
 {
        wpa_printf(MSG_DEBUG, "SME: Disassociation event received");
-       if (!is_zero_ether_addr(wpa_s->bssid) &&
+       if (wpa_s->sme.prev_bssid_set &&
            !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)) {
                /*
                 * cfg80211/mac80211 can get into somewhat confused state if
@@ -455,7 +509,7 @@ void sme_event_disassoc(struct wpa_supplicant *wpa_s,
                 */
                wpa_printf(MSG_DEBUG, "SME: Deauthenticate to clear driver "
                           "state");
-               wpa_drv_deauthenticate(wpa_s, wpa_s->bssid,
+               wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid,
                                       WLAN_REASON_DEAUTH_LEAVING);
        }
 }