Explorar el Código

Merge branch 'bugfix/wps_fixes_v4.1' into 'release/v4.1'

wpa_supplicant: Add WPS Fixes (backport V4.1)

See merge request espressif/esp-idf!17061
Jiang Jiang Jian hace 4 años
padre
commit
6ebe70287c

+ 118 - 82
components/wpa_supplicant/src/esp_supplicant/esp_wps.c

@@ -1,16 +1,8 @@
-// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+ * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #include <string.h>
 
@@ -84,6 +76,7 @@ void wifi_station_wps_msg_timeout_internal(void);
 void wifi_station_wps_success_internal(void);
 void wifi_wps_scan_internal(void);
 void wifi_station_wps_eapol_start_handle_internal(void);
+void wps_add_discard_ap(u8 *bssid);
 
 struct wps_sm *gWpsSm = NULL;
 static wps_factory_information_t *s_factory_info = NULL;
@@ -304,8 +297,8 @@ static inline int wps_sm_ether_send(struct wps_sm *sm, const u8 *dest, u16 proto
     void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
     struct l2_ethhdr *eth = (struct l2_ethhdr *)buffer;
 
-    memcpy(eth->h_dest, dest, ETH_ALEN);
-    memcpy(eth->h_source, sm->ownaddr, ETH_ALEN);
+    os_memcpy(eth->h_dest, dest, ETH_ALEN);
+    os_memcpy(eth->h_source, sm->ownaddr, ETH_ALEN);
     eth->h_proto = host_to_be16(proto);
 
     wps_sendto_wrapper(buffer, sizeof(struct l2_ethhdr) + data_len);
@@ -335,9 +328,9 @@ u8 *wps_sm_alloc_eapol(struct wps_sm *sm, u8 type,
     hdr->length = host_to_be16(data_len);
 
     if (data) {
-        memcpy(hdr + 1, data, data_len);
+        os_memcpy(hdr + 1, data, data_len);
     } else {
-        memset(hdr + 1, 0, data_len);
+        os_memset(hdr + 1, 0, data_len);
     }
 
     if (data_pos) {
@@ -388,10 +381,10 @@ struct wps_data *wps_init(void)
     data->registrar = 0; /* currently, we force to support enrollee only */
 
     if (data->registrar) {
-        memcpy(data->uuid_r, sm->uuid, WPS_UUID_LEN);
+        os_memcpy(data->uuid_r, sm->uuid, WPS_UUID_LEN);
     } else {
-        memcpy(data->mac_addr_e, sm->dev->mac_addr, ETH_ALEN);
-        memcpy(data->uuid_e, sm->uuid, WPS_UUID_LEN);
+        os_memcpy(data->mac_addr_e, sm->dev->mac_addr, ETH_ALEN);
+        os_memcpy(data->uuid_e, sm->uuid, WPS_UUID_LEN);
     }
 
     if (wps_get_type() == WPS_TYPE_PIN) {
@@ -411,10 +404,10 @@ struct wps_data *wps_init(void)
         do {
             char tmpp[9];
             os_bzero(tmpp, 9);
-            memcpy(tmpp, data->dev_password, 8);
+            os_memcpy(tmpp, data->dev_password, 8);
             wpa_printf(MSG_DEBUG, "WPS PIN [%s]", tmpp);
             wifi_event_sta_wps_er_pin_t evt;
-            memcpy(evt.pin_code, data->dev_password, 8);
+            os_memcpy(evt.pin_code, data->dev_password, 8);
             esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PIN, &evt, sizeof(evt), portMAX_DELAY);
         } while (0);
     } else if (wps_get_type() == WPS_TYPE_PBC) {
@@ -444,7 +437,7 @@ struct wps_data *wps_init(void)
             os_free(data);
             return NULL;
         }
-        memcpy(data->dev_password,
+        os_memcpy(data->dev_password,
                wpabuf_head(cfg->wps->ap_nfc_dev_pw),
                wpabuf_len(cfg->wps->ap_nfc_dev_pw));
         data->dev_password_len = wpabuf_len(cfg->wps->ap_nfc_dev_pw);
@@ -564,6 +557,10 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
     wpa_printf(MSG_DEBUG, "wps parse scan: %s", tmp);
 #endif
 
+    if (!sm->is_wps_scan || !scan->bssid) {
+        return false;
+    }
+
     if (wps_get_type() == WPS_TYPE_DISABLE
             || (wps_get_status() != WPS_STATUS_DISABLE
                 && wps_get_status() != WPS_STATUS_SCANNING)
@@ -571,38 +568,55 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
         return false;
     }
 
+    if (!scan->rsn && !scan->wpa && (scan->capinfo & WIFI_CAPINFO_PRIVACY)) {
+        wpa_printf(MSG_INFO, "WEP not suppported in WPS");
+        return false;
+    }
+
+    if (sm->wps_pin_war) {
+        /* We have selected candidate for this scan */
+        return false;
+    }
+
     esp_wifi_get_mode(&op_mode);
     if ((op_mode == WIFI_MODE_STA || op_mode == WIFI_MODE_APSTA) && scan->wps) {
+        bool ap_found = false;
+        int count;
         struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4);
 
-        if (wps_is_selected_pbc_registrar(buf, scan->bssid)
-                || wps_is_selected_pin_registrar(buf, scan->bssid)) {
-            wpabuf_free(buf);
-
-            if (sm->is_wps_scan == false) {
-                return false;
-            }
-            if (memcmp(sm->config.bssid, scan->bssid, ETH_ALEN) != 0 ) {
-                sm->discover_ssid_cnt++;
-            }
-
-            if (!scan->rsn && !scan->wpa && (scan->capinfo & WIFI_CAPINFO_PRIVACY)) {
-                wpa_printf(MSG_ERROR, "WEP not suppported in WPS");
-
-                return false;
+        if ((wps_get_type() == WPS_TYPE_PBC && wps_is_selected_pbc_registrar(buf)) ||
+            (wps_get_type() == WPS_TYPE_PIN && wps_is_addr_authorized(buf, sm->ownaddr, 1))) {
+            /* Found one AP with selected registrar true */
+            sm->ignore_sel_reg = false;
+            sm->discard_ap_cnt = 0;
+            ap_found = true;
+        }
+        if ((op_mode == WIFI_MODE_STA || op_mode == WIFI_MODE_APSTA) &&
+            wps_get_type() == WPS_TYPE_PIN && sm->ignore_sel_reg) {
+            /* AP is in discard list? */
+            for (count = 0; count < WPS_MAX_DIS_AP_NUM; count++) {
+                if (os_memcmp(sm->dis_ap_list[count].bssid, scan->bssid, ETH_ALEN) == 0) {
+                    wpa_printf(MSG_INFO, "discard ap bssid "MACSTR, MAC2STR(scan->bssid));
+                    return false;
+                }
             }
+            sm->wps_pin_war = true;
+        }
 
+        if (ap_found || sm->wps_pin_war) {
+            wpabuf_free(buf);
             esp_wifi_enable_sta_privacy_internal();
+            os_memset(sm->config.ssid, 0, sizeof(sm->config.ssid));
             strncpy((char *)sm->config.ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]);
-            if (scan->bssid) {
-                memcpy(gWpsSm->bssid, scan->bssid, ETH_ALEN);
-                memcpy(sm->config.bssid, scan->bssid, ETH_ALEN);
+            if (scan->bssid && memcmp(sm->config.bssid, scan->bssid, ETH_ALEN) != 0) {
+                wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR "\n",
+                           MAC2STR(sm->config.bssid), MAC2STR(scan->bssid));
+                sm->discover_ssid_cnt++;
+                os_memcpy(sm->bssid, scan->bssid, ETH_ALEN);
+                os_memcpy(sm->config.bssid, scan->bssid, ETH_ALEN);
                 sm->config.bssid_set = 1;
-            } else {
             }
             wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->config.ssid);
-            sm->scan_cnt = 0;
-
             sm->channel = scan->chan;
 
             return true;
@@ -983,10 +997,10 @@ int wps_finish(void)
         ets_timer_disarm(&sm->wps_msg_timeout_timer);
 
         if (sm->ap_cred_cnt == 1) {
-            memset(config, 0x00, sizeof(wifi_sta_config_t));
-            memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]);
-            memcpy(config->sta.password, sm->key[0], sm->key_len[0]);
-            memcpy(config->sta.bssid, sm->bssid, ETH_ALEN);
+            os_memset(config, 0x00, sizeof(wifi_sta_config_t));
+            os_memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]);
+            os_memcpy(config->sta.password, sm->key[0], sm->key_len[0]);
+            os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN);
             config->sta.bssid_set = 0;
             esp_wifi_set_config(0, config);
 
