diff options
Diffstat (limited to 'src/core/supplicant')
| -rw-r--r-- | src/core/supplicant/nm-supplicant-config.c | 51 | ||||
| -rw-r--r-- | src/core/supplicant/nm-supplicant-config.h | 1 | ||||
| -rw-r--r-- | src/core/supplicant/nm-supplicant-interface.c | 28 | ||||
| -rw-r--r-- | src/core/supplicant/nm-supplicant-manager.c | 9 | ||||
| -rw-r--r-- | src/core/supplicant/nm-supplicant-types.h | 6 | ||||
| -rw-r--r-- | src/core/supplicant/tests/test-supplicant-config.c | 1 |
6 files changed, 86 insertions, 10 deletions
diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c index 96c23579..a4e5cc4d 100644 --- a/src/core/supplicant/nm-supplicant-config.c +++ b/src/core/supplicant/nm-supplicant-config.c @@ -805,6 +805,7 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig NMSettingWirelessSecurity *setting, NMSetting8021x *setting_8021x, const char *con_uuid, + const char *mode, guint32 mtu, NMSettingWirelessSecurityPmf pmf, NMSettingWirelessSecurityFils fils, @@ -815,12 +816,20 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig const char *key_mgmt, *auth_alg; const char *psk; gboolean set_pmf, wps_disabled; + gboolean is_ap; g_return_val_if_fail(NM_IS_SUPPLICANT_CONFIG(self), FALSE); g_return_val_if_fail(setting != NULL, FALSE); g_return_val_if_fail(con_uuid != NULL, FALSE); g_return_val_if_fail(!error || !*error, FALSE); + /* Currently wpa_supplicant doesn't support FT in AP mode. Even + * if it did, it would require additional parameters as the nas + * identifier and the mobility domain. Therefore we disable all + * FT key-mgmts in AP mode. + */ + is_ap = nm_streq0(mode, NM_SETTING_WIRELESS_MODE_AP); + /* Check if we actually support FILS */ if (!_get_capability(priv, NM_SUPPL_CAP_TYPE_FILS)) { if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED) { @@ -852,11 +861,39 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig 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)) + if (!is_ap && _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)) { + + /* For NM "key-mgmt=wpa-psk" doesn't strictly mean WPA1/wPA2 only, + * but also allows WPA3 (SAE), so that existing connections can + * benefit from the improved security when the AP gets upgraded. + * + * According to WPA3_Specification_v3.0 section 2.3, when operating + * in WPA3-Personal transition mode a STA: + * + * - should allow AKM suite selector: 00-0F-AC:6 (WPA-PSK-SHA256) to + * be selected for an association; + * - shall negotiate PMF when associating to an AP using SAE. + * + * Those conditions are met when the interface has capabilities + * SAE, PMF, BIP. + * + * According to WPA3_Specification_v3.0 section 2.3, when operating + * in WPA3-Personal transition mode an AP: + * + * - shall set MFPC to 1, MFPR to 0. + * + * Therefore, do not operate in WPA3-Personal transition mode when PMF + * is set to disabled. This also provides a way to be compatible with + * some devices that are not fully compatible with WPA3-Personal + * transition mode. + */ + if (_get_capability(priv, NM_SUPPL_CAP_TYPE_SAE) + && _get_capability(priv, NM_SUPPL_CAP_TYPE_PMF) + && _get_capability(priv, NM_SUPPL_CAP_TYPE_BIP) + && (!is_ap || pmf != NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE)) { g_string_append(key_mgmt_conf, " SAE"); - if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) + if (!is_ap && _get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) g_string_append(key_mgmt_conf, " FT-SAE"); } @@ -864,13 +901,13 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig pmf = NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED; g_string_append(key_mgmt_conf, "SAE"); - if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) + if (!is_ap && _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 (pmf != NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) g_string_append(key_mgmt_conf, "WPA-EAP"); - if (_get_capability(priv, NM_SUPPL_CAP_TYPE_FT)) { + if (!is_ap && _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"); @@ -891,7 +928,7 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig 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_FT)) { + if (!is_ap && _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"); @@ -907,7 +944,7 @@ 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) + if (!is_ap && _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"); } diff --git a/src/core/supplicant/nm-supplicant-config.h b/src/core/supplicant/nm-supplicant-config.h index 349c310f..ee7f4dc8 100644 --- a/src/core/supplicant/nm-supplicant-config.h +++ b/src/core/supplicant/nm-supplicant-config.h @@ -51,6 +51,7 @@ gboolean nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig NMSettingWirelessSecurity *setting, NMSetting8021x *setting_8021x, const char *con_uuid, + const char *mode, guint32 mtu, NMSettingWirelessSecurityPmf pmf, NMSettingWirelessSecurityFils fils, diff --git a/src/core/supplicant/nm-supplicant-interface.c b/src/core/supplicant/nm-supplicant-interface.c index d8276144..e502ae85 100644 --- a/src/core/supplicant/nm-supplicant-interface.c +++ b/src/core/supplicant/nm-supplicant-interface.c @@ -1225,8 +1225,10 @@ parse_capabilities(NMSupplicantInterface *self, GVariant *capabilities) const guint32 old_max_scan_ssids = priv->max_scan_ssids; gboolean have_ft = FALSE; gboolean have_sae = FALSE; + gboolean have_bip = FALSE; gint32 max_scan_ssids; const char **array; + guint i; nm_assert(capabilities && g_variant_is_of_type(capabilities, G_VARIANT_TYPE_VARDICT)); @@ -1236,12 +1238,28 @@ parse_capabilities(NMSupplicantInterface *self, GVariant *capabilities) g_free(array); } + if (g_variant_lookup(capabilities, "GroupMgmt", "^a&s", &array)) { + for (i = 0; array[i]; i++) { + if (NM_IN_STRSET(array[i], + "aes-128-cmac", + "bip-gmac-128", + "bip-gmac-256", + "bip-cmac-256")) { + have_bip = TRUE; + break; + } + } + } + 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); + priv->iface_capabilities = NM_SUPPL_CAP_MASK_SET(priv->iface_capabilities, + NM_SUPPL_CAP_TYPE_BIP, + have_bip ? 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, @@ -1317,10 +1335,12 @@ _starting_check_ready(NMSupplicantInterface *self) " AP%c" " FT%c" " SAE%c" + " BIP%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)); + NM_SUPPL_CAP_TO_CHAR(priv->iface_capabilities, NM_SUPPL_CAP_TYPE_SAE), + NM_SUPPL_CAP_TO_CHAR(priv->iface_capabilities, NM_SUPPL_CAP_TYPE_BIP)); /* Other global properties are set in constructed() because they don't * depend on interface capabilities. */ @@ -1362,6 +1382,7 @@ _get_capability(NMSupplicantInterfacePrivate *priv, NMSupplCapType type) } break; case NM_SUPPL_CAP_TYPE_SAE: + case NM_SUPPL_CAP_TYPE_BIP: 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; @@ -1395,10 +1416,13 @@ nm_supplicant_interface_get_capabilities(NMSupplicantInterface *self) caps = NM_SUPPL_CAP_MASK_SET(caps, NM_SUPPL_CAP_TYPE_SAE, _get_capability(priv, NM_SUPPL_CAP_TYPE_SAE)); + caps = NM_SUPPL_CAP_MASK_SET(caps, + NM_SUPPL_CAP_TYPE_BIP, + _get_capability(priv, NM_SUPPL_CAP_TYPE_BIP)); 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_SAE_MASK))); + | NM_SUPPL_CAP_MASK_T_SAE_MASK | NM_SUPPL_CAP_MASK_T_BIP_MASK))); #if NM_MORE_ASSERTS > 10 { diff --git a/src/core/supplicant/nm-supplicant-manager.c b/src/core/supplicant/nm-supplicant-manager.c index 9de845f0..2ec7db23 100644 --- a/src/core/supplicant/nm-supplicant-manager.c +++ b/src/core/supplicant/nm-supplicant-manager.c @@ -920,6 +920,7 @@ _dbus_get_capabilities_cb(GVariant *res, GError *error, gpointer user_data) _caps_set(priv, NM_SUPPL_CAP_TYPE_PMF, NM_TERNARY_FALSE); _caps_set(priv, NM_SUPPL_CAP_TYPE_FILS, NM_TERNARY_FALSE); _caps_set(priv, NM_SUPPL_CAP_TYPE_SUITEB192, NM_TERNARY_FALSE); + _caps_set(priv, NM_SUPPL_CAP_TYPE_WEP, NM_TERNARY_TRUE); if (array) { for (a = array; *a; a++) { if (nm_streq(*a, "ap")) { @@ -954,6 +955,10 @@ _dbus_get_capabilities_cb(GVariant *res, GError *error, gpointer user_data) _caps_set(priv, NM_SUPPL_CAP_TYPE_SUITEB192, NM_TERNARY_TRUE); continue; } + if (nm_streq(*a, "wep_disabled")) { + _caps_set(priv, NM_SUPPL_CAP_TYPE_WEP, NM_TERNARY_FALSE); + continue; + } } } } @@ -994,6 +999,7 @@ _dbus_get_capabilities_cb(GVariant *res, GError *error, gpointer user_data) " FAST%c" " WFD%c" " SUITEB192%c" + " WEP%c" "", NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_AP), NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_PMF), @@ -1004,7 +1010,8 @@ _dbus_get_capabilities_cb(GVariant *res, GError *error, gpointer user_data) 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_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_SUITEB192)); + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_SUITEB192), + NM_SUPPL_CAP_TO_CHAR(priv->capabilities, NM_SUPPL_CAP_TYPE_WEP)); 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 d5cf1bf7..1ae67e13 100644 --- a/src/core/supplicant/nm-supplicant-types.h +++ b/src/core/supplicant/nm-supplicant-types.h @@ -48,6 +48,10 @@ typedef enum { NM_SUPPL_CAP_TYPE_FAST, NM_SUPPL_CAP_TYPE_WFD, NM_SUPPL_CAP_TYPE_SUITEB192, + NM_SUPPL_CAP_TYPE_WEP, + NM_SUPPL_CAP_TYPE_BIP, + /* Note: if you're adding a capability here, log its presence at the + * bottom of _dbus_get_capabilities_cb(). */ _NM_SUPPL_CAP_TYPE_NUM, } NMSupplCapType; @@ -75,6 +79,8 @@ typedef enum { _NM_SUPPL_CAP_MASK_DEFINE(FT), _NM_SUPPL_CAP_MASK_DEFINE(SAE), _NM_SUPPL_CAP_MASK_DEFINE(SHA384), + _NM_SUPPL_CAP_MASK_DEFINE(WEP), + _NM_SUPPL_CAP_MASK_DEFINE(BIP), #undef _NM_SUPPL_CAP_MASK_DEFINE } NMSupplCapMask; diff --git a/src/core/supplicant/tests/test-supplicant-config.c b/src/core/supplicant/tests/test-supplicant-config.c index 53c5f70f..237b1a96 100644 --- a/src/core/supplicant/tests/test-supplicant-config.c +++ b/src/core/supplicant/tests/test-supplicant-config.c @@ -116,6 +116,7 @@ build_supplicant_config(NMConnection *connection, s_wsec, s_8021x, nm_connection_get_uuid(connection), + nm_setting_wireless_get_mode(s_wifi), mtu, pmf, fils, |