summary refs log tree commit diff
path: root/src/settings/plugins/ifcfg-rh
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2019-03-26 23:25:23 +0100
committerMichael Biebl <biebl@debian.org>2019-03-26 23:25:23 +0100
commit9a6dcbf895f9da01768e64b73cec88c16157d91e (patch)
treea359958930d731e9f1b59344642e10754419fe84 /src/settings/plugins/ifcfg-rh
parent964ae8cc391520440cf5aa13e2b9cc34850ea6c2 (diff)
New upstream version 1.16.0 upstream/1.16.0
Diffstat (limited to 'src/settings/plugins/ifcfg-rh')
-rw-r--r--src/settings/plugins/ifcfg-rh/meson.build12
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-inotify-helper.c8
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c1
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c11
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c67
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c1
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c6
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.c32
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/meson.build4
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Band_A.cexpected2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_always.cexpected2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_default.cexpected2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_missing.cexpected2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_never.cexpected2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-sae5
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-42
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-sae1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c63
21 files changed, 133 insertions, 96 deletions
diff --git a/src/settings/plugins/ifcfg-rh/meson.build b/src/settings/plugins/ifcfg-rh/meson.build
index e84ae80c..9024782a 100644
--- a/src/settings/plugins/ifcfg-rh/meson.build
+++ b/src/settings/plugins/ifcfg-rh/meson.build
@@ -1,6 +1,6 @@
 install_data(
   'nm-ifcfg-rh.conf',
-  install_dir: dbus_conf_dir
+  install_dir: dbus_conf_dir,
 )
 
 name = 'nmdbus-ifcfg-rh'