@@ -998,9 +1012,16 @@ int wps_finish(void)
 
         ret = 0;
     } else {
-        wpa_printf(MSG_ERROR, "wps failed----->");
-
-        ret = wps_stop_process(WPS_FAIL_REASON_NORMAL);
+        wpa_printf(MSG_ERROR, "wps failed-----> wps_pin_war=%d", sm->wps_pin_war);
+        if (sm->wps_pin_war) {
+            sm->discover_ssid_cnt = 0;
+            esp_wifi_disconnect();
+            os_bzero(sm->ssid, sizeof(sm->ssid));
+            os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
+            wps_add_discard_ap(sm->config.bssid);
+        } else {
+            ret = wps_stop_process(WPS_FAIL_REASON_NORMAL);
+        }
     }
 
     return ret;
@@ -1020,11 +1041,12 @@ void wps_add_discard_ap(u8 *bssid)
         sm->discard_ap_cnt++;
     } else {
         for (cnt = 0; cnt < WPS_MAX_DIS_AP_NUM - 2; cnt++) {
-            memcpy(sm->dis_ap_list[cnt].bssid, sm->dis_ap_list[cnt + 1].bssid, 6);
+            os_memcpy(sm->dis_ap_list[cnt].bssid, sm->dis_ap_list[cnt + 1].bssid, 6);
         }
         sm->discard_ap_cnt = WPS_MAX_DIS_AP_NUM;
     }
