wifi: enable WPA-*-SHA256 AKMs only when the supplicant supports them

Commit 87ec5e90fe ("supplicant: set key_mgmt independent of pmf
value") enabled WPA-PSK-SHA256 or WPA-EAP-SHA256 even when the
supplicant didn't support them, potentially causing connection
failures.  Instead, use the 'pmf' capability to detect when they can
be enabled.

Fixes: 87ec5e90fe

https://mail.gnome.org/archives/networkmanager-list/2018-January/msg00096.html
This commit is contained in:
Beniamino Galvani 2018-01-17 18:06:54 +01:00 committed by Thomas Haller
parent dd2d55ca57
commit a0cf466482
6 changed files with 68 additions and 59 deletions

View file

@ -550,7 +550,7 @@ build_supplicant_config (NMDeviceEthernet *self,
mtu = nm_platform_link_get_mtu (nm_device_get_platform (NM_DEVICE (self)),
nm_device_get_ifindex (NM_DEVICE (self)));
config = nm_supplicant_config_new ();
config = nm_supplicant_config_new (FALSE, FALSE);
security = nm_connection_get_setting_802_1x (connection);
if (!nm_supplicant_config_add_setting_8021x (config, security, con_uuid, mtu, TRUE, error)) {

View file

@ -222,7 +222,7 @@ build_supplicant_config (NMDeviceMacsec *self, GError **error)
mtu = nm_platform_link_get_mtu (nm_device_get_platform (NM_DEVICE (self)),
nm_device_get_ifindex (NM_DEVICE (self)));
config = nm_supplicant_config_new ();
config = nm_supplicant_config_new (FALSE, FALSE);
s_macsec = (NMSettingMacsec *)
nm_device_get_applied_setting (NM_DEVICE (self), NM_TYPE_SETTING_MACSEC);

View file

@ -2389,7 +2389,9 @@ build_supplicant_config (NMDeviceWifi *self,
s_wireless = nm_connection_get_setting_wireless (connection);
g_return_val_if_fail (s_wireless != NULL, NULL);
config = nm_supplicant_config_new ();
config = nm_supplicant_config_new (
nm_supplicant_interface_get_pmf_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES,
nm_supplicant_interface_get_fils_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_YES);
/* Warn if AP mode may not be supported */
if ( g_strcmp0 (nm_setting_wireless_get_mode (s_wireless), NM_SETTING_WIRELESS_MODE_AP) == 0
@ -2431,26 +2433,6 @@ build_supplicant_config (NMDeviceWifi *self,
NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL);
}
/* Don't try to enable PMF on non-WPA networks */
if (!NM_IN_STRSET (nm_setting_wireless_security_get_key_mgmt (s_wireless_sec),
"wpa-eap",
"wpa-psk"))
pmf = NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE;
/* Check if we actually support PMF */
if (nm_supplicant_interface_get_pmf_support (priv->sup_iface) != NM_SUPPLICANT_FEATURE_YES) {
if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) {
g_set_error_literal (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
"Supplicant does not support PMF");
goto error;
} else if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL) {
/* To be on the safe side, assume no support if we can't determine
* capabilities.
*/
pmf = NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE;
}
}
/* Configure FILS (802.11ai) */
fils = nm_setting_wireless_security_get_fils (s_wireless_sec);
if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) {
@ -2463,24 +2445,6 @@ build_supplicant_config (NMDeviceWifi *self,
NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL);
}
/* Don't try to enable FILS on non-EAP networks */
if (!NM_IN_STRSET (nm_setting_wireless_security_get_key_mgmt (s_wireless_sec), "wpa-eap"))
fils = NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE;
/* Check if we actually support FILS */
if (nm_supplicant_interface_get_fils_support (priv->sup_iface) != NM_SUPPLICANT_FEATURE_YES) {
if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED) {
g_set_error_literal (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
"Supplicant does not support FILS");
goto error;
} else if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL) {
/* To be on the safe side, assume no support if we can't determine
* capabilities.
*/
fils = NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE;
}
}
s_8021x = nm_connection_get_setting_802_1x (connection);
if (!nm_supplicant_config_add_setting_wireless_security (config,
s_wireless_sec,

View file

@ -47,6 +47,8 @@ typedef struct {
guint32 ap_scan;
gboolean fast_required;
gboolean dispose_has_run;
gboolean support_pmf;
gboolean support_fils;
} NMSupplicantConfigPrivate;
struct _NMSupplicantConfig {
@ -65,9 +67,18 @@ G_DEFINE_TYPE (NMSupplicantConfig, nm_supplicant_config, G_TYPE_OBJECT)
/*****************************************************************************/
NMSupplicantConfig *
nm_supplicant_config_new (void)
nm_supplicant_config_new (gboolean support_pmf, gboolean support_fils)
{
return g_object_new (NM_TYPE_SUPPLICANT_CONFIG, NULL);
NMSupplicantConfigPrivate *priv;
NMSupplicantConfig *self;
self = g_object_new (NM_TYPE_SUPPLICANT_CONFIG, NULL);
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
priv->support_pmf = support_pmf;
priv->support_fils = support_fils;
return self;
}
static void
@ -736,6 +747,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
NMSettingWirelessSecurityFils fils,
GError **error)
{
NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
const char *key_mgmt, *key_mgmt_conf, *auth_alg;
const char *psk;
@ -744,21 +756,36 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
g_return_val_if_fail (con_uuid != NULL, FALSE);
g_return_val_if_fail (!error || !*error, FALSE);
/* Check if we actually support FILS */
if (!priv->support_fils) {
if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED) {
g_set_error_literal (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
"Supplicant does not support FILS");
return FALSE;
} else if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL)
fils = NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE;
}
key_mgmt = key_mgmt_conf = nm_setting_wireless_security_get_key_mgmt (setting);
if (nm_streq (key_mgmt, "wpa-psk"))
key_mgmt_conf = "wpa-psk wpa-psk-sha256";
else if (nm_streq (key_mgmt, "wpa-eap"))
if (nm_streq (key_mgmt, "wpa-psk")) {
if (priv->support_pmf)
key_mgmt_conf = "wpa-psk wpa-psk-sha256";
} else if (nm_streq (key_mgmt, "wpa-eap")) {
switch (fils) {
case NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL:
key_mgmt_conf = "wpa-eap wpa-eap-sha256 fils-sha256 fils-sha384";
key_mgmt_conf = priv->support_pmf
? "wpa-eap wpa-eap-sha256 fils-sha256 fils-sha384"
: "wpa-eap fils-sha256 fils-sha384";
break;
case NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED:
key_mgmt_conf = "fils-sha256 fils-sha384";
break;
default:
key_mgmt_conf = "wpa-eap wpa-eap-sha256";
if (priv->support_pmf)
key_mgmt_conf = "wpa-eap wpa-eap-sha256";
break;
}
}
if (!add_string_val (self, key_mgmt_conf, "key_mgmt", TRUE, NULL, error))
return FALSE;
@ -805,6 +832,20 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
}
}
/* Don't try to enable PMF on non-WPA networks */
if (!NM_IN_STRSET (key_mgmt, "wpa-eap", "wpa-psk"))
pmf = NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE;
/* Check if we actually support PMF */
if (!priv->support_pmf) {
if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) {
g_set_error_literal (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
"Supplicant does not support PMF");
return FALSE;
} else if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL)
pmf = NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE;
}
/* Only WPA-specific things when using WPA */
if ( !strcmp (key_mgmt, "wpa-none")
|| !strcmp (key_mgmt, "wpa-psk")

View file

@ -40,7 +40,7 @@ typedef struct _NMSupplicantConfigClass NMSupplicantConfigClass;
GType nm_supplicant_config_get_type (void);
NMSupplicantConfig *nm_supplicant_config_new (void);
NMSupplicantConfig *nm_supplicant_config_new (gboolean support_pmf, gboolean support_fils);
guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig *self);

