]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Allow per interface type AKM capabilities to be fetched
authorVeerendranath Jakkam <vjakkam@codeaurora.org>
Wed, 22 Apr 2020 07:24:35 +0000 (12:54 +0530)
committerJouni Malinen <j@w1.fi>
Tue, 12 May 2020 14:33:54 +0000 (17:33 +0300)
Add support to query per interface type AKM capabilities through the
control interface. For example, "GET_CAPABILITY key_mgmt
iftype=STATION".

Signed-off-by: Veerendranath Jakkam <vjakkam@codeaurora.org>
wpa_supplicant/ctrl_iface.c
wpa_supplicant/wpa_cli.c

index 5c99735c8c35a1757e2727f2ef1a2cdd49f20824..4860e34800be24762d94f645c84bf6903ed13a27 100644 (file)
@@ -4098,11 +4098,49 @@ static int ctrl_iface_get_capability_group_mgmt(int res, char *strict,
 }
 
 
+static int iftype_str_to_index(const char *iftype_str)
+{
+       if (!iftype_str)
+               return WPA_IF_MAX;
+
+       if (os_strcmp(iftype_str, "STATION") == 0)
+               return WPA_IF_STATION;
+
+       if (os_strcmp(iftype_str, "AP_VLAN") == 0)
+               return WPA_IF_AP_VLAN;
+
+       if (os_strcmp(iftype_str, "AP") == 0)
+               return WPA_IF_AP_BSS;
+
+       if (os_strcmp(iftype_str, "P2P_GO") == 0)
+               return WPA_IF_P2P_GO;
+
+       if (os_strcmp(iftype_str, "P2P_CLIENT") == 0)
+               return WPA_IF_P2P_CLIENT;
+
+       if (os_strcmp(iftype_str, "P2P_DEVICE") == 0)
+               return WPA_IF_P2P_DEVICE;
+
+       if (os_strcmp(iftype_str, "MESH") == 0)
+               return WPA_IF_MESH;
+
+       if (os_strcmp(iftype_str, "IBSS") == 0)
+               return WPA_IF_IBSS;
+
+       if (os_strcmp(iftype_str, "NAN") == 0)
+               return WPA_IF_NAN;
+
+       return WPA_IF_MAX;
+}
+
+
 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
                                              struct wpa_driver_capa *capa,
+                                             const char *iftype_str,
                                              char *buf, size_t buflen)
 {
        int ret;
+       unsigned int key_mgmt;
        char *pos, *end;
        size_t len;
 
@@ -4119,28 +4157,39 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
                return len;
        }
 
+       if (iftype_str) {
+               enum wpa_driver_if_type iftype;
+
+               iftype = iftype_str_to_index(iftype_str);
+               if (iftype == WPA_IF_MAX)
+                       return -1;
+               key_mgmt = capa->key_mgmt_iftype[iftype];
+       } else {
+               key_mgmt = capa->key_mgmt;
+       }
+
        ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
        if (os_snprintf_error(end - pos, ret))
                return pos - buf;
        pos += ret;
 
-       if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
-                             WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
+       if (key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
+                       WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
                ret = os_snprintf(pos, end - pos, " WPA-EAP");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
                pos += ret;
        }
 
-       if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
-                             WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
+       if (key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
+                       WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
                ret = os_snprintf(pos, end - pos, " WPA-PSK");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
                pos += ret;
        }
 
-       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
+       if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
                ret = os_snprintf(pos, end - pos, " WPA-NONE");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
@@ -4148,7 +4197,7 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
        }
 
 #ifdef CONFIG_SUITEB
-       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B) {
+       if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B) {
                ret = os_snprintf(pos, end - pos, " WPA-EAP-SUITE-B");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
@@ -4156,7 +4205,7 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
        }
 #endif /* CONFIG_SUITEB */
 #ifdef CONFIG_SUITEB192
-       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
+       if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
                ret = os_snprintf(pos, end - pos, " WPA-EAP-SUITE-B-192");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
@@ -4164,7 +4213,7 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
        }
 #endif /* CONFIG_SUITEB192 */
 #ifdef CONFIG_OWE
-       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
+       if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
                ret = os_snprintf(pos, end - pos, " OWE");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
@@ -4172,7 +4221,7 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
        }
 #endif /* CONFIG_OWE */
 #ifdef CONFIG_DPP
-       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
+       if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
                ret = os_snprintf(pos, end - pos, " DPP");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
@@ -4180,26 +4229,26 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
        }
 #endif /* CONFIG_DPP */
 #ifdef CONFIG_FILS
-       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
+       if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
                ret = os_snprintf(pos, end - pos, " FILS-SHA256");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
                pos += ret;
        }
-       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
+       if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
                ret = os_snprintf(pos, end - pos, " FILS-SHA384");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
                pos += ret;
        }
 #ifdef CONFIG_IEEE80211R
-       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256) {
+       if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256) {
                ret = os_snprintf(pos, end - pos, " FT-FILS-SHA256");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
                pos += ret;
        }