-    memcpy(sm->dis_ap_list[cnt].bssid, bssid, 6);
+    os_memcpy(sm->dis_ap_list[cnt].bssid, bssid, 6);
+    wpa_printf(MSG_INFO, "Added BSSID:"MACSTR" to discard list cnt=%d" , MAC2STR(bssid), sm->discard_ap_cnt);
 }
 
 int wps_start_msg_timer(void)
@@ -1089,9 +1111,9 @@ int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len)
             os_free(param);
             return ESP_ERR_NO_MEM;
         }
-        memcpy(param->buf, buf, len);
+        os_memcpy(param->buf, buf, len);
         param->len = len;
-        memcpy(param->sa, src_addr, WPS_ADDR_LEN);
+        os_memcpy(param->sa, src_addr, WPS_ADDR_LEN);
 
         wps_rxq_enqueue(param);
         return wps_post(SIG_WPS_RX, 0);
@@ -1241,7 +1263,10 @@ int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len)
         break;
     }
 out:
-    if (ret != 0 || res == WPS_FAILURE) {
+    if (ret != 0 && sm->wps_pin_war) {
+        sm->wps_pin_war = 0;
+        wifi_wps_scan();
+    } else if ((ret != 0 || res == WPS_FAILURE)) {
         wifi_event_sta_wps_fail_reason_t reason_code = WPS_FAIL_REASON_NORMAL;
         wpa_printf(MSG_DEBUG, "wpa rx eapol internal: fail ret=%d", ret);
         wps_set_status(WPS_STATUS_DISABLE);
@@ -1284,19 +1309,19 @@ int wps_set_factory_info(const esp_wps_config_t *config)
     }
 
     if (config->factory_info.manufacturer[0] != 0) {
-        memcpy(s_factory_info->manufacturer, config->factory_info.manufacturer, WPS_MAX_MANUFACTURER_LEN - 1);
+        os_memcpy(s_factory_info->manufacturer, config->factory_info.manufacturer, WPS_MAX_MANUFACTURER_LEN - 1);
     }
 
     if (config->factory_info.model_number[0] != 0) {
-        memcpy(s_factory_info->model_number, config->factory_info.model_number, WPS_MAX_MODEL_NUMBER_LEN - 1);
+        os_memcpy(s_factory_info->model_number, config->factory_info.model_number, WPS_MAX_MODEL_NUMBER_LEN - 1);
     }
 
     if (config->factory_info.model_name[0] != 0) {
-        memcpy(s_factory_info->model_name, config->factory_info.model_name, WPS_MAX_MODEL_NAME_LEN - 1);
+        os_memcpy(s_factory_info->model_name, config->factory_info.model_name, WPS_MAX_MODEL_NAME_LEN - 1);
     }
 
     if (config->factory_info.device_name[0] != 0) {
-        memcpy(s_factory_info->device_name, config->factory_info.device_name, WPS_MAX_DEVICE_NAME_LEN - 1);
+        os_memcpy(s_factory_info->device_name, config->factory_info.device_name, WPS_MAX_DEVICE_NAME_LEN - 1);
     }
 
     wpa_printf(MSG_INFO, "manufacturer: %s, model number: %s, model name: %s, device name: %s", s_factory_info->manufacturer,
@@ -1376,7 +1401,7 @@ int wps_dev_init(void)
             sm->ownaddr[3], sm->ownaddr[4], sm->ownaddr[5]);
 
     uuid_gen_mac_addr(sm->ownaddr, sm->uuid);
-    memcpy(dev->mac_addr, sm->ownaddr, ETH_ALEN);
+    os_memcpy(dev->mac_addr, sm->ownaddr, ETH_ALEN);
 
     return ESP_OK;
 
@@ -1468,7 +1493,6 @@ void
 wifi_station_wps_msg_timeout_internal(void)
 {
     struct wps_sm *sm = gWpsSm;
-
     if (!sm) {
         return;
     }
@@ -1476,11 +1500,22 @@ wifi_station_wps_msg_timeout_internal(void)
     if (sm->wps->state == WPS_FINISHED) {
         wpa_printf(MSG_DEBUG, "wps msg timeout WPS_FINISHED");
         wps_finish();
+        return;
     } else if (sm->wps->state == RECV_M2) {
         wpa_printf(MSG_DEBUG, "wps msg timeout RECV_M2");
         wpa_printf(MSG_DEBUG, "wps recev m2/m2d timeout------>");
+        if (!sm->wps_pin_war) {
+            wps_stop_process(WPS_FAIL_REASON_RECV_M2D);
+        }
+    }
+    if (sm->wps_pin_war) {
+        esp_wifi_disconnect();
         wps_add_discard_ap(sm->config.bssid);
-        wps_stop_process(WPS_FAIL_REASON_RECV_M2D);
+        sm->wps_pin_war = 0;
+        os_bzero(sm->ssid, sizeof(sm->ssid));
+        os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
+        sm->discover_ssid_cnt = 0;
+        wifi_wps_scan();
     }
 }
 
@@ -1563,19 +1598,20 @@ wifi_station_wps_init(void)
     }
 
     sm = gWpsSm;