View file

@ -95,7 +95,11 @@ validate_opt (const char *detail,
}
static GVariant *
build_supplicant_config (NMConnection *connection, guint mtu, guint fixed_freq)
build_supplicant_config (NMConnection *connection,
guint mtu,
guint fixed_freq,
gboolean support_pmf,
gboolean support_fils)
{
gs_unref_object NMSupplicantConfig *config = NULL;
gs_free_error GError *error = NULL;
@ -104,7 +108,7 @@ build_supplicant_config (NMConnection *connection, guint mtu, guint fixed_freq)
NMSetting8021x *s_8021x;
gboolean success;
config = nm_supplicant_config_new ();
config = nm_supplicant_config_new (support_pmf, support_fils);
s_wifi = nm_connection_get_setting_wireless (connection);
g_assert (s_wifi);
@ -205,7 +209,7 @@ test_wifi_open (void)
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 'NONE'");
config_dict = build_supplicant_config (connection, 1500, 0);
config_dict = build_supplicant_config (connection, 1500, 0, TRUE, TRUE);
g_test_assert_expected_messages ();
g_assert (config_dict);
@ -262,7 +266,7 @@ test_wifi_wep_key (const char *detail,
if (!test_bssid)
NMTST_EXPECT_NM_INFO ("Config: added 'bgscan' value 'simple:30:-80:86400'*");
config_dict = build_supplicant_config (connection, 1500, 0);
config_dict = build_supplicant_config (connection, 1500, 0, TRUE, TRUE);
g_test_assert_expected_messages ();
g_assert (config_dict);
@ -362,7 +366,7 @@ test_wifi_wpa_psk (const char *detail,
default:
break;
}
config_dict = build_supplicant_config (connection, 1500, 0);
config_dict = build_supplicant_config (connection, 1500, 0, TRUE, TRUE);
g_test_assert_expected_messages ();
g_assert (config_dict);
@ -456,7 +460,7 @@ test_wifi_eap_locked_bssid (void)
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-EAP WPA-EAP-SHA256 FILS-SHA256 FILS-SHA384'");
NMTST_EXPECT_NM_INFO ("Config: added 'key_mgmt' value 'WPA-EAP'");
NMTST_EXPECT_NM_INFO ("Config: added 'proto' value 'WPA RSN'");
NMTST_EXPECT_NM_INFO ("Config: added 'pairwise' value 'TKIP CCMP'");
NMTST_EXPECT_NM_INFO ("Config: added 'group' value 'TKIP CCMP'");
@ -465,14 +469,14 @@ test_wifi_eap_locked_bssid (void)
NMTST_EXPECT_NM_INFO ("Config: added 'ca_cert' value '*/test-ca-cert.pem'");
NMTST_EXPECT_NM_INFO ("Config: added 'private_key' value '*/test-cert.p12'");
NMTST_EXPECT_NM_INFO ("Config: added 'proactive_key_caching' value '1'");
config_dict = build_supplicant_config (connection, mtu, 0);
config_dict = build_supplicant_config (connection, mtu, 0, FALSE, FALSE);
g_test_assert_expected_messages ();
g_assert (config_dict);
validate_opt ("wifi-eap", config_dict, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1));
validate_opt ("wifi-eap", config_dict, "ssid", TYPE_BYTES, ssid);
validate_opt ("wifi-eap", config_dict, "bssid", TYPE_KEYWORD, bssid_str);
validate_opt ("wifi-eap", config_dict, "key_mgmt", TYPE_KEYWORD, "WPA-EAP WPA-EAP-SHA256 FILS-SHA256 FILS-SHA384");
validate_opt ("wifi-eap", config_dict, "key_mgmt", TYPE_KEYWORD, "WPA-EAP");
validate_opt ("wifi-eap", config_dict, "eap", TYPE_KEYWORD, "TLS");
validate_opt ("wifi-eap", config_dict, "proto", TYPE_KEYWORD, "WPA RSN");
validate_opt ("wifi-eap", config_dict, "pairwise", TYPE_KEYWORD, "TKIP CCMP");
@ -506,7 +510,7 @@ test_wifi_eap_unlocked_bssid (void)
NMTST_EXPECT_NM_INFO ("Config: added 'private_key' value '*/test-cert.p12'");
NMTST_EXPECT_NM_INFO ("Config: added 'proactive_key_caching' value '1'");
NMTST_EXPECT_NM_INFO ("Config: added 'bgscan' value 'simple:30:-65:300'");
config_dict = build_supplicant_config (connection, mtu, 0);
config_dict = build_supplicant_config (connection, mtu, 0, FALSE, TRUE);
g_test_assert_expected_messages ();
g_assert (config_dict);
@ -547,7 +551,7 @@ test_wifi_eap_fils_disabled (void)
NMTST_EXPECT_NM_INFO ("Config: added 'private_key' value '*/test-cert.p12'");
NMTST_EXPECT_NM_INFO ("Config: added 'proactive_key_caching' value '1'");
NMTST_EXPECT_NM_INFO ("Config: added 'bgscan' value 'simple:30:-65:300'");
config_dict = build_supplicant_config (connection, mtu, 0);
config_dict = build_supplicant_config (connection, mtu, 0, TRUE, TRUE);
g_test_assert_expected_messages ();
g_assert (config_dict);