]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - wpa_supplicant/ctrl_iface.c
tests: Protocol testing for supplicant PMF/IGTK KDE handling
[thirdparty/hostap.git] / wpa_supplicant / ctrl_iface.c
index 936cf3144fe2dc0ec23313ca331bc755f2ad8caf..198ac562d8b6afdbfa949aa7ef19dc179bac514f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant / Control interface (shared code for all backends)
- * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -1168,8 +1168,11 @@ static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
 #ifdef CONFIG_AP
        u8 *_p2p_dev_addr = NULL;
 #endif /* CONFIG_AP */
+       char *pos;
+       int multi_ap = 0;
 
-       if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
+       if (!cmd || os_strcmp(cmd, "any") == 0 ||
+           os_strncmp(cmd, "any ", 4) == 0) {
                _bssid = NULL;
 #ifdef CONFIG_P2P
        } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
@@ -1181,18 +1184,29 @@ static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
                }
                _p2p_dev_addr = p2p_dev_addr;
 #endif /* CONFIG_P2P */
+       } else if (os_strncmp(cmd, "multi_ap=", 9) == 0) {
+               _bssid = NULL;
+               multi_ap = atoi(cmd + 9);
        } else if (hwaddr_aton(cmd, bssid)) {
                wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
                           cmd);
                return -1;
        }
 
+       if (cmd) {
+               pos = os_strstr(cmd, " multi_ap=");
+               if (pos) {
+                       pos += 10;
+                       multi_ap = atoi(pos);
+               }
+       }
+
 #ifdef CONFIG_AP
        if (wpa_s->ap_iface)
                return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
 #endif /* CONFIG_AP */
 
-       return wpas_wps_start_pbc(wpa_s, _bssid, 0);
+       return wpas_wps_start_pbc(wpa_s, _bssid, 0, multi_ap);
 }
 
 
@@ -2118,6 +2132,18 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
                        pos += ret;
                }
 
+               if (wpa_s->connection_set &&
+                   (wpa_s->connection_ht || wpa_s->connection_vht ||
+                    wpa_s->connection_he)) {
+                       ret = os_snprintf(pos, end - pos,
+                                         "wifi_generation=%u\n",
+                                         wpa_s->connection_he ? 6 :
+                                         (wpa_s->connection_vht ? 5 : 4));
+                       if (os_snprintf_error(end - pos, ret))
+                               return pos - buf;
+                       pos += ret;
+               }
+
 #ifdef CONFIG_AP
                if (wpa_s->ap_iface) {
                        pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
@@ -2913,6 +2939,12 @@ static int wpa_supplicant_ctrl_iface_scan_result(
                pos += ret;
        }
 #endif /* CONFIG_FST */
+       if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_UTF_8_SSID)) {
+               ret = os_snprintf(pos, end - pos, "[UTF-8]");
+               if (os_snprintf_error(end - pos, ret))
+                       return -1;
+               pos += ret;
+       }
 
        ret = os_snprintf(pos, end - pos, "\t%s",
                          wpa_ssid_txt(bss->ssid, bss->ssid_len));
@@ -3988,6 +4020,14 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
        }
 #endif /* CONFIG_IEEE80211R */
 #endif /* CONFIG_FILS */
+#ifdef CONFIG_IEEE80211R
+       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK) {
+               ret = os_snprintf(pos, end - pos, " FT-PSK");
+               if (os_snprintf_error(end - pos, ret))
+                       return pos - buf;
+               pos += ret;
+       }
+#endif /* CONFIG_IEEE80211R */
 #ifdef CONFIG_SAE
        if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) {
                ret = os_snprintf(pos, end - pos, " SAE");
@@ -4403,6 +4443,19 @@ static int wpa_supplicant_ctrl_iface_get_capability(
                return res;
        }
 
+#ifdef CONFIG_DPP
+       if (os_strcmp(field, "dpp") == 0) {
+#ifdef CONFIG_DPP2
+               res = os_snprintf(buf, buflen, "DPP=2");
+#else /* CONFIG_DPP2 */
+               res = os_snprintf(buf, buflen, "DPP=1");
+#endif /* CONFIG_DPP2 */
+               if (os_snprintf_error(buflen, res))
+                       return -1;
+               return res;
+       }
+#endif /* CONFIG_DPP */
+
        wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
                   field);
 