-    memset(sm, 0x00, sizeof(struct wps_sm));
+    os_memset(sm, 0x00, sizeof(struct wps_sm));
 
     esp_wifi_get_macaddr_internal(WIFI_IF_STA, mac);
-    memcpy(sm->ownaddr, mac, ETH_ALEN);
+    os_memcpy(sm->ownaddr, mac, ETH_ALEN);
 
     sm->discover_ssid_cnt = 0;
     sm->ignore_sel_reg = false;
     sm->discard_ap_cnt = 0;
-    memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t));
-    memset(&sm->config, 0x00, sizeof(wifi_sta_config_t));
+    os_memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t));
+    os_memset(&sm->config, 0x00, sizeof(wifi_sta_config_t));
     sm->eapol_version = 0x1;
     sm->identity_len = 29;
-    memcpy(sm->identity, WPS_EAP_EXT_VENDOR_TYPE, sm->identity_len);
+    os_memcpy(sm->identity, WPS_EAP_EXT_VENDOR_TYPE, sm->identity_len);
+    sm->wps_pin_war = false;
 
     sm->is_wps_scan = false;
 
@@ -1734,14 +1770,14 @@ wps_ssid_save(u8 *ssid, u8 ssid_len, u8 idx)
         return ESP_FAIL;
     }
 