@@ -9,7 +9,7 @@ dbus_sources = gnome.gdbus_codegen(
   name,
   'nm-ifcfg-rh.xml',
   interface_prefix: 'com.redhat',
-  namespace: 'NMDBus'
+  namespace: 'NMDBus',
 )
 
 libnmdbus_ifcfg_rh = static_library(
@@ -23,11 +23,11 @@ core_sources = files(
   'nms-ifcfg-rh-reader.c',
   'nms-ifcfg-rh-utils.c',
   'nms-ifcfg-rh-writer.c',
-  'shvar.c'
+  'shvar.c',
 )
 
 deps = [
-  nm_dep
+  nm_dep,
 ]
 
 libnms_ifcfg_rh_core = static_library(
@@ -46,7 +46,7 @@ libnm_settings_plugin_ifcfg_rh = shared_module(
   link_args: ldflags_linker_script_settings,
   link_depends: linker_script_settings,
   install: true,
-  install_dir: nm_plugindir
+  install_dir: nm_plugindir,
 )
 
 core_plugins += libnm_settings_plugin_ifcfg_rh
@@ -56,7 +56,7 @@ core_plugins += libnm_settings_plugin_ifcfg_rh
 run_target(
   'check-local-symbols-settings-ifcfg-rh',
   command: [check_so_symbols, libnm_settings_plugin_ifcfg_rh.full_path()],
-  depends: libnm_settings_plugin_ifcfg_rh
+  depends: libnm_settings_plugin_ifcfg_rh,
 )
 
 check-local-symbols-settings-ifcfg-rh: src/settings/plugins/ifcfg-rh/libnm-settings-plugin-ifcfg-rh.la
diff --git a/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c
index e7a74a1a..04cbb5bc 100644
--- a/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c
+++ b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c
@@ -23,9 +23,7 @@
 #include "nm-inotify-helper.h"
 
 #include <unistd.h>
-#include <string.h>
 #include <sys/inotify.h>
-#include <errno.h>
 
 #include "NetworkManagerUtils.h"
 
@@ -143,12 +141,12 @@ init_inotify (NMInotifyHelper *self)
 {
 	NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self);
 	GIOChannel *channel;
+	int errsv;
 
 	priv->ifd = inotify_init1 (IN_CLOEXEC);
 	if (priv->ifd == -1) {
-		int errsv = errno;
-
-		nm_log_warn (LOGD_SETTINGS, "couldn't initialize inotify: %s (%d)", strerror (errsv), errsv);
+		errsv = errno;
+		nm_log_warn (LOGD_SETTINGS, "couldn't initialize inotify: %s (%d)", nm_strerror_native (errsv), errsv);
 		return FALSE;
 	}
 
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c
index ca319ddc..4f769c5f 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c
@@ -22,7 +22,6 @@
 
 #include "nms-ifcfg-rh-connection.h"
 
-#include <string.h>
 #include <sys/inotify.h>
 #include <glib/gstdio.h>
 
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
index 6cac8cb6..89272edb 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
@@ -25,9 +25,7 @@
 
 #include "nms-ifcfg-rh-plugin.h"
 
-#include <string.h>
 #include <unistd.h>
-#include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <gmodule.h>
@@ -539,7 +537,7 @@ read_connections (SettingsPluginIfcfg *plugin)
 	 * iterating over the files.
 	 *
 	 * To have sensible, reproducible behavior, sort the paths by last modification
-	 * time prefering older files.
+	 * time preferring older files.
 	 */
 	paths = _paths_from_connections (priv->connections);
 	g_ptr_array_sort_with_data (filenames, (GCompareDataFunc) _sort_paths, paths);
@@ -602,12 +600,9 @@ load_connection (NMSettingsPlugin *config,
 {
 	SettingsPluginIfcfg *plugin = SETTINGS_PLUGIN_IFCFG (config);
 	NMIfcfgConnection *connection;
-	int dir_len = strlen (IFCFG_DIR);
 	char *ifcfg_path;
 
-	if (   strncmp (filename, IFCFG_DIR, dir_len) != 0
-	    || filename[dir_len] != '/'
-	    || strchr (filename + dir_len + 1, '/') != NULL)
+	if (!nm_utils_file_is_in_path (filename, IFCFG_DIR))
 		return FALSE;
 
 	/* get the real ifcfg-path. This allows us to properly
@@ -987,7 +982,7 @@ config_changed_cb (NMConfig *config,
 	 * won't be offered.
 	 *
 	 * On SIGHUP and SIGUSR1 try to re-connect to D-Bus. So in the unlikely
-	 * event that the D-Bus conneciton is broken, that allows for recovery
+	 * event that the D-Bus connection is broken, that allows for recovery
 	 * without need for restarting NetworkManager. */
 	if (!NM_FLAGS_ANY (changes,   NM_CONFIG_CHANGE_CAUSE_SIGHUP
 	                            | NM_CONFIG_CHANGE_CAUSE_SIGUSR1))
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 261dfea2..7c1db225 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -23,13 +23,11 @@
 #include "nms-ifcfg-rh-reader.h"
 
 #include <stdlib.h>
-#include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <sys/wait.h>
 #include <sys/inotify.h>
-#include <errno.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
 
@@ -189,7 +187,7 @@ _secret_password_raw_to_bytes (const char *ifcfg_key,
 		password_raw += 2;
 
 	secret = nm_secret_buf_new (strlen (password_raw) / 2 + 3);
-	if (!_nm_utils_hexstr2bin_full (password_raw, FALSE, FALSE, ":", 0, secret->bin, secret->len, &len)) {
+	if (!nm_utils_hexstr2bin_full (password_raw, FALSE, FALSE, ":", 0, secret->bin, secret->len, &len)) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
 		             "Invalid hex password in %s",
 		             ifcfg_key);
@@ -670,7 +668,7 @@ read_full_ip4_address (shvarFile *ifcfg,
 		                       &has_key, &a, error))
 			return FALSE;
 		if (has_key)
-			*out_gateway = g_strdup (nm_utils_inet4_ntop (a, inet_buf));
+			*out_gateway = nm_utils_inet4_ntop_dup (a);
 	}
 
 	/* Prefix */
@@ -801,7 +799,7 @@ enum {
  * @options_route: (in-out): when line is from the OPTIONS setting, this is a pre-created
  *   route object that is completed with the settings from options. Otherwise,
  *   it shall point to %NULL and a new route is created and returned.
- * @out_route: (out): (transfer-full): (allow-none): the parsed %NMIPRoute instance.
+ * @out_route: (out) (transfer-full) (allow-none): the parsed %NMIPRoute instance.
  *   In case a @options_route is passed in, it returns the input route that was modified
  *   in-place. But the caller must unref the returned route in either case.
  * @error: the failure description.
@@ -810,7 +808,7 @@ enum {
  * setting, and one for initscript's handle_ip_file(), which takes the lines
  * and passes them to `ip route add`. The modes are similar, but certain properties
  * are not allowed for OPTIONS.
- * The mode is differenciated by having an @options_route argument.
+ * The mode is differentiated by having an @options_route argument.
  *
  * Returns: returns a negative errno on failure. On success, it returns 0
  *   and @out_route.
@@ -873,7 +871,7 @@ parse_route_line (const char *line,
 	};
 
 	nm_assert (line);
-	nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
+	nm_assert_addr_family (addr_family);
 	nm_assert (!options_route || nm_ip_route_get_family (options_route) == addr_family);
 
 	/* initscripts read the legacy route file line-by-line and
@@ -1018,6 +1016,7 @@ parse_line_type_addr_with_prefix:
 			if (info->type == PARSE_LINE_TYPE_ADDR) {
 				if (!nm_utils_parse_inaddr_bin (addr_family,
 				                                s,
+				                                NULL,
 				                                &info->v.addr.addr)) {
 					if (   info == &infos[PARSE_LINE_ATTR_ROUTE_VIA]
 					    && nm_streq (s, "(null)")) {
@@ -1045,6 +1044,7 @@ parse_line_type_addr_with_prefix:
 					prefix = 0;
 				} else if (!nm_utils_parse_inaddr_prefix_bin (addr_family,
 				                                              s,
+				                                              NULL,
 				                                              &info->v.addr.addr,
 				                                              &prefix)) {
 					g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
@@ -1150,7 +1150,7 @@ next:
 			                                                    : ""));
 			break;
 		case PARSE_LINE_TYPE_FLAG:
-			/* NOTE: the flag (for "onlink") only allows to explictly set "TRUE".
+			/* NOTE: the flag (for "onlink") only allows to explicitly set "TRUE".
 			 * There is no way to express an explicit "FALSE" setting
 			 * of this attribute, hence, the file format cannot encode
 			 * that configuration. */
@@ -1425,8 +1425,8 @@ make_user_setting (shvarFile *ifcfg)
 			has_user_data = TRUE;
 	}
 
-	return has_user_data
-	       ? g_steal_pointer (&s_user)
+	return   has_user_data
+	       ? NM_SETTING (g_steal_pointer (&s_user))
 	       : NULL;
 }
 
@@ -1527,7 +1527,6 @@ make_ip4_setting (shvarFile *ifcfg,
 	gboolean never_default;
 	gint64 timeout;
 	int priority;
-	char inet_buf[NM_UTILS_INET_ADDRSTRLEN];
 	const char *const *item;
 	guint32 route_table;
 
@@ -1612,7 +1611,7 @@ make_ip4_setting (shvarFile *ifcfg,
 	              NULL);
 
 	if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED))
-		return g_steal_pointer (&s_ip4);
+		return NM_SETTING (g_steal_pointer (&s_ip4));
 
 	/* Handle DHCP settings */
 	nm_clear_g_free (&value);
@@ -1679,7 +1678,7 @@ make_ip4_setting (shvarFile *ifcfg,
 					PARSE_WARNING ("ignoring GATEWAY (/etc/sysconfig/network) for %s "
 					               "because the connection has no static addresses", f);
 				} else
-					gateway = g_strdup (nm_utils_inet4_ntop (a, inet_buf));
+					gateway = nm_utils_inet4_ntop_dup (a);
 			}
 		}
 	}
