Allow per interface type AKM capabilities to be fetched

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>
This commit is contained in:
Veerendranath Jakkam 2020-04-22 12:54:35 +05:30 committed by Jouni Malinen
parent b67bedf2e3
commit 8d7502809c
2 changed files with 122 additions and 30 deletions

View 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,12 +4157,23 @@ 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 |
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))
@ -4132,7 +4181,7 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
pos += ret;
}
if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_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))
@ -4140,7 +4189,7 @@ static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
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,

View 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;