@@ -4733,6 +4786,20 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
                        pos += ret;
                }
 #endif /* CONFIG_FILS */
+#ifdef CONFIG_FST
+               if (wpa_bss_get_ie(bss, WLAN_EID_MULTI_BAND)) {
+                       ret = os_snprintf(pos, end - pos, "[FST]");
+                       if (os_snprintf_error(end - pos, ret))
+                               return 0;
+                       pos += ret;
+               }
+#endif /* CONFIG_FST */
+               if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_UTF_8_SSID)) {
+                       ret = os_snprintf(pos, end - pos, "[UTF-8]");
+                       if (os_snprintf_error(end - pos, ret))
+                               return 0;
+                       pos += ret;
+               }
 
                ret = os_snprintf(pos, end - pos, "\n");
                if (os_snprintf_error(end - pos, ret))
@@ -5029,10 +5096,11 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
                bss = NULL;
                dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
                {
-                       if (i-- == 0) {
+                       if (i == 0) {
                                bss = tmp;
                                break;
                        }
+                       i--;
                }
        }
 
@@ -5518,6 +5586,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
        int ht40, vht, max_oper_chwidth, chwidth = 0, freq2 = 0;
        u8 _group_ssid[SSID_MAX_LEN], *group_ssid = NULL;
        size_t group_ssid_len = 0;
+       int he;
 
        if (!wpa_s->global->p2p_init_wpa_s)
                return -1;
@@ -5530,7 +5599,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
        /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad|p2ps]
         * [persistent|persistent=<network id>]
         * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc]
-        * [ht40] [vht] [auto] [ssid=<hexdump>] */
+        * [ht40] [vht] [he] [auto] [ssid=<hexdump>] */
 
        if (hwaddr_aton(cmd, addr))
                return -1;
@@ -5561,6 +5630,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
        vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht;
        ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
                vht;
+       he = (os_strstr(cmd, " he") != NULL) || wpa_s->conf->p2p_go_he;
 
        pos2 = os_strstr(pos, " go_intent=");
        if (pos2) {
@@ -5631,7 +5701,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
        new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
                                   persistent_group, automatic, join,
                                   auth, go_intent, freq, freq2, persistent_id,
-                                  pd, ht40, vht, max_oper_chwidth,
+                                  pd, ht40, vht, max_oper_chwidth, he,
                                   group_ssid, group_ssid_len);
        if (new_pin == -2) {
                os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
@@ -6187,7 +6257,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
        struct wpa_ssid *ssid;
        u8 *_peer = NULL, peer[ETH_ALEN];
        int freq = 0, pref_freq = 0;
-       int ht40, vht, max_oper_chwidth, chwidth = 0, freq2 = 0;
+       int ht40, vht, he, max_oper_chwidth, chwidth = 0, freq2 = 0;
 
        id = atoi(cmd);
        pos = os_strstr(cmd, " peer=");
@@ -6224,6 +6294,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
        vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht;
        ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
                vht;
+       he = (os_strstr(cmd, " he") != NULL) || wpa_s->conf->p2p_go_he;
 
        pos = os_strstr(cmd, "freq2=");
        if (pos)
@@ -6238,7 +6309,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
                return -1;
 
        return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, freq2, ht40, vht,
-                              max_oper_chwidth, pref_freq);
+                              max_oper_chwidth, pref_freq, he);
 }
 
 
@@ -6286,7 +6357,8 @@ static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
 
 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
                                         int id, int freq, int vht_center_freq2,