-       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384) {
+       if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384) {
                ret = os_snprintf(pos, end - pos, " FT-FILS-SHA384");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
@@ -4208,7 +4257,7 @@ 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) {
+       if (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;
@@ -4216,7 +4265,7 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
        }
 #endif /* CONFIG_IEEE80211R */
 #ifdef CONFIG_SAE
-       if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) {
+       if (key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) {
                ret = os_snprintf(pos, end - pos, " SAE");
                if (os_snprintf_error(end - pos, ret))
                        return pos - buf;
@@ -4512,23 +4561,35 @@ static int wpa_supplicant_ctrl_iface_get_capability(
 {
        struct wpa_driver_capa capa;
        int res;
-       char *strict;
-       char field[30];
+       char *next_param, *curr_param, *iftype = NULL, *strict = NULL;
+       char field[50];
        size_t len;
 
        /* Determine whether or not strict checking was requested */
        len = os_strlcpy(field, _field, sizeof(field));
        if (len >= sizeof(field))
                return -1;
-       strict = os_strchr(field, ' ');
-       if (strict != NULL) {
-               *strict++ = '\0';
-               if (os_strcmp(strict, "strict") != 0)
+
+       next_param = os_strchr(field, ' ');
+       while (next_param) {
+               *next_param++ = '\0';
+               curr_param = next_param;
+               next_param = os_strchr(next_param, ' ');
+
+               if (next_param)
+                       *next_param = '\0';
+
+               if (os_strcmp(curr_param, "strict") == 0)
+                       strict = curr_param;
+               else if (os_strncmp(curr_param, "iftype=", 7) == 0)
+                       iftype = curr_param + 7;
+               else
                        return -1;
        }
 
-       wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
-               field, strict ? strict : "");
+       wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s'%s%s%s",
+                  field, iftype ? " iftype=" : "", iftype ? iftype : "",
+                  strict ? " strict" : "");
 
        if (os_strcmp(field, "eap") == 0) {
                return eap_get_names(buf, buflen);
@@ -4550,7 +4611,7 @@ static int wpa_supplicant_ctrl_iface_get_capability(
 
        if (os_strcmp(field, "key_mgmt") == 0)
                return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
-                                                         buf, buflen);
+                                                         iftype, buf, buflen);
 
        if (os_strcmp(field, "proto") == 0)
                return ctrl_iface_get_capability_proto(res, strict, &capa,
index 07d5f315cf5cf3ea595275cf3b3c8022e65504cf..6a2d2c3d65e742601b883d4db1de54eef4f6b1fb 100644 (file)
@@ -1706,15 +1706,25 @@ static char ** wpa_cli_complete_bss(const char *str, int pos)
 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
                                      char *argv[])
 {
-       if (argc < 1 || argc > 2) {
-               printf("Invalid GET_CAPABILITY command: need either one or "
-                      "two arguments\n");
+       if (argc < 1 || argc > 3) {
+               printf("Invalid GET_CAPABILITY command: need at least one argument and max three arguments\n");
                return -1;
        }
 
-       if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
-               printf("Invalid GET_CAPABILITY command: second argument, "
-                      "if any, must be 'strict'\n");
+       if (argc > 1 && os_strcmp(argv[0], "key_mgmt") != 0 &&
+           os_strncmp(argv[1], "iftype=", 7) == 0) {
+               printf("Invalid GET_CAPABILITY command: 'iftype=' param is allowed only for 'key_mgmt'\n");
+               return -1;
+       }
+
+       if (argc == 2 && os_strcmp(argv[1], "strict") != 0 &&
+           os_strncmp(argv[1], "iftype=", 7) != 0) {
+               printf("Invalid GET_CAPABILITY command: the second argument, if any, must be 'strict' OR 'iftype=<iftype_name>'\n");
+               return -1;
+       }
+
+       if (argc == 3 && os_strcmp(argv[2], "strict") != 0) {
+               printf("Invalid GET_CAPABILITY command: the third argument, if any, must be 'strict'\n");
                return -1;
        }
 
@@ -1741,7 +1751,13 @@ static char ** wpa_cli_complete_get_capability(const char *str, int pos)
                "acs",
 #endif /* CONFIG_ACS */
        };
+       const char *iftypes[] = {
+               "iftype=STATION", "iftype=AP", "iftype=P2P_CLIENT",
+               "iftype=P2P_GO", "iftype=AP_VLAN", "iftype=IBSS", "iftype=NAN",
+               "iftype=P2P_DEVICE", "iftype=MESH",
+       };
        int i, num_fields = ARRAY_SIZE(fields);
+       int num_iftypes = ARRAY_SIZE(iftypes);
        char **res = NULL;
 
        if (arg == 1) {
@@ -1755,6 +1771,21 @@ static char ** wpa_cli_complete_get_capability(const char *str, int pos)
                }
        }
        if (arg == 2) {
+               /* the second argument can be "iftype=<iftype_name>" OR
+                * "strict" */
+               res = os_calloc(num_iftypes + 2, sizeof(char *));
+               if (!res)
+                       return NULL;
+               res[0] = os_strdup("strict");
+               if (!res[0])
+                       return res;
+               for (i = 0; i < num_iftypes; i++) {
+                       res[i + 1] = os_strdup(iftypes[i]);
+                       if (!res[i + 1])
+                               return res;
+               }
+       }
+       if (arg == 3) {
                res = os_calloc(1 + 1, sizeof(char *));
                if (res == NULL)
                        return NULL;