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



Commit 87ec5e90fe79 ("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: 87ec5e90fe79fcb2ac315cf1604e757dcab60bb9
---

Hi,

this patch fixes regressions discovered after the merge of FILS
patches by our nightly CI that runs on CentOS where wpa_supplicant is
compiled without 802.11w support.

This patch fixes those regression. Comments welcome.

Thanks,
Beniamino


 src/devices/nm-device-ethernet.c              |  2 +-
 src/devices/nm-device-macsec.c                |  2 +-
 src/devices/wifi/nm-device-wifi.c             | 42 ++------------------
 src/supplicant/nm-supplicant-config.c         | 55 +++++++++++++++++++++++----
 src/supplicant/nm-supplicant-config.h         |  2 +-
 src/supplicant/tests/test-supplicant-config.c | 24 +++++++-----
 6 files changed, 68 insertions(+), 59 deletions(-)

diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index 54c8176f6..0e1ebcc6a 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -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)) {
diff --git a/src/devices/nm-device-macsec.c b/src/devices/nm-device-macsec.c
index 4f2cbcca0..8b51f8ce6 100644
--- a/src/devices/nm-device-macsec.c
+++ b/src/devices/nm-device-macsec.c
@@ -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);
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 979f309dd..a7283b63a 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -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,
diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c
index a2502bd7b..14f5cac82 100644
--- a/src/supplicant/nm-supplicant-config.c
+++ b/src/supplicant/nm-supplicant-config.c
@@ -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")
diff --git a/src/supplicant/nm-supplicant-config.h b/src/supplicant/nm-supplicant-config.h
index 39b8a9f2d..f6c845a3f 100644
--- a/src/supplicant/nm-supplicant-config.h
+++ b/src/supplicant/nm-supplicant-config.h
@@ -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);
 
diff --git a/src/supplicant/tests/test-supplicant-config.c b/src/supplicant/tests/test-supplicant-config.c
index 3f4304619..60ca52586 100644
--- a/src/supplicant/tests/test-supplicant-config.c
+++ b/src/supplicant/tests/test-supplicant-config.c
@@ -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);
 
-- 
2.14.3



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]