@@ -1803,7 +1802,7 @@ make_ip4_setting (shvarFile *ifcfg,
 	}
 	g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, (int) timeout, NULL);
 
-	return g_steal_pointer (&s_ip4);
+	return NM_SETTING (g_steal_pointer (&s_ip4));
 }
 
 static void
@@ -2945,7 +2944,7 @@ make_wep_setting (shvarFile *ifcfg,
 		return NULL;
 	}
 
-	return g_steal_pointer (&s_wsec);
+	return NM_SETTING (g_steal_pointer (&s_wsec));
 }
 
 static gboolean
@@ -3160,7 +3159,7 @@ eap_tls_reader (const char *eap_method,
 	/* FIXME: writer does not actually write IEEE_8021X_CLIENT_CERT_PASSWORD and other
 	 * certificate related passwords. It should, because otherwise persisting such profiles
 	 * to ifcfg looses information. As this currently only matters for PKCS11 URIs, it seems
-	 * a seldomly used feature so that it is not fixed yet. */
+	 * a seldom used feature so that it is not fixed yet. */
 	_secret_set_from_ifcfg (s_8021x,
 	                        ifcfg,
 	                        keys_ifcfg,
@@ -3535,7 +3534,7 @@ fill_8021x (shvarFile *ifcfg,
 				goto next;
 
 			/* Some EAP methods don't provide keying material, thus they
-			 * cannot be used with WiFi unless they are an inner method
+			 * cannot be used with Wi-Fi unless they are an inner method
 			 * used with TTLS or PEAP or whatever.
 			 */
 			if (wifi && eap->wifi_phase2_only) {
@@ -3611,7 +3610,7 @@ make_wpa_setting (shvarFile *ifcfg,
 	gs_unref_object NMSettingWirelessSecurity *wsec = NULL;
 	gs_free char *value = NULL;
 	const char *v;
-	gboolean wpa_psk = FALSE, wpa_eap = FALSE, ieee8021x = FALSE;
+	gboolean wpa_psk = FALSE, wpa_sae = FALSE, wpa_eap = FALSE, ieee8021x = FALSE;
 	int i_val;
 	GError *local = NULL;
 
@@ -3619,9 +3618,10 @@ make_wpa_setting (shvarFile *ifcfg,
 
 	v = svGetValueStr (ifcfg, "KEY_MGMT", &value);
 	wpa_psk = nm_streq0 (v, "WPA-PSK");
+	wpa_sae = nm_streq0 (v, "SAE");
 	wpa_eap = nm_streq0 (v, "WPA-EAP");
 	ieee8021x = nm_streq0 (v, "IEEE8021X");
-	if (!wpa_psk && !wpa_eap && !ieee8021x)
+	if (!wpa_psk && !wpa_sae && !wpa_eap && !ieee8021x)
 		return NULL; /* Not WPA or Dynamic WEP */
 
 	/* WPS */
@@ -3635,7 +3635,7 @@ make_wpa_setting (shvarFile *ifcfg,
 	              NULL);
 
 	/* Pairwise and Group ciphers (only relevant for WPA/RSN) */
-	if (wpa_psk || wpa_eap) {
+	if (wpa_psk || wpa_sae || wpa_eap) {
 		fill_wpa_ciphers (ifcfg, wsec, FALSE, adhoc);
 		fill_wpa_ciphers (ifcfg, wsec, TRUE, adhoc);
 	}
@@ -3658,7 +3658,7 @@ make_wpa_setting (shvarFile *ifcfg,
 			nm_setting_wireless_security_add_proto (wsec, "rsn");
 	}
 
-	if (wpa_psk) {
+	if (wpa_psk || wpa_sae) {
 		NMSettingSecretFlags psk_flags;
 
 		psk_flags = _secret_read_ifcfg_flags (ifcfg, "WPA_PSK_FLAGS");
@@ -3679,8 +3679,12 @@ make_wpa_setting (shvarFile *ifcfg,
 
 		if (adhoc)
 			g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL);
-		else
+		else if (wpa_psk)
 			g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL);
+		else if (wpa_sae)
+			g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NULL);
+		else
+			g_assert_not_reached ();
 	} else if (wpa_eap || ieee8021x) {
 		/* Adhoc mode is mutually exclusive with any 802.1x-based authentication */
 		if (adhoc) {
@@ -3945,9 +3949,8 @@ make_wireless_setting (shvarFile *ifcfg,
 
 	value = svGetValueStr_cp (ifcfg, "CHANNEL");
 	if (value) {
-		errno = 0;
 		chan = _nm_utils_ascii_str_to_int64 (value, 10, 1, 196, 0);
-		if (errno || (chan == 0)) {
+		if (chan == 0) {
 			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
 			             "Invalid wireless channel '%s'", value);
 			g_free (value);
@@ -4991,7 +4994,7 @@ handle_bridge_option (NMSetting *setting,
 			} else {
 				v = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1);
 				if (v == -1) {
-					error_message = g_strerror (errno);
+					error_message = nm_strerror_native (errno);
 					goto warn;
 				}
 			}
@@ -5003,7 +5006,7 @@ handle_bridge_option (NMSetting *setting,
 		case G_TYPE_UINT:
 			v = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT, -1);
 			if (v == -1) {
-				error_message = g_strerror (errno);
+				error_message = nm_strerror_native (errno);
 				goto warn;
 			}
 			if (!nm_g_object_set_property_uint (G_OBJECT (setting), m[i].property_name, v, NULL)) {
@@ -5228,16 +5231,14 @@ is_vlan_device (const char *name, shvarFile *parsed)
 static gboolean
 is_wifi_device (const char *name, shvarFile *parsed)
 {
-	int ifindex;
+	const NMPlatformLink *pllink;
 
 	g_return_val_if_fail (name != NULL, FALSE);
 	g_return_val_if_fail (parsed != NULL, FALSE);
 
-	ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, name);
-	if (ifindex == 0)
-		return FALSE;
-
-	return nm_platform_link_get_type (NM_PLATFORM_GET, ifindex) == NM_LINK_TYPE_WIFI;
+	pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, name);
+	return    pllink
+	       && pllink->type == NM_LINK_TYPE_WIFI;
 }
 
 static void
@@ -5383,7 +5384,7 @@ make_vlan_setting (shvarFile *ifcfg,
 	parse_prio_map_list (s_vlan, ifcfg, "VLAN_INGRESS_PRIORITY_MAP", NM_VLAN_INGRESS_MAP);
 	parse_prio_map_list (s_vlan, ifcfg, "VLAN_EGRESS_PRIORITY_MAP", NM_VLAN_EGRESS_MAP);
 
-	return g_steal_pointer (&s_vlan);
+	return NM_SETTING (g_steal_pointer (&s_vlan));
 }
 
 static NMConnection *
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
index 49096d26..22c9061b 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
@@ -23,7 +23,6 @@
 #include "nms-ifcfg-rh-utils.h"
 
 #include <stdlib.h>
-#include <string.h>
 
 #include "nm-core-internal.h"
 #include "NetworkManagerUtils.h"
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 f5be7520..ee7fd161 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -22,11 +22,9 @@
 
 #include "nms-ifcfg-rh-writer.h"
 
-#include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
-#include <errno.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -603,6 +601,10 @@ write_wireless_security_setting (NMConnection *connection,
 		svSetValueStr (ifcfg, "KEY_MGMT", "WPA-PSK");
 		wpa = TRUE;
 		*no_8021x = TRUE;
+	} else if (!strcmp (key_mgmt, "sae")) {
+		svSetValueStr (ifcfg, "KEY_MGMT", "SAE");
+		wpa = TRUE;
+		*no_8021x = TRUE;
 	} else if (!strcmp (key_mgmt, "ieee8021x")) {
 		svSetValueStr (ifcfg, "KEY_MGMT", "IEEE8021X");
 		dynamic_wep = TRUE;
diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c
index fe82fbdd..f3d58e26 100644
--- a/src/settings/plugins/ifcfg-rh/shvar.c
+++ b/src/settings/plugins/ifcfg-rh/shvar.c
@@ -27,11 +27,9 @@
 
 #include "shvar.h"
 
-#include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -215,9 +213,9 @@ _escape_ansic (const char *source)
 
 /*****************************************************************************/
 
-#define _char_req_escape(ch)        NM_IN_SET (ch,      '\"', '\\',       '$', '`')
-#define _char_req_escape_old(ch)    NM_IN_SET (ch,      '\"', '\\', '\'', '$', '`', '~')
-#define _char_req_quotes(ch)        NM_IN_SET (ch, ' ',             '\'',           '~', '\t', '|', '&', ';', '(', ')', '<', '>')
+#define _char_req_escape(ch)        NM_IN_SET (ch,      '"', '\\',       '$', '`')
+#define _char_req_escape_old(ch)    NM_IN_SET (ch,      '"', '\\', '\'', '$', '`', '~')
+#define _char_req_quotes(ch)        NM_IN_SET (ch, ' ',            '\'',           '~', '\t', '|', '&', ';', '(', ')', '<', '>')
 
 const char *
 svEscape (const char *s, char **to_free)
@@ -330,7 +328,7 @@ _gstr_init (GString **str, const char *value, gsize i)
 		 * Unescaping usually does not extend the length of a string,
 		 * so we might be tempted to allocate a fixed buffer of length
 		 * (strlen(value)+CONST).
-		 * However, due to $'\Ux' escapes, the maxium length is some
+		 * However, due to $'\Ux' escapes, the maximum length is some
 		 * (FACTOR*strlen(value) + CONST), which is non trivial to get
 		 * right in all cases. Also, we would have to provision for the
 		 * very unlikely extreme case.
@@ -453,7 +451,7 @@ svUnescape (const char *value, char **to_free)
 					if (NM_IN_SET (value[i], '$', '`', '"', '\\')) {
 						/* Drop the backslash. */
 					} else if (NM_IN_SET (value[i], '\'', '~')) {
-						/* '\'' and '~' in double qoutes are not handled special by shell.
+						/* '\'' and '~' in double quotes are not handled special by shell.
 						 * However, old versions of svEscape() would wrongly use double-quoting
 						 * with backslash escaping for these characters (expecting svUnescape()
 						 * to remove the backslash).
@@ -649,7 +647,7 @@ void
 _nmtst_svFileSetName (shvarFile *s, const char *fileName)
 {
 	/* changing the file name is not supported for regular
-	 * operation. Only allowed to use in tests, othewise,
+	 * operation. Only allowed to use in tests, otherwise,
 	 * the filename is immutable. */
 	g_free (s->fileName);
 	s->fileName = g_strdup (fileName);
@@ -815,7 +813,7 @@ svOpenFileInternal (const char *name, gboolean create, GError **error)
 
 		g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv),
 		             "Could not read file '%s': %s",
-		             name, strerror (errsv));
+		             name, nm_strerror_native (errsv));
 		return NULL;
 	}
 
@@ -1317,34 +1315,32 @@ svWriteFile (shvarFile *s, int mode, GError **error)
 	FILE *f;
 	int tmpfd;
 	CList *current;
+	int errsv;
 
 	if (s->modified) {
 		if (s->fd == -1)
 			s->fd = open (s->fileName, O_WRONLY | O_CREAT | O_CLOEXEC, mode);
 		if (s->fd == -1) {
-			int errsv = errno;
-
+			errsv = errno;
 			g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv),
 			             "Could not open file '%s' for writing: %s",
-			             s->fileName, strerror (errsv));
+			             s->fileName, nm_strerror_native (errsv));
 			return FALSE;
 		}
 		if (ftruncate (s->fd, 0) < 0) {
-			int errsv = errno;
-
+			errsv = errno;
 			g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv),
 			             "Could not overwrite file '%s': %s",
-			             s->fileName, strerror (errsv));
+			             s->fileName, nm_strerror_native (errsv));
 			return FALSE;
 		}
 
 		tmpfd = fcntl (s->fd, F_DUPFD_CLOEXEC, 0);
 		if (tmpfd == -1) {
-			int errsv = errno;
-
+			errsv = errno;
 			g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv),
 			             "Internal error writing file '%s': %s",
-			             s->fileName, strerror (errsv));
+			             s->fileName, nm_strerror_native (errsv));
 			return FALSE;
 		}
 		f = fdopen (tmpfd, "w");