-                                        int ht40, int vht, int vht_chwidth)
+                                        int ht40, int vht, int vht_chwidth,
+                                        int he)
 {
        struct wpa_ssid *ssid;
 
@@ -6300,7 +6372,7 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
 
        return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq,
                                             vht_center_freq2, 0, ht40, vht,
-                                            vht_chwidth, NULL, 0, 0);
+                                            vht_chwidth, he, NULL, 0, 0);
 }
 
 
@@ -6309,6 +6381,7 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
        int freq = 0, persistent = 0, group_id = -1;
        int vht = wpa_s->conf->p2p_go_vht;
        int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+       int he = wpa_s->conf->p2p_go_he;
        int max_oper_chwidth, chwidth = 0, freq2 = 0;
        char *token, *context = NULL;
 #ifdef CONFIG_ACS
@@ -6331,6 +6404,8 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
                } else if (os_strcmp(token, "vht") == 0) {
                        vht = 1;
                        ht40 = 1;
+               } else if (os_strcmp(token, "he") == 0) {
+                       he = 1;
                } else if (os_strcmp(token, "persistent") == 0) {
                        persistent = 1;
                } else {
@@ -6356,6 +6431,8 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
                        wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211ANY;
                        wpa_s->p2p_go_do_acs = 1;
                }
+       } else {
+               wpa_s->p2p_go_do_acs = 0;
        }
 #endif /* CONFIG_ACS */
 
@@ -6366,10 +6443,10 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
        if (group_id >= 0)
                return p2p_ctrl_group_add_persistent(wpa_s, group_id,
                                                     freq, freq2, ht40, vht,
-                                                    max_oper_chwidth);
+                                                    max_oper_chwidth, he);
 
        return wpas_p2p_group_add(wpa_s, persistent, freq, freq2, ht40, vht,
-                                 max_oper_chwidth);
+                                 max_oper_chwidth, he);
 }
 
 
@@ -7638,7 +7715,7 @@ static int wpas_ctrl_iface_get_pref_freq_list(
 
        wpa_printf(MSG_DEBUG,
                   "CTRL_IFACE: GET_PREF_FREQ_LIST iface_type=%d (%s)",
-                  iface_type, buf);
+                  iface_type, cmd);
 
        ret = wpa_drv_get_pref_freq_list(wpa_s, iface_type, &num, freq_list);
        if (ret)