-    memset(gWpsSm->ssid[idx], 0x00, sizeof(gWpsSm->ssid[idx]));
-    memcpy(gWpsSm->ssid[idx], ssid, ssid_len);
+    os_memset(gWpsSm->ssid[idx], 0x00, sizeof(gWpsSm->ssid[idx]));
+    os_memcpy(gWpsSm->ssid[idx], ssid, ssid_len);
     gWpsSm->ssid_len[idx] = ssid_len;
     gWpsSm->ap_cred_cnt++;
 
     tmpssid = (u8 *)os_zalloc(ssid_len + 1);
     if (tmpssid) {
-        memcpy(tmpssid, ssid, ssid_len);
+        os_memcpy(tmpssid, ssid, ssid_len);
         wpa_printf(MSG_DEBUG, "WPS: key[%s]", tmpssid);
         os_free(tmpssid);
     }
@@ -1757,13 +1793,13 @@ wps_key_save(char *key, u8 key_len, u8 idx)
         return ESP_FAIL;
     }
 
-    memset(gWpsSm->key[idx], 0x00, sizeof(gWpsSm->key[idx]));
-    memcpy(gWpsSm->key[idx], key, key_len);
+    os_memset(gWpsSm->key[idx], 0x00, sizeof(gWpsSm->key[idx]));
+    os_memcpy(gWpsSm->key[idx], key, key_len);
     gWpsSm->key_len[idx] = key_len;
 
     tmpkey = (u8 *)os_zalloc(key_len + 1);
     if (tmpkey) {
-        memcpy(tmpkey, key, key_len);
+        os_memcpy(tmpkey, key, key_len);
         wpa_printf(MSG_DEBUG, "WPS: key[%s], idx - %d", tmpkey, idx);
         os_free(tmpkey);
     }
@@ -1776,6 +1812,7 @@ wifi_wps_scan_done(void *arg, STATUS status)
     struct wps_sm *sm = gWpsSm;
     wifi_config_t wifi_config;
 
+    wpa_printf(MSG_INFO, "WPS: scan done");
     if (wps_get_type() == WPS_TYPE_DISABLE) {
         return;
     }
@@ -1801,14 +1838,17 @@ wifi_wps_scan_done(void *arg, STATUS status)
     if (wps_get_status() == WPS_STATUS_PENDING) {
         esp_wifi_disconnect();
 
-        memcpy(&wifi_config.sta, &sm->config, sizeof(wifi_sta_config_t));
+        os_memcpy(&wifi_config.sta, &sm->config, sizeof(wifi_sta_config_t));
         esp_wifi_set_config(0, &wifi_config);
 
         wpa_printf(MSG_DEBUG, "WPS: neg start");
         esp_wifi_connect();
+        ets_timer_disarm(&sm->wps_msg_timeout_timer);
+        ets_timer_arm(&sm->wps_msg_timeout_timer, 2000, 0);
     } else if (wps_get_status() == WPS_STATUS_SCANNING) {
-        if (sm->scan_cnt < WPS_IGNORE_SEL_REG_MAX_CNT) {
+        if (wps_get_type() == WPS_TYPE_PIN && sm->scan_cnt > WPS_IGNORE_SEL_REG_MAX_CNT) {
             sm->ignore_sel_reg = true;
+            sm->wps_pin_war = false;
         }
         ets_timer_arm(&sm->wps_scan_timer, 100, 0);
     } else {
@@ -1869,6 +1909,8 @@ int wifi_station_wps_start(void)
     default:
         break;
     }
+    sm->discard_ap_cnt = 0;
+    os_memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t));
     esp_wifi_set_wps_start_flag_internal(true);
     return ESP_OK;
 }