diff --git a/src/settings/plugins/ifcfg-rh/tests/meson.build b/src/settings/plugins/ifcfg-rh/tests/meson.build
index 29bc9699..f65494bb 100644
--- a/src/settings/plugins/ifcfg-rh/tests/meson.build
+++ b/src/settings/plugins/ifcfg-rh/tests/meson.build
@@ -6,12 +6,12 @@ exe = executable(
   test_unit,
   test_unit + '.c',
   dependencies: test_nm_dep,
-  link_with: libnms_ifcfg_rh_core
+  link_with: libnms_ifcfg_rh_core,
 )
 
 test(
   'ifcfg-rh/' + test_unit,
   test_script,
   timeout: 90,
-  args: test_args + [exe.full_path()]
+  args: test_args + [exe.full_path()],
 )
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Band_A.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Band_A.cexpected
index a95a58db..ddbd986f 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Band_A.cexpected
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Band_A.cexpected
@@ -13,6 +13,6 @@ IPV6_AUTOCONF=yes
 IPV6_DEFROUTE=yes
 IPV6_FAILURE_FATAL=no
 IPV6_ADDR_GEN_MODE=stable-privacy
-NAME="Test Write WiFi Band A"
+NAME="Test Write Wi-Fi Band A"
 UUID=${UUID}
 ONBOOT=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected
index cf325f35..495a24d3 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected
@@ -12,6 +12,6 @@ IPV6_AUTOCONF=yes
 IPV6_DEFROUTE=yes
 IPV6_FAILURE_FATAL=no
 IPV6_ADDR_GEN_MODE=stable-privacy
-NAME="Test Write WiFi Hidden"
+NAME="Test Write Wi-Fi Hidden"
 UUID=${UUID}
 ONBOOT=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_always.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_always.cexpected
index f3704f10..aec6918a 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_always.cexpected
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_always.cexpected
@@ -13,6 +13,6 @@ IPV6_AUTOCONF=yes
 IPV6_DEFROUTE=yes
 IPV6_FAILURE_FATAL=no
 IPV6_ADDR_GEN_MODE=stable-privacy
-NAME="Test Write WiFi MAC always"
+NAME="Test Write Wi-Fi MAC always"
 UUID=${UUID}
 ONBOOT=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_default.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_default.cexpected
index 005c6179..9d47163f 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_default.cexpected
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_default.cexpected
@@ -12,6 +12,6 @@ IPV6_AUTOCONF=yes
 IPV6_DEFROUTE=yes
 IPV6_FAILURE_FATAL=no
 IPV6_ADDR_GEN_MODE=stable-privacy
-NAME="Test Write WiFi MAC default"
+NAME="Test Write Wi-Fi MAC default"
 UUID=${UUID}
 ONBOOT=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_missing.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_missing.cexpected