@@ -9500,13 +9577,6 @@ static int wpas_ctrl_iface_mac_rand_scan(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
-       if ((wpa_s->mac_addr_rand_supported & type) != type) {
-               wpa_printf(MSG_INFO,
-                          "CTRL: MAC_RAND_SCAN types=%u != supported=%u",
-                          type, wpa_s->mac_addr_rand_supported);
-               return -1;
-       }
-
        if (enable > 1) {
                wpa_printf(MSG_INFO,
                           "CTRL: MAC_RAND_SCAN enable=<0/1> not specified");
@@ -9540,21 +9610,25 @@ static int wpas_ctrl_iface_mac_rand_scan(struct wpa_supplicant *wpa_s,
        }
 
        if (type & MAC_ADDR_RAND_SCAN) {
-               wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCAN,
-                                           addr, mask);
+               if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCAN,
+                                           addr, mask))
+                       return -1;
        }
 
        if (type & MAC_ADDR_RAND_SCHED_SCAN) {
-               wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCHED_SCAN,
-                                           addr, mask);
+               if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCHED_SCAN,
+                                           addr, mask))
+                       return -1;
 
                if (wpa_s->sched_scanning && !wpa_s->pno)
                        wpas_scan_restart_sched_scan(wpa_s);
        }
 
        if (type & MAC_ADDR_RAND_PNO) {
-               wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_PNO,
-                                           addr, mask);
+               if (wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_PNO,
+                                           addr, mask))
+                       return -1;
+
                if (wpa_s->pno) {
                        wpas_stop_pno(wpa_s);
                        wpas_start_pno(wpa_s);
@@ -10553,10 +10627,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strcmp(buf, "RESEND_ASSOC") == 0) {
                if (wpas_ctrl_resend_assoc(wpa_s) < 0)
                        reply_len = -1;
+#ifdef CONFIG_IEEE80211W
        } else if (os_strcmp(buf, "UNPROT_DEAUTH") == 0) {
                sme_event_unprot_disconnect(
                        wpa_s, wpa_s->bssid, NULL,
                        WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
+#endif /* CONFIG_IEEE80211W */
 #endif /* CONFIG_TESTING_OPTIONS */
        } else if (os_strncmp(buf, "VENDOR_ELEM_ADD ", 16) == 0) {
                if (wpas_ctrl_vendor_elem_add(wpa_s, buf + 16) < 0)
@@ -10600,7 +10676,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strncmp(buf, "DPP_BOOTSTRAP_GEN ", 18) == 0) {
                int res;
 
-               res = wpas_dpp_bootstrap_gen(wpa_s, buf + 18);
+               res = dpp_bootstrap_gen(wpa_s->dpp, buf + 18);
                if (res < 0) {
                        reply_len = -1;
                } else {
@@ -10609,12 +10685,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                                reply_len = -1;
                }
        } else if (os_strncmp(buf, "DPP_BOOTSTRAP_REMOVE ", 21) == 0) {
-               if (wpas_dpp_bootstrap_remove(wpa_s, buf + 21) < 0)
+               if (dpp_bootstrap_remove(wpa_s->dpp, buf + 21) < 0)
                        reply_len = -1;
        } else if (os_strncmp(buf, "DPP_BOOTSTRAP_GET_URI ", 22) == 0) {
                const char *uri;
 
-               uri = wpas_dpp_bootstrap_get_uri(wpa_s, atoi(buf + 22));
+               uri = dpp_bootstrap_get_uri(wpa_s->dpp, atoi(buf + 22));
                if (!uri) {
                        reply_len = -1;
                } else {
@@ -10623,8 +10699,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                                reply_len = -1;
                }
        } else if (os_strncmp(buf, "DPP_BOOTSTRAP_INFO ", 19) == 0) {
-               reply_len = wpas_dpp_bootstrap_info(wpa_s, atoi(buf + 19),
-                                                   reply, reply_size);
+               reply_len = dpp_bootstrap_info(wpa_s->dpp, atoi(buf + 19),
+                                              reply, reply_size);
        } else if (os_strncmp(buf, "DPP_AUTH_INIT ", 14) == 0) {
                if (wpas_dpp_auth_init(wpa_s, buf + 13) < 0)
                        reply_len = -1;
@@ -10637,7 +10713,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_ADD", 20) == 0) {
                int res;
 
-               res = wpas_dpp_configurator_add(wpa_s, buf + 20);
+               res = dpp_configurator_add(wpa_s->dpp, buf + 20);
                if (res < 0) {
                        reply_len = -1;
                } else {
@@ -10646,14 +10722,15 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                                reply_len = -1;
                }
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
-               if (wpas_dpp_configurator_remove(wpa_s, buf + 24) < 0)
+               if (dpp_configurator_remove(wpa_s->dpp, buf + 24) < 0)
                        reply_len = -1;
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_SIGN ", 22) == 0) {
                if (wpas_dpp_configurator_sign(wpa_s, buf + 21) < 0)
                        reply_len = -1;
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_GET_KEY ", 25) == 0) {
-               reply_len = wpas_dpp_configurator_get_key(wpa_s, atoi(buf + 25),
-                                                         reply, reply_size);
+               reply_len = dpp_configurator_get_key_id(wpa_s->dpp,
+                                                       atoi(buf + 25),
+                                                       reply, reply_size);
        } else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) {
                int res;