@@ -1895,12 +1937,6 @@ int wps_task_deinit(void)
         wpa_printf(MSG_DEBUG, "wps task deinit: free queue");
     }
 
-    if (s_wps_task_hdl) {
-        vTaskDelete(s_wps_task_hdl);
-        s_wps_task_hdl = NULL;
-        wpa_printf(MSG_DEBUG, "wps task deinit: free task");
-    }
-
     if (STAILQ_FIRST(&s_wps_rxq) != NULL){
         wps_rxq_deinit();
     }

+ 24 - 55
components/wpa_supplicant/src/wps/wps.c

@@ -67,11 +67,9 @@ struct wpabuf * wps_get_msg(struct wps_data *wps, enum wsc_op_code *op_code)
  * @msg: WPS IE contents from Beacon or Probe Response frame
  * Returns: 1 if PBC Registrar is active, 0 if not
  */
-int wps_is_selected_pbc_registrar(const struct wpabuf *msg, u8 *bssid)
+int wps_is_selected_pbc_registrar(const struct wpabuf *msg)
 {
-	struct wps_sm *sm = wps_sm_get();
     struct wps_parse_attr *attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
-    int i = 0;
 
     /*
      * In theory, this could also verify that attr.sel_reg_config_methods
@@ -80,33 +78,23 @@ int wps_is_selected_pbc_registrar(const struct wpabuf *msg, u8 *bssid)
      * it is safer to just use Device Password ID here.
      */
 
-    if (wps_parse_msg(msg, attr) < 0) {
-    	os_free(attr);
-    	return 0;
+    if (wps_parse_msg(msg, attr) < 0 ||
+        !attr->selected_registrar || *attr->selected_registrar == 0 ||
+        !attr->dev_password_id ||
+        WPA_GET_BE16(attr->dev_password_id) != DEV_PW_PUSHBUTTON) {
+            os_free(attr);
+            return 0;
     }
 
-    if(!attr->selected_registrar || *attr->selected_registrar == 0) {
-    	if (sm->ignore_sel_reg == false) {
-    		os_free(attr);
-    	    return 0;
-    	}
-    	else {
-    	   for (i = 0; i < WPS_MAX_DIS_AP_NUM; i++) {
-    	    	if (0 == os_memcmp(sm->dis_ap_list[i].bssid, bssid, 6)) {
-    	    		wpa_printf(MSG_DEBUG, "discard ap bssid[%02x:%02x:%02x:%02x:%02x:%02x]\n", \
-    	    				bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
-    	    		os_free(attr);
-    	    		return 0;
-    	    	}
-    	   }
-    	}
-    }
 
-    if (!attr->dev_password_id ||
-        WPA_GET_BE16(attr->dev_password_id) != DEV_PW_PUSHBUTTON) {
-        os_free(attr);
-        return 0;
+#ifdef CONFIG_WPS_STRICT
+    if (!attr->sel_reg_config_methods ||
+        !(WPA_GET_BE16(attr->sel_reg_config_methods) &
+        WPS_CONFIG_PUSHBUTTON)) {
+            os_free(attr);
+            return 0;
     }
+#endif /* CONFIG_WPS_STRICT */
 
     os_free(attr);
     return 1;
@@ -114,14 +102,8 @@ int wps_is_selected_pbc_registrar(const struct wpabuf *msg, u8 *bssid)
 
 #ifdef CONFIG_WPS_PIN
 
-static int is_selected_pin_registrar(struct wps_parse_attr *attr, u8 *bssid)
+static int is_selected_pin_registrar(struct wps_parse_attr *attr)
 {
-	struct wps_sm *sm = wps_sm_get();
-	int i = 0;
-
-	if (!sm || !bssid){
-		return 0;
-	}
     /*
      * In theory, this could also verify that attr.sel_reg_config_methods
      * includes WPS_CONFIG_LABEL, WPS_CONFIG_DISPLAY, or WPS_CONFIG_KEYPAD,
@@ -131,27 +113,19 @@ static int is_selected_pin_registrar(struct wps_parse_attr *attr, u8 *bssid)
      */
 
     if (!attr->selected_registrar || *attr->selected_registrar == 0) {
-    	if (sm->ignore_sel_reg == false) {
-    		return 0;
-        }
-    	else {
-    		for (i = 0; i < WPS_MAX_DIS_AP_NUM; i++) {
-    		    if (0 == os_memcmp(sm->dis_ap_list[i].bssid, bssid, 6)) {
-    		    	wpa_printf(MSG_DEBUG, "discard ap bssid[%02x:%02x:%02x:%02x:%02x:%02x]\n", \
-    		    	    bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
-    		        return 0;
-    		    }
-    		}
-    	}
+        return 0;
     }
     if (attr->dev_password_id != NULL &&
         WPA_GET_BE16(attr->dev_password_id) == DEV_PW_PUSHBUTTON) {
         return 0;
     }
 #ifdef CONFIG_WPS_STRICT
-    if (!attr->sel_reg_config_methods)
+    if (!attr->sel_reg_config_methods ||
+        !(WPA_GET_BE16(attr->sel_reg_config_methods) &
+        (WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD)))
         return 0;
 #endif /* CONFIG_WPS_STRICT */
+
     return 1;
 }
 
@@ -161,7 +135,7 @@ static int is_selected_pin_registrar(struct wps_parse_attr *attr, u8 *bssid)
  * @msg: WPS IE contents from Beacon or Probe Response frame
  * Returns: 1 if PIN Registrar is active, 0 if not
  */
-int wps_is_selected_pin_registrar(const struct wpabuf *msg, u8 *bssid)
+int wps_is_selected_pin_registrar(const struct wpabuf *msg)
 {
     struct wps_parse_attr *attr;
     int ret;
@@ -175,7 +149,7 @@ int wps_is_selected_pin_registrar(const struct wpabuf *msg, u8 *bssid)
         return 0;
     }
 
-    ret = is_selected_pin_registrar(attr, bssid);
+    ret = is_selected_pin_registrar(attr);
     os_free(attr);
 
     return ret;
@@ -193,20 +167,15 @@ int wps_is_selected_pin_registrar(const struct wpabuf *msg, u8 *bssid)
 int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr,
                int ver1_compat)
 {
-	struct wps_sm *sm = wps_sm_get();
     struct wps_parse_attr *attr;
     int ret = 0;
     unsigned int i;
     const u8 *pos;
     const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
-    if (!sm){
-    	return -10;
-    }
-
     attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
     if (attr == NULL) {
-        ret = -99;
+        ret = 0;
         goto _out;
     }
 
@@ -222,7 +191,7 @@ int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr,
          */
 #ifdef CONFIG_WPS_PIN
 
-        ret = is_selected_pin_registrar(attr, sm->config.bssid);
+        ret = is_selected_pin_registrar(attr);
         goto _out;
 #endif
     }

+ 3 - 2
components/wpa_supplicant/src/wps/wps.h

@@ -233,8 +233,8 @@ enum wps_process_res wps_process_msg(struct wps_data *wps,
 
 struct wpabuf * wps_get_msg(struct wps_data *wps, enum wsc_op_code *op_code);
 
-int wps_is_selected_pbc_registrar(const struct wpabuf *msg, u8 *bssid);
-int wps_is_selected_pin_registrar(const struct wpabuf *msg, u8 *bssid);
+int wps_is_selected_pbc_registrar(const struct wpabuf *msg);
+int wps_is_selected_pin_registrar(const struct wpabuf *msg);
 int wps_ap_priority_compar(const struct wpabuf *wps_a,
 			   const struct wpabuf *wps_b);
 int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr,
@@ -1054,6 +1054,7 @@ struct wps_sm {
 #endif
     u8 discover_ssid_cnt;
     bool ignore_sel_reg;
+    bool wps_pin_war;
     struct discard_ap_list_t dis_ap_list[WPS_MAX_DIS_AP_NUM];
     u8 discard_ap_cnt;
     wifi_sta_config_t config;