index dff17ef2..43c07ddb 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_missing.cexpected
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_missing.cexpected
@@ -13,6 +13,6 @@ IPV6_AUTOCONF=yes
 IPV6_DEFROUTE=yes
 IPV6_FAILURE_FATAL=no
 IPV6_ADDR_GEN_MODE=stable-privacy
-NAME="Test Write WiFi MAC missing"
+NAME="Test Write Wi-Fi MAC missing"
 UUID=${UUID}
 ONBOOT=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_never.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_never.cexpected
index 94274cf9..21f2e2de 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_never.cexpected
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_never.cexpected
@@ -13,6 +13,6 @@ IPV6_AUTOCONF=yes
 IPV6_DEFROUTE=yes
 IPV6_FAILURE_FATAL=no
 IPV6_ADDR_GEN_MODE=stable-privacy
-NAME="Test Write WiFi MAC never"
+NAME="Test Write Wi-Fi MAC never"
 UUID=${UUID}
 ONBOOT=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-sae b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-sae
new file mode 100644
index 00000000..68afbe97
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-sae
@@ -0,0 +1,5 @@
+TYPE=Wireless
+DEVICE=wlan1
+ESSID=blahblah
+MODE=Managed
+KEY_MGMT=SAE
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4
index a7156e33..2c1b7fb4 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4
@@ -6,7 +6,7 @@
 # expected.
 #
 # Also note that setting NAME will replace the last
