From f7f4db156ffdd0792dbfcddde3ba60a7ee561dcc Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 22 Feb 2021 09:49:19 +0100 Subject: [PATCH 1/3] supplicant: detect the SAE interface capability There isn't a global SAE capability in wpa_supplicant, use the per-interface one. --- src/core/supplicant/nm-supplicant-interface.c | 17 +++++++++++++++-- src/core/supplicant/nm-supplicant-types.h | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/core/supplicant/nm-supplicant-interface.c b/src/core/supplicant/nm-supplicant-interface.c index 176e4d2f61..62a380ce95 100644 --- a/src/core/supplicant/nm-supplicant-interface.c +++ b/src/core/supplicant/nm-supplicant-interface.c @@ -1171,19 +1171,24 @@ parse_capabilities(NMSupplicantInterface *self, GVariant *capabilities) const gboolean old_prop_scan_ssid = priv->prop_scan_ssid; const guint32 old_max_scan_ssids = priv->max_scan_ssids; gboolean have_ft = FALSE; + gboolean have_sae = FALSE; gint32 max_scan_ssids; const char ** array; nm_assert(capabilities && g_variant_is_of_type(capabilities, G_VARIANT_TYPE_VARDICT)); if (g_variant_lookup(capabilities, "KeyMgmt", "^a&s", &array)) { - have_ft = g_strv_contains(array, "wpa-ft-psk"); + have_ft = g_strv_contains(array, "wpa-ft-psk"); + have_sae = g_strv_contains(array, "sae"); g_free(array); } priv->iface_capabilities = NM_SUPPL_CAP_MASK_SET(priv->iface_capabilities, NM_SUPPL_CAP_TYPE_FT, have_ft ? NM_TERNARY_TRUE : NM_TERNARY_FALSE); + priv->iface_capabilities = NM_SUPPL_CAP_MASK_SET(priv->iface_capabilities, + NM_SUPPL_CAP_TYPE_SAE, + have_sae ? NM_TERNARY_TRUE : NM_TERNARY_FALSE); if (g_variant_lookup(capabilities, "Modes", "^a&s", &array)) { /* Setting p2p_capable might toggle _prop_p2p_available_get(). However, @@ -1278,6 +1283,10 @@ _get_capability(NMSupplicantInterfacePrivate *priv, NMSupplCapType type) value = iface_value; } break; + case NM_SUPPL_CAP_TYPE_SAE: + nm_assert(NM_SUPPL_CAP_MASK_GET(priv->global_capabilities, type) == NM_TERNARY_DEFAULT); + value = NM_SUPPL_CAP_MASK_GET(priv->iface_capabilities, type); + break; default: nm_assert(NM_SUPPL_CAP_MASK_GET(priv->iface_capabilities, type) == NM_TERNARY_DEFAULT); value = NM_SUPPL_CAP_MASK_GET(priv->global_capabilities, type); @@ -1305,9 +1314,13 @@ nm_supplicant_interface_get_capabilities(NMSupplicantInterface *self) caps = NM_SUPPL_CAP_MASK_SET(caps, NM_SUPPL_CAP_TYPE_FT, _get_capability(priv, NM_SUPPL_CAP_TYPE_FT)); + caps = NM_SUPPL_CAP_MASK_SET(caps, + NM_SUPPL_CAP_TYPE_SAE, + _get_capability(priv, NM_SUPPL_CAP_TYPE_SAE)); nm_assert(!NM_FLAGS_ANY(priv->iface_capabilities, - ~(NM_SUPPL_CAP_MASK_T_AP_MASK | NM_SUPPL_CAP_MASK_T_FT_MASK))); + ~(NM_SUPPL_CAP_MASK_T_AP_MASK | NM_SUPPL_CAP_MASK_T_FT_MASK + | NM_SUPPL_CAP_MASK_T_SAE_MASK))); #if NM_MORE_ASSERTS > 10 { diff --git a/src/core/supplicant/nm-supplicant-types.h b/src/core/supplicant/nm-supplicant-types.h index adcf02db8b..8836bba760 100644 --- a/src/core/supplicant/nm-supplicant-types.h +++ b/src/core/supplicant/nm-supplicant-types.h @@ -41,6 +41,7 @@ typedef enum { NM_SUPPL_CAP_TYPE_FILS, NM_SUPPL_CAP_TYPE_P2P, NM_SUPPL_CAP_TYPE_FT, + NM_SUPPL_CAP_TYPE_SAE, NM_SUPPL_CAP_TYPE_SHA384, NM_SUPPL_CAP_TYPE_MESH, NM_SUPPL_CAP_TYPE_FAST, @@ -71,6 +72,7 @@ typedef enum { _NM_SUPPL_CAP_MASK_DEFINE(MESH), _NM_SUPPL_CAP_MASK_DEFINE(WFD), _NM_SUPPL_CAP_MASK_DEFINE(FT), + _NM_SUPPL_CAP_MASK_DEFINE(SAE), _NM_SUPPL_CAP_MASK_DEFINE(SHA384), #undef _NM_SUPPL_CAP_MASK_DEFINE } NMSupplCapMask; From d233314ce123dfde6dadfd02653b9067cd88cfb2 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 22 Feb 2021 10:54:25 +0100 Subject: [PATCH 2/3] supplicant: print interface capabilities --- src/core/supplicant/nm-supplicant-interface.c | 9 ++++++ src/core/supplicant/nm-supplicant-manager.c | 31 ++++++------------- src/core/supplicant/nm-supplicant-types.h | 13 ++++++++ 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/core/supplicant/nm-supplicant-interface.c b/src/core/supplicant/nm-supplicant-interface.c index 62a380ce95..7c1a32783a 100644 --- a/src/core/supplicant/nm-supplicant-interface.c +++ b/src/core/supplicant/nm-supplicant-interface.c @@ -1260,6 +1260,15 @@ _starting_check_ready(NMSupplicantInterface *self) return; } + _LOGD("interface supported features:" + " AP%c" + " FT%c" + " SAE%c" + "", + NM_SUPPL_CAP_TO_CHAR(priv->iface_capabilities, NM_SUPPL_CAP_TYPE_AP), + NM_SUPPL_CAP_TO_CHAR(priv->iface_capabilities, NM_SUPPL_CAP_TYPE_FT), + NM_SUPPL_CAP_TO_CHAR(priv->iface_capabilities, NM_SUPPL_CAP_TYPE_SAE)); + set_state(self, priv->supp_state); } diff --git a/src/core/supplicant/nm-supplicant-manager.c b/src/core/supplicant/nm-supplicant-manager.c index d4806161e8..cf36322e30 100644 --- a/src/core/supplicant/nm-supplicant-manager.c +++ b/src/core/supplicant/nm-supplicant-manager.c @@ -168,19 +168,6 @@ _caps_set(NMSupplicantManagerPrivate *priv, NMSupplCapType type, NMTernary value priv->capabilities = NM_SUPPL_CAP_MASK_SET(priv->capabilities, type, value); } -static char -_caps_to_char(NMSupplicantManagerPrivate *priv, NMSupplCapType type) -{ - NMTernary val; - - val = NM_SUPPL_CAP_MASK_GET(priv->capabilities, type); - if (val == NM_TERNARY_TRUE) - return '+'; - if (val == NM_TERNARY_FALSE) - return '-'; - return '?'; -} - /*****************************************************************************/ static void @@ -1008,15 +995,15 @@ _dbus_get_capabilities_cb(GVariant *res, GError *error, gpointer user_data) " FAST%c" " WFD%c" "", - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_AP), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_PMF), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_FILS), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_P2P), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_FT), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_SHA384), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_MESH), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_FAST), - _caps_to_char(priv, NM_SUPPL_CAP_TYPE_WFD)); + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_AP), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_PMF), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_FILS), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_P2P), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_FT), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_SHA384), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_MESH), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_FAST), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_WFD)); nm_assert(g_hash_table_size(priv->supp_ifaces) == 0); nm_assert(c_list_is_empty(&priv->supp_lst_head)); diff --git a/src/core/supplicant/nm-supplicant-types.h b/src/core/supplicant/nm-supplicant-types.h index 8836bba760..ae2db3f6eb 100644 --- a/src/core/supplicant/nm-supplicant-types.h +++ b/src/core/supplicant/nm-supplicant-types.h @@ -116,6 +116,19 @@ NM_SUPPL_CAP_MASK_GET(NMSupplCapMask features, NMSupplCapType type) return (NMTernary)(f - 1); } +static inline char +NM_SUPPL_CAP_TO_CHAR(NMSupplCapMask features, NMSupplCapType type) +{ + NMTernary val; + + val = NM_SUPPL_CAP_MASK_GET(features, type); + if (val == NM_TERNARY_TRUE) + return '+'; + if (val == NM_TERNARY_FALSE) + return '-'; + return '?'; +} + /*****************************************************************************/ /** From f5d78c2d289c9e4a4c247d2520c7c3e2baf537c8 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 19 Feb 2021 16:28:44 +0100 Subject: [PATCH 3/3] supplicant: enable WPA3 for WPA-PSK connections A connection with key-mgmt=wpa-psk should be able to connect to WPA, WPA2 and WPA3 APs, choosing the best candidate automatically. Also pass SAE (WPA3) key-mgmt to wpa_supplicant when it is supported. For example, I now get this when connecting to a WPA2 network: [1613749711.2915] Config: added 'key_mgmt' value 'WPA-PSK WPA-PSK-SHA256 FT-PSK SAE FT-SAE' --- src/core/supplicant/nm-supplicant-config.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c index 9a77d03e6f..cd0e99c6d7 100644 --- a/src/core/supplicant/nm-supplicant-config.c +++ b/src/core/supplicant/nm-supplicant-config.c @@ -841,6 +841,11 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig * g_string_append(key_mgmt_conf, " wpa-psk-sha256"); if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) g_string_append(key_mgmt_conf, " ft-psk"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_SAE)) { + g_string_append(key_mgmt_conf, " sae"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) + g_string_append(key_mgmt_conf, " ft-sae"); + } } else if (nm_streq(key_mgmt, "wpa-eap")) { if (_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF)) { g_string_append(key_mgmt_conf, " wpa-eap-sha256");