From 5f146b40f3f48c4bd52f4678a4ccda5d32c58f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Fri, 23 Apr 2021 15:17:07 +0200 Subject: [PATCH 1/8] supplicant/config: Refactor key_mgmt config generation Refactor the generation of the key_mgmt option of the wpa_supplicant config we generate. The goal of this is to lay out all the cases we support more obviously and to make it a bit clearer that our key-mgmt property of NMSettingsWirelessSecurity is not the same as the "key_mgmt" config we set in wpa_supplicant. --- src/core/supplicant/nm-supplicant-config.c | 84 +++++++++++++--------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c index bb6cb6c44a..494274ae33 100644 --- a/src/core/supplicant/nm-supplicant-config.c +++ b/src/core/supplicant/nm-supplicant-config.c @@ -834,55 +834,73 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig * } key_mgmt = nm_setting_wireless_security_get_key_mgmt(setting); - key_mgmt_conf = g_string_new(key_mgmt); - if (nm_streq(key_mgmt, "wpa-psk")) { - if (_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF)) - 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"); + key_mgmt_conf = g_string_new(""); + if (nm_streq(key_mgmt, "none")) { + g_string_append(key_mgmt_conf, "NONE"); + + } else if (nm_streq(key_mgmt, "ieee8021x")) { + g_string_append(key_mgmt_conf, "IEEE8021X"); + + } else if (nm_streq(key_mgmt, "owe")) { + g_string_append(key_mgmt_conf, "OWE"); + + } else if (nm_streq(key_mgmt, "wpa-psk")) { + g_string_append(key_mgmt_conf, "WPA-PSK"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF)) + 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, "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")) { + g_string_append(key_mgmt_conf, "WPA-EAP"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) { + g_string_append(key_mgmt_conf, " FT-EAP"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_SHA384)) + g_string_append(key_mgmt_conf, " FT-EAP-SHA384"); + } + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF)) { + g_string_append(key_mgmt_conf, " WPA-EAP-SHA256"); if (_get_capability(priv, NM_SUPPL_CAP_TYPE_SUITEB192) && pmf == NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) - g_string_append(key_mgmt_conf, " wpa-eap-suite-b-192"); + g_string_append(key_mgmt_conf, " WPA-EAP-SUITE-B-192"); } - if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) - g_string_append(key_mgmt_conf, " ft-eap"); - if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT) - && _get_capability(priv, NM_SUPPL_CAP_TYPE_SHA384)) - g_string_append(key_mgmt_conf, " ft-eap-sha384"); + switch (fils) { case NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED: g_string_truncate(key_mgmt_conf, 0); if (!_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF)) - g_string_assign(key_mgmt_conf, "fils-sha256 fils-sha384"); + g_string_assign(key_mgmt_conf, "FILS-SHA256 FILS-SHA384"); /* fall-through */ case NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL: - if (_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF)) - g_string_append(key_mgmt_conf, " fils-sha256 fils-sha384"); - if (_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF) - && _get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) - g_string_append(key_mgmt_conf, " ft-fils-sha256"); - if (_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF) - && _get_capability(priv, NM_SUPPL_CAP_TYPE_FT) - && _get_capability(priv, NM_SUPPL_CAP_TYPE_SHA384)) - g_string_append(key_mgmt_conf, " ft-fils-sha384"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF)) { + g_string_append(key_mgmt_conf, " FILS-SHA256 FILS-SHA384"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) { + g_string_append(key_mgmt_conf, " FT-FILS-SHA256"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_SHA384)) + g_string_append(key_mgmt_conf, " FT-FILS-SHA384"); + } + } break; + default: break; } - } else if (nm_streq(key_mgmt, "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-suite-b-192")) { pmf = NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED; + + g_string_append(key_mgmt_conf, "WPA-EAP-SUITE-B-192"); } if (!add_string_val(self, key_mgmt_conf->str, "key_mgmt", TRUE, NULL, error)) From e06f9508d1752ed9929b0c7e1092928cdc7a8095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Fri, 23 Apr 2021 14:00:48 +0200 Subject: [PATCH 2/8] libnm-core: Rewrite comment of key-mgmt property The key-mgmt property of NMSettingWirelessSecurity is slightly confusing when you know there's also a wpa_supplicant configuration option called "key_mgmt". Our property is not the same as that supplicant option even though they do have things in common. NMs key-mgmt is not exactly meant to configure which AKM suites you want to use, but rather which method of wifi security is being used (so "wpa2+wpa3 personal", "wpa3 personal only" or "wpa3 enterprise only"). Try to make this a bit clearer in the documentation of the property by rewriting it and listing those security methods. --- src/libnm-core-impl/nm-setting-wireless-security.c | 14 ++++++++------ src/libnmc-setting/settings-docs.h.in | 2 +- src/nmcli/generate-docs-nm-settings-nmcli.xml.in | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libnm-core-impl/nm-setting-wireless-security.c b/src/libnm-core-impl/nm-setting-wireless-security.c index 47a9ca3286..64fce089a7 100644 --- a/src/libnm-core-impl/nm-setting-wireless-security.c +++ b/src/libnm-core-impl/nm-setting-wireless-security.c @@ -1498,17 +1498,19 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass) /** * NMSettingWirelessSecurity:key-mgmt: * - * Key management used for the connection. One of "none" (WEP), - * "ieee8021x" (Dynamic WEP), "wpa-psk" (infrastructure WPA-PSK), "sae" - * (SAE), "owe" (Opportunistic Wireless Encryption), "wpa-eap" - * (WPA-Enterprise) or "wpa-eap-suite-b-192" (WPA3-Enterprise Suite B). + * Key management used for the connection. One of "none" (WEP or no + * password protection), "ieee8021x" (Dynamic WEP), "owe" (Opportunistic + * Wireless Encryption), "wpa-psk" (WPA2 + WPA3 personal), "sae" (WPA3 + * personal only), "wpa-eap" (WPA2 + WPA3 enterprise) or + * "wpa-eap-suite-b-192" (WPA3 enterprise only). + * * This property must be set for any Wi-Fi connection that uses security. **/ /* ---ifcfg-rh--- * property: key-mgmt * variable: KEY_MGMT(+) - * values: IEEE8021X, WPA-PSK, WPA-EAP, WPA-EAP-SUITE-B-192 - * description: Key management menthod. + * values: none, ieee8021x, owe, wpa-psk, sae, wpa-eap, wpa-eap-suite-b-192 + * description: Key management method. * ---end--- */ obj_properties[PROP_KEY_MGMT] = diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in index f9bc6573a2..1a6e698be5 100644 --- a/src/libnmc-setting/settings-docs.h.in +++ b/src/libnmc-setting/settings-docs.h.in @@ -25,7 +25,7 @@ #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_AUTH_ALG N_("When WEP is used (ie, key-mgmt = \"none\" or \"ieee8021x\") indicate the 802.11 authentication algorithm required by the AP here. One of \"open\" for Open System, \"shared\" for Shared Key, or \"leap\" for Cisco LEAP. When using Cisco LEAP (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\") the \"leap-username\" and \"leap-password\" properties must be specified.") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_FILS N_("Indicates whether Fast Initial Link Setup (802.11ai) must be enabled for the connection. One of NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (0) (use global default value), NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE (1) (disable FILS), NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL (2) (enable FILS if the supplicant and the access point support it) or NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED (3) (enable FILS and fail if not supported). When set to NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (0) and no global default is set, FILS will be optionally enabled.") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_GROUP N_("A list of group/broadcast encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of \"wep40\", \"wep104\", \"tkip\", or \"ccmp\".") -#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_KEY_MGMT N_("Key management used for the connection. One of \"none\" (WEP), \"ieee8021x\" (Dynamic WEP), \"wpa-psk\" (infrastructure WPA-PSK), \"sae\" (SAE), \"owe\" (Opportunistic Wireless Encryption), \"wpa-eap\" (WPA-Enterprise) or \"wpa-eap-suite-b-192\" (WPA3-Enterprise Suite B). This property must be set for any Wi-Fi connection that uses security.") +#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_KEY_MGMT N_("Key management used for the connection. One of \"none\" (WEP or no password protection), \"ieee8021x\" (Dynamic WEP), \"owe\" (Opportunistic Wireless Encryption), \"wpa-psk\" (WPA2 + WPA3 personal), \"sae\" (WPA3 personal only), \"wpa-eap\" (WPA2 + WPA3 enterprise) or \"wpa-eap-suite-b-192\" (WPA3 enterprise only). This property must be set for any Wi-Fi connection that uses security.") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD N_("The login password for legacy LEAP connections (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\").") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS N_("Flags indicating how to handle the \"leap-password\" property.") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME N_("The login username for legacy LEAP connections (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\").") diff --git a/src/nmcli/generate-docs-nm-settings-nmcli.xml.in b/src/nmcli/generate-docs-nm-settings-nmcli.xml.in index 17332eb0a8..df722c1dd4 100644 --- a/src/nmcli/generate-docs-nm-settings-nmcli.xml.in +++ b/src/nmcli/generate-docs-nm-settings-nmcli.xml.in @@ -63,7 +63,7 @@ + description="Key management used for the connection. One of "none" (WEP or no password protection), "ieee8021x" (Dynamic WEP), "owe" (Opportunistic Wireless Encryption), "wpa-psk" (WPA2 + WPA3 personal), "sae" (WPA3 personal only), "wpa-eap" (WPA2 + WPA3 enterprise) or "wpa-eap-suite-b-192" (WPA3 enterprise only). This property must be set for any Wi-Fi connection that uses security." /> Date: Fri, 23 Apr 2021 17:06:36 +0200 Subject: [PATCH 3/8] supplicant/config: Require pmf for owe, sae and wpa-eap-suite-b-192 When using modern WPA3 encryption like owe, sae or wpa-eap-suite-b-192 without fallbacks (so not WPA3+WPA2), protected management frames are required to be enabled by the specification. For wpa-eap-suite-b-192 we already do this and force PMF to REQUIRED, we should also do it for OWE and SAE. --- src/core/supplicant/nm-supplicant-config.c | 4 +++ .../supplicant/tests/test-supplicant-config.c | 34 +++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c index 494274ae33..16fdd1eb8d 100644 --- a/src/core/supplicant/nm-supplicant-config.c +++ b/src/core/supplicant/nm-supplicant-config.c @@ -843,6 +843,8 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig * g_string_append(key_mgmt_conf, "IEEE8021X"); } else if (nm_streq(key_mgmt, "owe")) { + pmf = NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED; + g_string_append(key_mgmt_conf, "OWE"); } else if (nm_streq(key_mgmt, "wpa-psk")) { @@ -858,6 +860,8 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig * } } else if (nm_streq(key_mgmt, "sae")) { + pmf = NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED; + g_string_append(key_mgmt_conf, "SAE"); if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) g_string_append(key_mgmt_conf, " FT-SAE"); diff --git a/src/core/supplicant/tests/test-supplicant-config.c b/src/core/supplicant/tests/test-supplicant-config.c index 3525f99962..0cf35d0e5d 100644 --- a/src/core/supplicant/tests/test-supplicant-config.c +++ b/src/core/supplicant/tests/test-supplicant-config.c @@ -394,7 +394,17 @@ test_wifi_wpa_psk(const char * detail, NMTST_EXPECT_NM_INFO("Config: added 'scan_ssid' value '1'*"); NMTST_EXPECT_NM_INFO("Config: added 'bssid' value '11:22:33:44:55:66'*"); NMTST_EXPECT_NM_INFO("Config: added 'freq_list' value *"); - NMTST_EXPECT_NM_INFO("Config: added 'key_mgmt' value 'WPA-PSK WPA-PSK-SHA256'"); + switch (pmf) { + case NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE: + case NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL: + NMTST_EXPECT_NM_INFO("Config: added 'key_mgmt' value 'WPA-PSK WPA-PSK-SHA256'"); + break; + case NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED: + NMTST_EXPECT_NM_INFO("Config: added 'key_mgmt' value ' WPA-PSK-SHA256'"); + break; + default: + break; + } NMTST_EXPECT_NM_INFO("Config: added 'psk' value *"); NMTST_EXPECT_NM_INFO("Config: added 'proto' value 'WPA RSN'"); NMTST_EXPECT_NM_INFO("Config: added 'pairwise' value 'TKIP CCMP'"); @@ -421,11 +431,22 @@ test_wifi_wpa_psk(const char * detail, validate_opt(detail, config_dict, "scan_ssid", NM_SUPPL_OPT_TYPE_INT, GINT_TO_POINTER(1)); validate_opt(detail, config_dict, "ssid", NM_SUPPL_OPT_TYPE_BYTES, ssid); validate_opt(detail, config_dict, "bssid", NM_SUPPL_OPT_TYPE_KEYWORD, bssid_str); - validate_opt(detail, - config_dict, - "key_mgmt", - NM_SUPPL_OPT_TYPE_KEYWORD, - "WPA-PSK WPA-PSK-SHA256"); + switch (pmf) { + case NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE: + case NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL: + validate_opt(detail, + config_dict, + "key_mgmt", + NM_SUPPL_OPT_TYPE_KEYWORD, + "WPA-PSK WPA-PSK-SHA256"); + break; + case NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED: + validate_opt(detail, config_dict, "key_mgmt", NM_SUPPL_OPT_TYPE_KEYWORD, " WPA-PSK-SHA256"); + break; + default: + break; + } + validate_opt(detail, config_dict, "proto", NM_SUPPL_OPT_TYPE_KEYWORD, "WPA RSN"); validate_opt(detail, config_dict, "pairwise", NM_SUPPL_OPT_TYPE_KEYWORD, "TKIP CCMP"); validate_opt(detail, config_dict, "group", NM_SUPPL_OPT_TYPE_KEYWORD, "TKIP CCMP"); @@ -483,6 +504,7 @@ test_wifi_sae_psk(const char *psk) NMTST_EXPECT_NM_INFO("Config: added 'proto' value 'RSN'"); NMTST_EXPECT_NM_INFO("Config: added 'pairwise' value 'TKIP CCMP'"); NMTST_EXPECT_NM_INFO("Config: added 'group' value 'TKIP CCMP'"); + NMTST_EXPECT_NM_INFO("Config: added 'ieee80211w' value '2'"); config_dict = build_supplicant_config(connection, 1500, From a4b95a9fcd85cd79d1cf1f6cd3235b1072d728d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Fri, 23 Apr 2021 16:39:44 +0200 Subject: [PATCH 4/8] libnm-core: Don't allow disabling PMF when using WPA3 key management Modern WPA3 authentication methods like SAE and WPA-EAP-SUITE-B-192 need to have management frame protection set to required according to the standard. Since the last commit, we enforce this automatically when key-mgmt is set to 'owe', 'sae' or 'wpa-eap-suite-b-192', so disabling it manually should not be possible. Add a check to the pmf property that makes sure it can't be set to 'disabled' or 'optional' when one of those key-mgmt methods is used. --- .../nm-setting-wireless-security.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libnm-core-impl/nm-setting-wireless-security.c b/src/libnm-core-impl/nm-setting-wireless-security.c index 64fce089a7..f085f2c33a 100644 --- a/src/libnm-core-impl/nm-setting-wireless-security.c +++ b/src/libnm-core-impl/nm-setting-wireless-security.c @@ -1117,6 +1117,22 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if (NM_IN_STRSET(priv->key_mgmt, "owe", "sae", "wpa-eap-suite-b-192") + && !NM_IN_SET(priv->pmf, + NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT, + NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("pmf can only be 'default' or 'required' when using 'owe', 'sae' or " + "'wpa-eap-suite-b-192' key management")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PMF); + return FALSE; + } + if (!_nm_utils_wps_method_validate(priv->wps_method, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WPS_METHOD, From 2bc3cf0cb81e30bf8d485d8293c19d8694937fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Fri, 23 Apr 2021 18:04:36 +0200 Subject: [PATCH 5/8] supplicant/config: Disallow SHA1 ciphers when using required PMF As mentioned in the wpa_supplicant reference config, when setting PMF to required with WPA2 (personal or enterprise) authentication, we want to only enable SHA256 and upwards as HMAC. So enforce that by not passing WPA-PSK and WPA-EAP to the config in case pmf is set to REQUIRED. --- src/core/supplicant/nm-supplicant-config.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c index 16fdd1eb8d..40efc6c593 100644 --- a/src/core/supplicant/nm-supplicant-config.c +++ b/src/core/supplicant/nm-supplicant-config.c @@ -848,7 +848,8 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig * g_string_append(key_mgmt_conf, "OWE"); } else if (nm_streq(key_mgmt, "wpa-psk")) { - g_string_append(key_mgmt_conf, "WPA-PSK"); + if (pmf != NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) + g_string_append(key_mgmt_conf, "WPA-PSK"); if (_get_capability(priv, NM_SUPPL_CAP_TYPE_PMF)) g_string_append(key_mgmt_conf, " WPA-PSK-SHA256"); if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) @@ -867,7 +868,8 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig * g_string_append(key_mgmt_conf, " FT-SAE"); } else if (nm_streq(key_mgmt, "wpa-eap")) { - g_string_append(key_mgmt_conf, "WPA-EAP"); + if (pmf != NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) + g_string_append(key_mgmt_conf, "WPA-EAP"); if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) { g_string_append(key_mgmt_conf, " FT-EAP"); if (_get_capability(priv, NM_SUPPL_CAP_TYPE_SHA384)) From 60c2f6c596988e54e7c17a7b32a25ca049a025be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Fri, 23 Apr 2021 18:10:00 +0200 Subject: [PATCH 6/8] supplicant/config: Allow using FT ciphers with WPA-EAP-SUITE-B-192 According to [1], the only suitable FT cipher suite for WPA3 Enterprise 192-bit mode is "FT over 802.1X, SHA-384", so enable that in case of key-mgmt is WPA-EAP-SUITE-B-192 to support FT in that case too. [1] https://mrncciew.com/2020/08/17/wpa3-enterprise/ --- src/core/supplicant/nm-supplicant-config.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c index 40efc6c593..1a75819cc3 100644 --- a/src/core/supplicant/nm-supplicant-config.c +++ b/src/core/supplicant/nm-supplicant-config.c @@ -907,6 +907,9 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig * pmf = NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED; g_string_append(key_mgmt_conf, "WPA-EAP-SUITE-B-192"); + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT) + && _get_capability(priv, NM_SUPPL_CAP_TYPE_SHA384)) + g_string_append(key_mgmt_conf, " FT-EAP-SHA384"); } if (!add_string_val(self, key_mgmt_conf->str, "key_mgmt", TRUE, NULL, error)) From e01913203389c5cc5e27f11537684c1cc6bc5e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Fri, 23 Apr 2021 18:45:32 +0200 Subject: [PATCH 7/8] supplicant/interface: Match more ciphers to determine AP security There can also be APs which don't do wpa-psk, but do support wpa-psk-sha256, so we should match all AKM suites the AP offers to determine the security type we want to assign it. --- src/core/supplicant/nm-supplicant-interface.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/core/supplicant/nm-supplicant-interface.c b/src/core/supplicant/nm-supplicant-interface.c index 168dd39c8d..bbd7288e81 100644 --- a/src/core/supplicant/nm-supplicant-interface.c +++ b/src/core/supplicant/nm-supplicant-interface.c @@ -271,17 +271,21 @@ security_from_vardict(GVariant *security) nm_assert(g_variant_is_of_type(security, G_VARIANT_TYPE_VARDICT)); if (g_variant_lookup(security, "KeyMgmt", "^a&s", &array)) { - if (g_strv_contains(array, "wpa-psk") || g_strv_contains(array, "wpa-ft-psk")) + if (g_strv_contains(array, "wpa-psk") || g_strv_contains(array, "wpa-psk-sha256") + || g_strv_contains(array, "wpa-ft-psk")) flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK; - if (g_strv_contains(array, "wpa-eap") || g_strv_contains(array, "wpa-ft-eap") - || g_strv_contains(array, "wpa-fils-sha256") - || g_strv_contains(array, "wpa-fils-sha384")) + if (g_strv_contains(array, "wpa-eap") || g_strv_contains(array, "wpa-eap-sha256") + || g_strv_contains(array, "wpa-ft-eap") || g_strv_contains(array, "wpa-fils-sha256") + || g_strv_contains(array, "wpa-fils-sha384") + || g_strv_contains(array, "wpa-fils-ft-sha256") + || g_strv_contains(array, "wpa-fils-ft-sha384")) flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X; - if (g_strv_contains(array, "sae")) + if (g_strv_contains(array, "sae") || g_strv_contains(array, "ft-sae")) flags |= NM_802_11_AP_SEC_KEY_MGMT_SAE; if (g_strv_contains(array, "owe")) flags |= NM_802_11_AP_SEC_KEY_MGMT_OWE; - if (g_strv_contains(array, "wpa-eap-suite-b-192")) + if (g_strv_contains(array, "wpa-eap-suite-b-192") + || g_strv_contains(array, "wpa-ft-eap-sha384")) flags |= NM_802_11_AP_SEC_KEY_MGMT_EAP_SUITE_B_192; g_free(array); } From 0e30a5256cd8e36e9a2200bbf470257d6971c0a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Sat, 24 Apr 2021 11:18:12 +0200 Subject: [PATCH 8/8] devices/wifi: Use wpa-psk key-mgmt for networks supporting WPA2 and WPA3 Networks offering WPA2 and WPA3/SAE at the same time are in WPA3 hybrid mode. In this case the PSK passphrase rules that apply need to be the WPA2 rules, so we shouldn't use "sae" as key-mgmt. Also our wifi card might not support SAE and we want to make sure WPA2 eventually gets used in that case. So use "wpa-psk" as key-mgmt method in case an AP is in WPA3 hybrid mode. --- src/core/devices/wifi/nm-wifi-utils.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/core/devices/wifi/nm-wifi-utils.c b/src/core/devices/wifi/nm-wifi-utils.c index d9cf5df20b..a8209c36bb 100644 --- a/src/core/devices/wifi/nm-wifi-utils.c +++ b/src/core/devices/wifi/nm-wifi-utils.c @@ -814,15 +814,24 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, * setting. Since there's so much configuration required for it, there's * no way it can be automatically completed. */ - } else if ((key_mgmt && !strcmp(key_mgmt, "sae")) - || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE)) { + } else if (nm_streq0(key_mgmt, "wpa-psk") + || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE + && (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK + || ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK))) { + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", + NULL); + } else if (nm_streq0(key_mgmt, "sae") || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE)) { g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL); - } else if ((key_mgmt && !strcmp(key_mgmt, "owe")) + } else if (nm_streq0(key_mgmt, "owe") || NM_FLAGS_ANY(ap_rsn_flags, NM_802_11_AP_SEC_KEY_MGMT_OWE | NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) { g_object_set(s_wsec, @@ -831,9 +840,8 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL); - } else if ((key_mgmt && !strcmp(key_mgmt, "wpa-psk")) - || (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) - || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { + } else if (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK + || ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) { g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", @@ -843,7 +851,7 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, /* Leave proto/pairwise/group as client set them; if they are unset the * supplicant will figure out the best combination at connect time. */ - } else if ((key_mgmt && !strcmp(key_mgmt, "wpa-eap-suite-b-192")) + } else if (nm_streq0(key_mgmt, "wpa-eap-suite-b-192") || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_EAP_SUITE_B_192)) { g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,