-# occurance, and delete all previous once.
+# occurrence, and delete all previous once.
 
 #L1
 NAME=l2
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected
index 674df840..cf3f45bd 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-write-unknown-4.expected
@@ -6,7 +6,7 @@
 # expected.
 #
 # Also note that setting NAME will replace the last
-# occurance, and delete all previous once.
+# occurrence, and delete all previous once.
 
 #L1
 
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-sae b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-sae
new file mode 100644
index 00000000..5a9569ed
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-sae
@@ -0,0 +1 @@
+WPA_PSK="The king is dead."
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default
index 9a292679..4347405e 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default
@@ -1,4 +1,4 @@
 GATEWAYDEV=eth0
-# when devices in IPV6_DEFAULTDEV and IPV6_DEFAULTGW don't match the one in IPV6_DEFAULTGW is prefered
+# when devices in IPV6_DEFAULTDEV and IPV6_DEFAULTGW don't match the one in IPV6_DEFAULTGW is preferred
 IPV6_DEFAULTDEV=eth4
 IPV6_DEFAULTGW=2001::1234%eth0
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 472bb8a6..b352fbfc 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -23,7 +23,6 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <unistd.h>
-#include <string.h>
 #include <linux/pkt_sched.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -123,7 +122,7 @@ _assert_reread_same_FIXME (NMConnection *connection, NMConnection *reread)
 
 /* dummy path for an "expected" file, meaning: don't check for expected
  * written ifcfg file. */
-static const char const NO_EXPECTED[1];
+static const char NO_EXPECTED[1];
 
 static void
 _assert_expected_content (NMConnection *connection, const char *filename, const char *expected)
@@ -2374,7 +2373,7 @@ test_read_wifi_open (void)
 	g_assert_cmpstr (nm_setting_wireless_get_mode (s_wireless), ==, "infrastructure");
 	g_assert_cmpint (nm_setting_wireless_get_channel (s_wireless), ==, 1);
 
-	/* ===== WiFi SECURITY SETTING ===== */
+	/* ===== Wi-Fi SECURITY SETTING ===== */
 	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	g_assert (s_wsec == NULL);
 
@@ -2967,6 +2966,45 @@ test_read_wifi_wpa_psk (void)
 }
 
 static void
