diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2017-04-28 09:59:34 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2017-04-28 09:59:34 +0200 |
commit | a7fdf09848070990710529946fff782fc60c1461 (patch) | |
tree | 244bc8ba5428a9b88e186a0493a1dbcd0977be2c | |
parent | 1f40bb13cf0789e31fb0206f954850a662b8f97c (diff) | |
parent | acb70d84f9cc58cb09e02d68d01660f6d5087b34 (diff) |
wifi: merge branch 'bg/wifi-pmf-bgo748367-pt2'
Per-connection configurable PMF (802.11w) support.
https://bugzilla.gnome.org/show_bug.cgi?id=748367
-rw-r--r-- | clients/common/nm-meta-setting-desc.c | 8 | ||||
-rw-r--r-- | clients/common/settings-docs.c.in | 1 | ||||
-rw-r--r-- | libnm-core/nm-setting-wireless-security.c | 79 | ||||
-rw-r--r-- | libnm-core/nm-setting-wireless-security.h | 22 | ||||
-rw-r--r-- | libnm/libnm.ver | 6 | ||||
-rw-r--r-- | man/NetworkManager.conf.xml | 5 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 36 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 20 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 11 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 1 | ||||
-rw-r--r-- | src/supplicant/nm-supplicant-config.c | 59 | ||||
-rw-r--r-- | src/supplicant/nm-supplicant-config.h | 1 | ||||
-rw-r--r-- | src/supplicant/nm-supplicant-interface.c | 54 | ||||
-rw-r--r-- | src/supplicant/nm-supplicant-interface.h | 1 | ||||
-rw-r--r-- | src/supplicant/nm-supplicant-settings-verify.c | 1 | ||||
-rw-r--r-- | src/supplicant/tests/test-supplicant-config.c | 10 |
16 files changed, 234 insertions, 81 deletions
diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 98a5c38cd9..6807735937 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -6926,6 +6926,14 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS_SECURITY[] = { .values_static = wifi_sec_valid_groups, ), ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_PMF, + .property_type = &_pt_gobject_enum, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + PROPERTY_TYP_DATA_SUBTYPE (gobject_enum, + .get_gtype = nm_setting_wireless_security_pmf_get_type, + ), + ), + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, .property_type = &_pt_gobject_string, ), diff --git a/clients/common/settings-docs.c.in b/clients/common/settings-docs.c.in index 0ebddc6185..5710ce73a5 100644 --- a/clients/common/settings-docs.c.in +++ b/clients/common/settings-docs.c.in @@ -29,6 +29,7 @@ #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\").") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_PAIRWISE N_("A list of pairwise 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 \"tkip\" or \"ccmp\".") +#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_PMF N_("Indicates whether Protected Management Frames (802.11w) must be enabled for the connection. One of NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT (0) (use global default value), NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE (1) (disable PMF), NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL (2) (enable PMF if the supplicant and the access point support it) or NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED (3) (enable PMF and fail if not supported). When set to NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT (0) and no global default is set, PMF will be optionally enabled.") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_PROTO N_("List of strings specifying the allowed WPA protocol versions to use. Each element may be one \"wpa\" (allow WPA) or \"rsn\" (allow WPA2/RSN). If not specified, both WPA and RSN connections are allowed.") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_PSK N_("Pre-Shared-Key for WPA networks. If the key is 64-characters long, it must contain only hexadecimal characters and is interpreted as a hexadecimal WPA key. Otherwise, the key must be between 8 and 63 ASCII characters (as specified in the 802.11i standard) and is interpreted as a WPA passphrase, and is hashed to derive the actual WPA-PSK used when connecting to the Wi-Fi network.") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS N_("Flags indicating how to handle the \"psk\" property.") diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c index 70bdf7541d..dd5e9b5a9f 100644 --- a/libnm-core/nm-setting-wireless-security.c +++ b/libnm-core/nm-setting-wireless-security.c @@ -65,6 +65,7 @@ typedef struct { GSList *proto; /* GSList of strings */ GSList *pairwise; /* GSList of strings */ GSList *group; /* GSList of strings */ + guint pmf; /* LEAP */ char *leap_username; @@ -93,6 +94,7 @@ enum { PROP_PROTO, PROP_PAIRWISE, PROP_GROUP, + PROP_PMF, PROP_LEAP_USERNAME, PROP_WEP_KEY0, PROP_WEP_KEY1, @@ -573,6 +575,22 @@ nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting) g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP); } +/* + * nm_setting_wireless_security_get_pmf: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:pmf property of the setting + * + * Since: 1.10 + **/ +NMSettingWirelessSecurityPmf +nm_setting_wireless_security_get_pmf (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->pmf; +} + /** * nm_setting_wireless_security_get_psk: * @setting: the #NMSettingWirelessSecurity @@ -1013,6 +1031,30 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } } + if (priv->pmf > NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PMF); + return FALSE; + } + + if ( NM_IN_SET (priv->pmf, + NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL, + NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) + && !NM_IN_STRSET (priv->key_mgmt, "wpa-eap", "wpa-psk")) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' can only be used with '%s=%s or '%s=%s'"), + priv->pmf == NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL ? "optional" : "required", + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk"); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PMF); + return FALSE; + } + return TRUE; } @@ -1198,6 +1240,9 @@ set_property (GObject *object, guint prop_id, g_slist_free_full (priv->group, g_free); priv->group = _nm_utils_strv_to_slist (g_value_get_boxed (value), TRUE); break; + case PROP_PMF: + priv->pmf = g_value_get_uint (value); + break; case PROP_LEAP_USERNAME: g_free (priv->leap_username); priv->leap_username = g_value_dup_string (value); @@ -1270,6 +1315,9 @@ get_property (GObject *object, guint prop_id, case PROP_GROUP: g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->group, TRUE)); break; + case PROP_PMF: + g_value_set_uint (value, nm_setting_wireless_security_get_pmf (setting)); + break; case PROP_LEAP_USERNAME: g_value_set_string (value, priv->leap_username); break; @@ -1468,6 +1516,37 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting G_PARAM_STATIC_STRINGS)); /** + * NMSettingWirelessSecurity:pmf: + * + * Indicates whether Protected Management Frames (802.11w) must be enabled + * for the connection. One of %NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT + * (use global default value), %NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE + * (disable PMF), %NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL (enable PMF if + * the supplicant and the access point support it) or + * %NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED (enable PMF and fail if not + * supported). When set to %NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT and no + * global default is set, PMF will be optionally enabled. + * + * Since: 1.10 + **/ + /* ---ifcfg-rh--- + * property: pmf + * variable: PMF(+) + * values: default, disable, optional, required + * description: Enables or disables PMF (802.11w) + * example: PMF=required + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PMF, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_PMF, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** * NMSettingWirelessSecurity:leap-username: * * The login username for legacy LEAP connections (ie, key-mgmt = diff --git a/libnm-core/nm-setting-wireless-security.h b/libnm-core/nm-setting-wireless-security.h index ae252f1124..2c6dcaad62 100644 --- a/libnm-core/nm-setting-wireless-security.h +++ b/libnm-core/nm-setting-wireless-security.h @@ -71,12 +71,31 @@ typedef enum { NM_WEP_KEY_TYPE_LAST = NM_WEP_KEY_TYPE_PASSPHRASE } NMWepKeyType; +/** + * NMSettingWirelessSecurityPmf: + * @NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT: use the default value + * @NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE: disable PMF + * @NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL: enable PMF if the supplicant and the AP support it + * @NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED: require PMF and fail if not available + * + * These flags indicate whether PMF must be enabled. + **/ +typedef enum { + NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT = 0, + NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE = 1, + NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL = 2, + NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED = 3, + _NM_SETTING_WIRELESS_SECURITY_PMF_NUM, /*< skip >*/ + NM_SETTING_WIRELESS_SECURITY_PMF_LAST = _NM_SETTING_WIRELESS_SECURITY_PMF_NUM - 1, /*< skip >*/ +} NMSettingWirelessSecurityPmf; + #define NM_SETTING_WIRELESS_SECURITY_KEY_MGMT "key-mgmt" #define NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX "wep-tx-keyidx" #define NM_SETTING_WIRELESS_SECURITY_AUTH_ALG "auth-alg" #define NM_SETTING_WIRELESS_SECURITY_PROTO "proto" #define NM_SETTING_WIRELESS_SECURITY_PAIRWISE "pairwise" #define NM_SETTING_WIRELESS_SECURITY_GROUP "group" +#define NM_SETTING_WIRELESS_SECURITY_PMF "pmf" #define NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME "leap-username" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY0 "wep-key0" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY1 "wep-key1" @@ -132,6 +151,9 @@ void nm_setting_wireless_security_remove_group (NMSettingWireles gboolean nm_setting_wireless_security_remove_group_by_value (NMSettingWirelessSecurity *setting, const char *group); void nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting); +NM_AVAILABLE_IN_1_10 +NMSettingWirelessSecurityPmf nm_setting_wireless_security_get_pmf (NMSettingWirelessSecurity *setting); + const char *nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting); NMSettingSecretFlags nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting); diff --git a/libnm/libnm.ver b/libnm/libnm.ver index b767bf83a5..f9d826d831 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1177,3 +1177,9 @@ global: nm_utils_format_variant_attributes; nm_utils_parse_variant_attributes; } libnm_1_6_0; + +libnm_1_10_0 { +global: + nm_setting_wireless_security_get_pmf; + nm_setting_wireless_security_pmf_get_type; +} libnm_1_8_0; diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index 658fd7c2d6..808f7375df 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -701,6 +701,11 @@ ipv6.ip6-privacy=0 <listitem><para>If left unspecified, the default value "<literal>ignore</literal>" will be used.</para></listitem> </varlistentry> + <varlistentry> + <term><varname>wifi-sec.pmf</varname></term> + <listitem><para>If left unspecified, the default value + "<literal>optional</literal>" will be used.</para></listitem> + </varlistentry> </variablelist> </para> </refsect2> diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 7359be96ea..fd0cd0d9f3 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -2348,6 +2348,8 @@ build_supplicant_config (NMDeviceWifi *self, NMSupplicantConfig *config = NULL; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wireless_sec; + NMSettingWirelessSecurityPmf pmf; + gs_free char *value = NULL; g_return_val_if_fail (priv->sup_iface, NULL); @@ -2378,12 +2380,46 @@ build_supplicant_config (NMDeviceWifi *self, nm_device_get_ifindex (NM_DEVICE (self))); g_assert (con_uuid); + + /* Configure PMF (802.11w) */ + pmf = nm_setting_wireless_security_get_pmf (s_wireless_sec); + if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT) { + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "wifi-sec.pmf", + NM_DEVICE (self)); + pmf = _nm_utils_ascii_str_to_int64 (value, 10, + NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE, + NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED, + 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; + } + } + s_8021x = nm_connection_get_setting_802_1x (connection); if (!nm_supplicant_config_add_setting_wireless_security (config, s_wireless_sec, s_8021x, con_uuid, mtu, + pmf, error)) { g_prefix_error (error, "802-11-wireless-security: "); goto error; diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index f16aaa8420..c4221c8893 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -3294,7 +3294,9 @@ make_wpa_setting (shvarFile *ifcfg, { NMSettingWirelessSecurity *wsec; char *value, *psk, *lower; + const char *cvalue; gboolean wpa_psk = FALSE, wpa_eap = FALSE, ieee8021x = FALSE; + guint pmf = NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT; wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); @@ -3373,6 +3375,24 @@ make_wpa_setting (shvarFile *ifcfg, g_free (value); + cvalue = svGetValue (ifcfg, "PMF", &value); + if (cvalue) { + int i_pmf; + + if (!nm_utils_enum_from_str (nm_setting_wireless_security_pmf_get_type (), + cvalue, + &i_pmf, + NULL)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid PMF value '%s'", cvalue); + g_free (value); + goto error; + } + pmf = i_pmf; + g_free (value); + } + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PMF, pmf, NULL); + value = svGetValueStr_cp (ifcfg, "SECURITYMODE"); if (NM_IN_STRSET (value, NULL, "open")) g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, value, NULL); diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index c6957e8816..3b2b1a5c73 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -707,6 +707,17 @@ write_wireless_security_setting (NMConnection *connection, "WPA_PSK_FLAGS", wpa ? nm_setting_wireless_security_get_psk_flags (s_wsec) : NM_SETTING_SECRET_FLAG_NONE); + + if (nm_setting_wireless_security_get_pmf (s_wsec) == NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT) + svUnsetValue (ifcfg, "PMF"); + else { + gs_free char * value = NULL; + + value = nm_utils_enum_to_str (nm_setting_wireless_security_pmf_get_type(), + nm_setting_wireless_security_get_pmf (s_wsec)); + svSetValueStr (ifcfg, "PMF", value); + } + return TRUE; } diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 057d72d5f6..97b65eaaf7 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -5768,6 +5768,7 @@ test_write_wifi_wpa_psk (gconstpointer test_data) g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NM_SETTING_WIRELESS_SECURITY_PSK, args.psk, + NM_SETTING_WIRELESS_SECURITY_PMF, (guint) NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED, NULL); if (GPOINTER_TO_INT (args.wep_group_p)) { diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c index 4ff376a5cd..3f607420c6 100644 --- a/src/supplicant/nm-supplicant-config.c +++ b/src/supplicant/nm-supplicant-config.c @@ -684,9 +684,10 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, NMSetting8021x *setting_8021x, const char *con_uuid, guint32 mtu, + NMSettingWirelessSecurityPmf pmf, GError **error) { - const char *key_mgmt, *auth_alg; + const char *key_mgmt, *key_mgmt_conf, *auth_alg; const char *psk; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); @@ -694,8 +695,19 @@ 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); - key_mgmt = nm_setting_wireless_security_get_key_mgmt (setting); - if (!add_string_val (self, key_mgmt, "key_mgmt", TRUE, NULL, error)) + key_mgmt = key_mgmt_conf = nm_setting_wireless_security_get_key_mgmt (setting); + if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL) { + if (nm_streq (key_mgmt_conf, "wpa-psk")) + key_mgmt_conf = "wpa-psk wpa-psk-sha256"; + else if (nm_streq (key_mgmt_conf, "wpa-eap")) + key_mgmt_conf = "wpa-eap wpa-eap-sha256"; + } else if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED) { + if (nm_streq (key_mgmt_conf, "wpa-psk")) + key_mgmt_conf = "wpa-psk-sha256"; + else if (nm_streq (key_mgmt_conf, "wpa-eap")) + key_mgmt_conf = "wpa-eap-sha256"; + } + if (!add_string_val (self, key_mgmt_conf, "key_mgmt", TRUE, NULL, error)) return FALSE; auth_alg = nm_setting_wireless_security_get_auth_alg (setting); @@ -750,6 +762,19 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, return FALSE; if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, group, groups, "group", ' ', TRUE, NULL, error)) return FALSE; + + if ( !nm_streq (key_mgmt, "wpa-none") + && NM_IN_SET (pmf, + NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL, + NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED)) { + if (!nm_supplicant_config_add_option (self, + "ieee80211w", + pmf == NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL ? "1" : "2", + -1, + NULL, + error)) + return FALSE; + } } /* WEP keys if required */ @@ -1325,31 +1350,3 @@ nm_supplicant_config_add_no_security (NMSupplicantConfig *self, GError **error) return nm_supplicant_config_add_option (self, "key_mgmt", "NONE", -1, NULL, error); } -gboolean -nm_supplicant_config_enable_pmf_akm (NMSupplicantConfig *self, GError **error) -{ - NMSupplicantConfigPrivate *priv; - ConfigOption *option; - - g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); - g_return_val_if_fail (!error || !*error, FALSE); - - priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); - - option = g_hash_table_lookup (priv->config, "key_mgmt"); - if (!option) - return TRUE; - - if (nm_streq0 (option->value, "WPA-PSK")) { - g_hash_table_remove (priv->config, "key_mgmt"); - if (!nm_supplicant_config_add_option (self, "key_mgmt", "WPA-PSK WPA-PSK-SHA256", -1, NULL, error)) - return FALSE; - } else if (nm_streq0 (option->value, "WPA-EAP")) { - g_hash_table_remove (priv->config, "key_mgmt"); - if (!nm_supplicant_config_add_option (self, "key_mgmt", "WPA-EAP WPA-EAP-SHA256", -1, NULL, error)) - return FALSE; - } - - return TRUE; -} - diff --git a/src/supplicant/nm-supplicant-config.h b/src/supplicant/nm-supplicant-config.h index 705833ff5f..93fc57ce3a 100644 --- a/src/supplicant/nm-supplicant-config.h +++ b/src/supplicant/nm-supplicant-config.h @@ -60,6 +60,7 @@ gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig NMSetting8021x *setting_8021x, const char *con_uuid, guint32 mtu, + NMSettingWirelessSecurityPmf pmf, GError **error); gboolean nm_supplicant_config_add_no_security (NMSupplicantConfig *self, diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c index dec208276e..c4633f2535 100644 --- a/src/supplicant/nm-supplicant-interface.c +++ b/src/supplicant/nm-supplicant-interface.c @@ -472,30 +472,6 @@ iface_check_ready (NMSupplicantInterface *self) } } -static void -set_pmf_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) -{ - NMSupplicantInterface *self; - NMSupplicantInterfacePrivate *priv; - gs_unref_variant GVariant *reply = NULL; - gs_free_error GError *error = NULL; - - reply = g_dbus_proxy_call_finish (proxy, result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = NM_SUPPLICANT_INTERFACE (user_data); - priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - if (!reply) { - g_dbus_error_strip_remote_error (error); - _LOGW ("couldn't enable PMF: %s", error->message); - return; - } - - _LOGD ("PMF enabled"); -} - gboolean nm_supplicant_interface_credentials_reply (NMSupplicantInterface *self, const char *field, @@ -567,6 +543,12 @@ nm_supplicant_interface_get_ap_support (NMSupplicantInterface *self) return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->ap_support; } +NMSupplicantFeature +nm_supplicant_interface_get_pmf_support (NMSupplicantInterface *self) +{ + return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->pmf_support; +} + void nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self, NMSupplicantFeature ap_support) @@ -841,21 +823,6 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ NULL, NULL); - if ( priv->pmf_support == NM_SUPPLICANT_FEATURE_YES - && priv->driver == NM_SUPPLICANT_DRIVER_WIRELESS) { - g_dbus_proxy_call (priv->iface_proxy, - DBUS_INTERFACE_PROPERTIES ".Set", - g_variant_new ("(ssv)", - WPAS_DBUS_IFACE_INTERFACE, - "Pmf", - g_variant_new_uint32 (1)), - G_DBUS_CALL_FLAGS_NONE, - -1, - priv->init_cancellable, - (GAsyncReadyCallback) set_pmf_cb, - self); - } - /* Check whether NetworkReply and AP mode are supported */ priv->ready_count = 1; g_dbus_proxy_call (priv->iface_proxy, @@ -1424,7 +1391,6 @@ nm_supplicant_interface_assoc (NMSupplicantInterface *self, { NMSupplicantInterfacePrivate *priv; AssocData *assoc_data; - GError *error = NULL; g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (self)); g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (cfg)); @@ -1441,14 +1407,6 @@ nm_supplicant_interface_assoc (NMSupplicantInterface *self, assoc_data->callback = callback; assoc_data->user_data = user_data; - if ( priv->driver == NM_SUPPLICANT_DRIVER_WIRELESS - && priv->pmf_support == NM_SUPPLICANT_FEATURE_YES) { - if (!nm_supplicant_config_enable_pmf_akm (cfg, &error)) { - _LOGW ("could not enable PMF AKMs in config: %s", error->message); - g_error_free (error); - } - } - _LOGD ("assoc[%p]: starting association...", assoc_data); /* Make sure the supplicant supports EAP-FAST before trying to send diff --git a/src/supplicant/nm-supplicant-interface.h b/src/supplicant/nm-supplicant-interface.h index a881ede236..a31d2b8a81 100644 --- a/src/supplicant/nm-supplicant-interface.h +++ b/src/supplicant/nm-supplicant-interface.h @@ -121,6 +121,7 @@ gboolean nm_supplicant_interface_credentials_reply (NMSupplicantInterface *self, GError **error); NMSupplicantFeature nm_supplicant_interface_get_ap_support (NMSupplicantInterface *self); +NMSupplicantFeature nm_supplicant_interface_get_pmf_support (NMSupplicantInterface *self); void nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self, NMSupplicantFeature apmode); diff --git a/src/supplicant/nm-supplicant-settings-verify.c b/src/supplicant/nm-supplicant-settings-verify.c index fd5b06eacf..14daf6938b 100644 --- a/src/supplicant/nm-supplicant-settings-verify.c +++ b/src/supplicant/nm-supplicant-settings-verify.c @@ -151,6 +151,7 @@ static const struct Opt opt_table[] = { { "mka_cak", TYPE_BYTES, 0, 65536, FALSE, NULL }, { "mka_ckn", TYPE_BYTES, 0, 65536, FALSE, NULL }, { "macsec_port", TYPE_INT, 1, 65534, FALSE, NULL }, + { "ieee80211w", TYPE_INT, 0, 2, FALSE, NULL }, }; diff --git a/src/supplicant/tests/test-supplicant-config.c b/src/supplicant/tests/test-supplicant-config.c index fd91e92177..68c4f83da3 100644 --- a/src/supplicant/tests/test-supplicant-config.c +++ b/src/supplicant/tests/test-supplicant-config.c @@ -278,6 +278,7 @@ test_wifi_wep_key (const char *detail, NULL, "376aced7-b28c-46be-9a62-fcdf072571da", 1500, + 0, &error)); g_assert_no_error (error); g_test_assert_expected_messages (); @@ -374,6 +375,7 @@ test_wifi_wpa_psk (const char *detail, g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NM_SETTING_WIRELESS_SECURITY_PSK, key_data, + NM_SETTING_WIRELESS_SECURITY_PMF, NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL, NULL); nm_setting_wireless_security_add_proto (s_wsec, "wpa"); @@ -411,7 +413,7 @@ test_wifi_wpa_psk (const char *detail, g_test_assert_expected_messages (); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, - "*added 'key_mgmt' value 'WPA-PSK'"); + "*added 'key_mgmt' value 'WPA-PSK WPA-PSK-SHA256'"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*added 'psk' value *"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, @@ -420,11 +422,14 @@ test_wifi_wpa_psk (const char *detail, "*added 'pairwise' value 'TKIP CCMP'"); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, "*added 'group' value 'TKIP CCMP'"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_INFO, + "*added 'ieee80211w' value '1'"); g_assert (nm_supplicant_config_add_setting_wireless_security (config, s_wsec, NULL, "376aced7-b28c-46be-9a62-fcdf072571da", 1500, + NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL, &error)); g_assert_no_error (error); g_test_assert_expected_messages (); @@ -435,7 +440,7 @@ test_wifi_wpa_psk (const char *detail, validate_opt (detail, config_dict, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1); validate_opt (detail, config_dict, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data)); validate_opt (detail, config_dict, "bssid", TYPE_KEYWORD, bssid_str, -1); - validate_opt (detail, config_dict, "key_mgmt", TYPE_KEYWORD, "WPA-PSK", -1); + validate_opt (detail, config_dict, "key_mgmt", TYPE_KEYWORD, "WPA-PSK WPA-PSK-SHA256", -1); validate_opt (detail, config_dict, "proto", TYPE_KEYWORD, "WPA RSN", -1); validate_opt (detail, config_dict, "pairwise", TYPE_KEYWORD, "TKIP CCMP", -1); validate_opt (detail, config_dict, "group", TYPE_KEYWORD, "TKIP CCMP", -1); @@ -580,6 +585,7 @@ test_wifi_eap (void) s_8021x, "d5b488af-9cab-41ed-bad4-97709c58430f", mtu, + NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE, &error)); g_assert_no_error (error); g_test_assert_expected_messages (); |