+test_read_wifi_sae (void)
+{
+	gs_unref_object NMConnection *connection = NULL;
+	NMSettingConnection *s_con;
+	NMSettingWireless *s_wireless;
+	NMSettingWirelessSecurity *s_wsec;
+	GBytes *ssid;
+	const char *expected_ssid = "blahblah";
+
+	connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wifi-sae",
+	                                    NULL, TYPE_WIRELESS, NULL);
+
+	s_con = nm_connection_get_setting_connection (connection);
+	g_assert (s_con);
+	g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System blahblah (test-wifi-sae)");
+
+	g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0);
+	g_assert (nm_setting_connection_get_autoconnect (s_con));
+
+	s_wireless = nm_connection_get_setting_wireless (connection);
+	g_assert (s_wireless);
+
+	g_assert_cmpint (nm_setting_wireless_get_mtu (s_wireless), ==, 0);
+
+	ssid = nm_setting_wireless_get_ssid (s_wireless);
+	g_assert (ssid);
+	g_assert_cmpmem (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), expected_ssid, strlen (expected_ssid));
+
+	g_assert (!nm_setting_wireless_get_bssid (s_wireless));
+	g_assert_cmpstr (nm_setting_wireless_get_mode (s_wireless), ==, "infrastructure");
+
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
+	g_assert (s_wsec);
+	g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "sae");
+	g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "The king is dead.");
+	g_assert (!nm_setting_wireless_security_get_auth_alg (s_wsec));
+}
+
+static void
 test_read_wifi_wpa_psk_2 (void)
 {
 	NMConnection *connection;
@@ -3275,7 +3313,7 @@ test_read_wifi_dynamic_wep_leap (void)
 	s_wifi = nm_connection_get_setting_wireless (connection);
 	g_assert (s_wifi);
 
-	/* ===== WiFi SECURITY SETTING ===== */
+	/* ===== Wi-Fi SECURITY SETTING ===== */
 	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	g_assert (s_wsec);
 
@@ -3501,7 +3539,7 @@ test_write_wifi_hidden (void)
 	nm_connection_add_setting (connection, NM_SETTING (s_con));
 
 	g_object_set (s_con,
-	              NM_SETTING_CONNECTION_ID, "Test Write WiFi Hidden",
+	              NM_SETTING_CONNECTION_ID, "Test Write Wi-Fi Hidden",
 	              NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (),
 	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
 	              NULL);
@@ -3584,7 +3622,7 @@ test_write_wifi_mac_random (gconstpointer user_data)
 	s_con = (NMSettingConnection *) nm_setting_connection_new ();
 	nm_connection_add_setting (connection, NM_SETTING (s_con));
 
-	val = g_strdup_printf ("Test Write WiFi MAC %s", name);
+	val = g_strdup_printf ("Test Write Wi-Fi MAC %s", name);
 	g_object_set (s_con,
 	              NM_SETTING_CONNECTION_ID, val,
 	              NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (),
@@ -3803,7 +3841,7 @@ test_write_wifi_band_a (void)
 	nm_connection_add_setting (connection, NM_SETTING (s_con));
 
 	g_object_set (s_con,
-	              NM_SETTING_CONNECTION_ID, "Test Write WiFi Band A",
+	              NM_SETTING_CONNECTION_ID, "Test Write Wi-Fi Band A",
 	              NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (),
 	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
 	              NULL);
@@ -7402,8 +7440,6 @@ test_write_mobile_broadband (gconstpointer data)
 		/* GSM setting */
 		s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
 		nm_connection_add_setting (connection, NM_SETTING (s_gsm));
-
-		g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL);
 	} else {
 		/* CDMA setting */
 		s_cdma = (NMSettingCdma *) nm_setting_cdma_new ();
@@ -9983,10 +10019,14 @@ NMTST_DEFINE ();
 
 int main (int argc, char **argv)
 {
+	int errsv;
+
 	nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
 
-	if (g_mkdir_with_parents (TEST_SCRATCH_DIR_TMP, 0755) != 0)
-		g_error ("failure to create test directory \"%s\": %s", TEST_SCRATCH_DIR_TMP, g_strerror (errno));
+	if (g_mkdir_with_parents (TEST_SCRATCH_DIR_TMP, 0755) != 0) {
+		errsv = errno;
+		g_error ("failure to create test directory \"%s\": %s", TEST_SCRATCH_DIR_TMP, nm_strerror_native (errsv));
+	}
 
 	g_test_add_func (TPATH "svUnescape", test_svUnescape);
 
@@ -10083,6 +10123,7 @@ int main (int argc, char **argv)
 	g_test_add_func (TPATH "wifi/read/wpa-psk/unquoted2", test_read_wifi_wpa_psk_unquoted2);
 	g_test_add_func (TPATH "wifi/read/wpa-psk/adhoc", test_read_wifi_wpa_psk_adhoc);
 	g_test_add_func (TPATH "wifi/read/wpa-psk/hex", test_read_wifi_wpa_psk_hex);
+	g_test_add_func (TPATH "wifi/read/sae", test_read_wifi_sae);
 	g_test_add_func (TPATH "wifi/read/dynamic-wep/leap", test_read_wifi_dynamic_wep_leap);
 	g_test_add_func (TPATH "wifi/read/wpa/eap/tls", test_read_wifi_wpa_eap_tls);
 	g_test_add_func (TPATH "wifi/read/wpa/eap/ttls/tls", test_read_wifi_wpa_eap_ttls_tls);