summary refs log tree commit diff
path: root/libnm-core/nm-setting-wireless-security.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-core/nm-setting-wireless-security.c')
-rw-r--r--libnm-core/nm-setting-wireless-security.c686
1 files changed, 334 insertions, 352 deletions
diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c
index d1527821..f689751e 100644
--- a/libnm-core/nm-setting-wireless-security.c
+++ b/libnm-core/nm-setting-wireless-security.c
@@ -22,9 +22,8 @@
 
 #include "nm-default.h"
 
-#include <string.h>
-
 #include "nm-setting-wireless-security.h"
+
 #include "nm-setting-8021x.h"
 #include "nm-utils.h"
 #include "nm-utils-private.h"
@@ -53,9 +52,30 @@
  *       ISBN: 978-1587051548
  **/
 
-G_DEFINE_TYPE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING)
+/*****************************************************************************/
 
-#define NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurityPrivate))
+NM_GOBJECT_PROPERTIES_DEFINE (NMSettingWirelessSecurity,
+	PROP_KEY_MGMT,
+	PROP_WEP_TX_KEYIDX,
+	PROP_AUTH_ALG,
+	PROP_PROTO,
+	PROP_PAIRWISE,
+	PROP_GROUP,
+	PROP_PMF,
+	PROP_LEAP_USERNAME,
+	PROP_WEP_KEY0,
+	PROP_WEP_KEY1,
+	PROP_WEP_KEY2,
+	PROP_WEP_KEY3,
+	PROP_WEP_KEY_FLAGS,
+	PROP_WEP_KEY_TYPE,
+	PROP_PSK,
+	PROP_PSK_FLAGS,
+	PROP_LEAP_PASSWORD,
+	PROP_LEAP_PASSWORD_FLAGS,
+	PROP_WPS_METHOD,
+	PROP_FILS,
+);
 
 typedef struct {
 	char *key_mgmt;
@@ -90,44 +110,11 @@ typedef struct {
 	NMSettingWirelessSecurityFils fils;
 } NMSettingWirelessSecurityPrivate;
 
-enum {
-	PROP_0,
-	PROP_KEY_MGMT,
-	PROP_WEP_TX_KEYIDX,
-	PROP_AUTH_ALG,
-	PROP_PROTO,
-	PROP_PAIRWISE,
-	PROP_GROUP,
-	PROP_PMF,
-	PROP_LEAP_USERNAME,
-	PROP_WEP_KEY0,
-	PROP_WEP_KEY1,
-	PROP_WEP_KEY2,
-	PROP_WEP_KEY3,
-	PROP_WEP_KEY_FLAGS,
-	PROP_WEP_KEY_TYPE,
-	PROP_PSK,
-	PROP_PSK_FLAGS,
-	PROP_LEAP_PASSWORD,
-	PROP_LEAP_PASSWORD_FLAGS,
-	PROP_WPS_METHOD,
-	PROP_FILS,
+G_DEFINE_TYPE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING)
 
-	LAST_PROP
-};
+#define NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurityPrivate))
 
-/**
- * nm_setting_wireless_security_new:
- *
- * Creates a new #NMSettingWirelessSecurity object with default values.
- *
- * Returns: (transfer full): the new empty #NMSettingWirelessSecurity object
- **/
-NMSetting *
-nm_setting_wireless_security_new (void)
-{
-	return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRELESS_SECURITY, NULL);
-}
+/*****************************************************************************/
 
 /**
  * nm_setting_wireless_security_get_key_mgmt:
@@ -209,7 +196,7 @@ nm_setting_wireless_security_add_proto (NMSettingWirelessSecurity *setting, cons
 	}
 
 	priv->proto = g_slist_append (priv->proto, g_ascii_strdown (proto, -1));
-	g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO);
+	_notify (setting, PROP_PROTO);
 	return TRUE;
 }
 
@@ -234,7 +221,7 @@ nm_setting_wireless_security_remove_proto (NMSettingWirelessSecurity *setting, g
 
 	g_free (elt->data);
 	priv->proto = g_slist_delete_link (priv->proto, elt);
-	g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO);
+	_notify (setting, PROP_PROTO);
 }
 
 /**
@@ -260,7 +247,7 @@ nm_setting_wireless_security_remove_proto_by_value (NMSettingWirelessSecurity *s
 	for (iter = priv->proto; iter; iter = g_slist_next (iter)) {
 		if (strcasecmp (proto, (char *) iter->data) == 0) {
 			priv->proto = g_slist_delete_link (priv->proto, iter);
-			g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO);
+			_notify (setting, PROP_PROTO);
 			return TRUE;
 		}
 	}
@@ -284,7 +271,7 @@ nm_setting_wireless_security_clear_protos (NMSettingWirelessSecurity *setting)
 	priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
 	g_slist_free_full (priv->proto, g_free);
 	priv->proto = NULL;
-	g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO);
+	_notify (setting, PROP_PROTO);
 }
 
 /**
@@ -353,7 +340,7 @@ nm_setting_wireless_security_add_pairwise (NMSettingWirelessSecurity *setting, c
 	}
 
 	priv->pairwise = g_slist_append (priv->pairwise, g_ascii_strdown (pairwise, -1));
-	g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
+	_notify (setting, PROP_PAIRWISE);
 	return TRUE;
 }
 
@@ -379,7 +366,7 @@ nm_setting_wireless_security_remove_pairwise (NMSettingWirelessSecurity *setting
 
 	g_free (elt->data);
 	priv->pairwise = g_slist_delete_link (priv->pairwise, elt);
-	g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
+	_notify (setting, PROP_PAIRWISE);
 }
 
 /**
@@ -390,7 +377,7 @@ nm_setting_wireless_security_remove_pairwise (NMSettingWirelessSecurity *setting
  * Removes an encryption algorithm from the allowed pairwise encryption
  * algorithm list.
  *
- * Returns: %TRUE if the encryption algorith was found and removed; %FALSE if it was not.
+ * Returns: %TRUE if the encryption algorithm was found and removed; %FALSE if it was not.
  **/
 gboolean
 nm_setting_wireless_security_remove_pairwise_by_value (NMSettingWirelessSecurity *setting,
@@ -406,7 +393,7 @@ nm_setting_wireless_security_remove_pairwise_by_value (NMSettingWirelessSecurity
 	for (iter = priv->pairwise; iter; iter = g_slist_next (iter)) {
 		if (strcasecmp (pairwise, (char *) iter->data) == 0) {
 			priv->pairwise = g_slist_delete_link (priv->pairwise, iter);
-			g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
+			_notify (setting, PROP_PAIRWISE);
 			return TRUE;
 		}
 	}
@@ -430,7 +417,7 @@ nm_setting_wireless_security_clear_pairwise (NMSettingWirelessSecurity *setting)
 	priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
 	g_slist_free_full (priv->pairwise, g_free);
 	priv->pairwise = NULL;
-	g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
+	_notify (setting, PROP_PAIRWISE);
 }
 
 /**
@@ -500,7 +487,7 @@ nm_setting_wireless_security_add_group (NMSettingWirelessSecurity *setting, cons
 	}
 
 	priv->group = g_slist_append (priv->group, g_ascii_strdown (group, -1));
-	g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP);
+	_notify (setting, PROP_GROUP);
 	return TRUE;
 }
 
@@ -526,7 +513,7 @@ nm_setting_wireless_security_remove_group (NMSettingWirelessSecurity *setting, g
 
 	g_free (elt->data);
 	priv->group = g_slist_delete_link (priv->group, elt);
-	g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP);
+	_notify (setting, PROP_GROUP);
 }
 
 /**
@@ -554,7 +541,7 @@ nm_setting_wireless_security_remove_group_by_value (NMSettingWirelessSecurity *s
 	for (iter = priv->group; iter; iter = g_slist_next (iter)) {
 		if (strcasecmp (group, (char *) iter->data) == 0) {
 			priv->group = g_slist_delete_link (priv->group, iter);
-			g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP);
+			_notify (setting, PROP_GROUP);
 			return TRUE;
 		}
 	}
@@ -578,7 +565,7 @@ nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting)
 	priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
 	g_slist_free_full (priv->group, g_free);
 	priv->group = NULL;
-	g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP);
+	_notify (setting, PROP_GROUP);
 }
 
 /*
@@ -721,22 +708,22 @@ nm_setting_wireless_security_set_wep_key (NMSettingWirelessSecurity *setting, gu
 	case 0:
 		g_free (priv->wep_key0);
 		priv->wep_key0 = g_strdup (key);
-		g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+		_notify (setting, PROP_WEP_KEY0);
 		break;
 	case 1:
 		g_free (priv->wep_key1);
 		priv->wep_key1 = g_strdup (key);
-		g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
+		_notify (setting, PROP_WEP_KEY1);
 		break;
 	case 2:
 		g_free (priv->wep_key2);
 		priv->wep_key2 = g_strdup (key);
-		g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
+		_notify (setting, PROP_WEP_KEY2);
 		break;
 	case 3:
 		g_free (priv->wep_key3);
 		priv->wep_key3 = g_strdup (key);
-		g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
+		_notify (setting, PROP_WEP_KEY3);
 		break;
 	default:
 		g_assert_not_reached ();
@@ -874,6 +861,15 @@ need_secrets (NMSetting *setting)
 		goto no_secrets;
 	}
 
+	/* SAE, used in MESH and WPA3-Personal */
+	if (strcmp (priv->key_mgmt, "sae") == 0) {
+		if (!priv->psk || !*priv->psk) {
+			g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_PSK);
+			return secrets;
+		}
+		goto no_secrets;
+	}
+
 	/* LEAP */
 	if (   priv->auth_alg
 	    && !strcmp (priv->auth_alg, "leap")
@@ -905,7 +901,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 {
 	NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (setting);
 	NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self);
-	const char *valid_key_mgmt[] = { "none", "ieee8021x", "wpa-none", "wpa-psk", "wpa-eap", NULL };
+	const char *valid_key_mgmt[] = { "none", "ieee8021x", "wpa-none", "wpa-psk", "wpa-eap", "sae", NULL };
 	const char *valid_auth_algs[] = { "open", "shared", "leap", NULL };
 	const char *valid_protos[] = { "wpa", "rsn", NULL };
 	const char *valid_pairwise[] = { "tkip", "ccmp", NULL };
@@ -1083,36 +1079,22 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 	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")) {
+	    && !NM_IN_STRSET (priv->key_mgmt, "wpa-eap", "wpa-psk", "sae")) {
 		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");
+		             _("'%s' can only be used with 'wpa-eap', 'wpa-psk' or 'sae' key management "),
+		             priv->pmf == NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL ? "optional" : "required");
 		g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PMF);
 		return FALSE;
 	}
 
-	/* WPS */
-	if (priv->wps_method > NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN) {
-		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_WPS_METHOD);
-		return FALSE;
-	}
-
-	if (priv->wps_method & NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DISABLED && priv->wps_method != NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DISABLED) {
-		g_set_error_literal (error,
-		                     NM_CONNECTION_ERROR,
-		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		                     _("can't be simultaneously disabled and enabled"));
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WPS_METHOD);
+	if (!_nm_utils_wps_method_validate (priv->wps_method,
+	                                    NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+	                                    NM_SETTING_WIRELESS_SECURITY_WPS_METHOD,
+	                                    FALSE,
+	                                    error))
 		return FALSE;
-	}
 
 	return TRUE;
 }
@@ -1162,7 +1144,9 @@ verify_secrets (NMSetting *setting, NMConnection *connection, GError **error)
 		return FALSE;
 
 	/* WPA-PSK */
-	if (priv->psk && !nm_utils_wpa_psk_valid (priv->psk)) {
+	if (   priv->psk
+	    && strcmp (priv->key_mgmt, "sae") != 0
+	    && !nm_utils_wpa_psk_valid (priv->psk)) {
 		g_set_error_literal (error,
 		                     NM_CONNECTION_ERROR,
 		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
@@ -1177,83 +1161,56 @@ verify_secrets (NMSetting *setting, NMConnection *connection, GError **error)
 static gboolean
 get_secret_flags (NMSetting *setting,
                   const char *secret_name,
-                  gboolean verify_secret,
                   NMSettingSecretFlags *out_flags,
                   GError **error)
 {
-	NMSettingClass *setting_class;
-	gboolean verify_override = verify_secret;
-
-	/* There's only one 'flags' property for WEP keys, so alias all the WEP key
-	 * property names to that flags property.
-	 */
-	if (   !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0)
-	    || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1)
-	    || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2)
-	    || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) {
-		secret_name = "wep-key";
-		verify_override = FALSE; /* Already know it's a secret */
+	NMSettingSecretFlags flags;
+
+	if (NM_IN_STRSET (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0,
+	                               NM_SETTING_WIRELESS_SECURITY_WEP_KEY1,
+	                               NM_SETTING_WIRELESS_SECURITY_WEP_KEY2,
+	                               NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) {
+		/* There's only one 'flags' property for WEP keys, so alias all the WEP key
+		 * property names to that flags property. */
+		nm_assert (_nm_setting_property_is_regular_secret (setting, secret_name));
+		nm_assert (_nm_setting_property_is_regular_secret_flags (setting, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS));
+
+		g_object_get (G_OBJECT (setting),
+		              NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS,
+		              &flags,
+		              NULL);
+		NM_SET_OUT (out_flags, flags);
+		return TRUE;
 	}
 
-	/* Chain up to superclass with modified key name */
-	setting_class = NM_SETTING_CLASS (nm_setting_wireless_security_parent_class);
-	return setting_class->get_secret_flags (setting, secret_name, verify_override, out_flags, error);
+	return NM_SETTING_CLASS (nm_setting_wireless_security_parent_class)->get_secret_flags (setting, secret_name, out_flags, error);
 }
 
 static gboolean
 set_secret_flags (NMSetting *setting,
                   const char *secret_name,
-                  gboolean verify_secret,
                   NMSettingSecretFlags flags,
                   GError **error)
 {
-	NMSettingClass *setting_class;
-	gboolean verify_override = verify_secret;
-
-	/* There's only one 'flags' property for WEP keys, so alias all the WEP key
-	 * property names to that flags property.
-	 */
-	if (   !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0)
-	    || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1)
-	    || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2)
-	    || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) {
-		secret_name = "wep-key";
-		verify_override = FALSE; /* Already know it's a secret */
+	if (NM_IN_STRSET (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0,
+	                               NM_SETTING_WIRELESS_SECURITY_WEP_KEY1,
+	                               NM_SETTING_WIRELESS_SECURITY_WEP_KEY2,
+	                               NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) {
+		/* There's only one 'flags' property for WEP keys, so alias all the WEP key
+		 * property names to that flags property. */
+		nm_assert (_nm_setting_property_is_regular_secret (setting, secret_name));
+		nm_assert (_nm_setting_property_is_regular_secret_flags (setting, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS));
+
+		if (!nm_g_object_set_property_flags (G_OBJECT (setting),
+		                                     NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS,
+		                                     NM_TYPE_SETTING_SECRET_FLAGS,
+		                                     flags,
+		                                     error))
+			g_return_val_if_reached (FALSE);
+		return TRUE;
 	}
 
-	/* Chain up to superclass with modified key name */
-	setting_class = NM_SETTING_CLASS (nm_setting_wireless_security_parent_class);
-	return setting_class->set_secret_flags (setting, secret_name, verify_override, flags, error);
-}
-
-static void
-nm_setting_wireless_security_init (NMSettingWirelessSecurity *setting)
-{
-}
-
-static void
-finalize (GObject *object)
-{
-	NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (object);
-	NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self);
-
-	/* Strings first. g_free() already checks for NULLs so we don't have to */
-
-	g_free (priv->key_mgmt);
-	g_free (priv->auth_alg);
-	g_free (priv->leap_username);
-	g_free (priv->wep_key0);
-	g_free (priv->wep_key1);
-	g_free (priv->wep_key2);
-	g_free (priv->wep_key3);
-	g_free (priv->psk);
-	g_free (priv->leap_password);
-
-	g_slist_free_full (priv->proto, g_free);
-	g_slist_free_full (priv->pairwise, g_free);
-	g_slist_free_full (priv->group, g_free);
-
-	G_OBJECT_CLASS (nm_setting_wireless_security_parent_class)->finalize (object);
+	return NM_SETTING_CLASS (nm_setting_wireless_security_parent_class)->set_secret_flags (setting, secret_name, flags, error);
 }
 
 /* NMSettingWirelessSecurity:wep-key-type is an enum, but needs to be marshalled
@@ -1265,88 +1222,75 @@ wep_key_type_to_dbus (const GValue *from)
 	return g_variant_new_uint32 (g_value_get_enum (from));
 }
 
+/*****************************************************************************/
+
 static void
-set_property (GObject *object, guint prop_id,
-              const GValue *value, GParamSpec *pspec)
+get_property (GObject *object, guint prop_id,
+              GValue *value, GParamSpec *pspec)
 {
 	NMSettingWirelessSecurity *setting = NM_SETTING_WIRELESS_SECURITY (object);
 	NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
-	const char *str;
 
 	switch (prop_id) {
 	case PROP_KEY_MGMT:
-		g_free (priv->key_mgmt);
-		str = g_value_get_string (value);
-		priv->key_mgmt = str ? g_ascii_strdown (str, -1) : NULL;
+		g_value_set_string (value, priv->key_mgmt);
 		break;
 	case PROP_WEP_TX_KEYIDX:
-		priv->wep_tx_keyidx = g_value_get_uint (value);
+		g_value_set_uint (value, priv->wep_tx_keyidx);
 		break;
 	case PROP_AUTH_ALG:
-		g_free (priv->auth_alg);
-		str = g_value_get_string (value);
-		priv->auth_alg = str ? g_ascii_strdown (str, -1) : NULL;
+		g_value_set_string (value, priv->auth_alg);
 		break;
 	case PROP_PROTO:
-		g_slist_free_full (priv->proto, g_free);
-		priv->proto = _nm_utils_strv_to_slist (g_value_get_boxed (value), TRUE);
+		g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->proto, TRUE));
 		break;
 	case PROP_PAIRWISE:
-		g_slist_free_full (priv->pairwise, g_free);
-		priv->pairwise = _nm_utils_strv_to_slist (g_value_get_boxed (value), TRUE);
+		g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->pairwise, TRUE));
 		break;
 	case PROP_GROUP:
-		g_slist_free_full (priv->group, g_free);
-		priv->group = _nm_utils_strv_to_slist (g_value_get_boxed (value), TRUE);
+		g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->group, TRUE));
 		break;
 	case PROP_PMF:
-		priv->pmf = g_value_get_int (value);
+		g_value_set_int (value, nm_setting_wireless_security_get_pmf (setting));
 		break;
 	case PROP_LEAP_USERNAME:
-		g_free (priv->leap_username);
-		priv->leap_username = g_value_dup_string (value);
+		g_value_set_string (value, priv->leap_username);
 		break;
 	case PROP_WEP_KEY0:
-		g_free (priv->wep_key0);
-		priv->wep_key0 = g_value_dup_string (value);
+		g_value_set_string (value, priv->wep_key0);
 		break;
 	case PROP_WEP_KEY1:
-		g_free (priv->wep_key1);
-		priv->wep_key1 = g_value_dup_string (value);
+		g_value_set_string (value, priv->wep_key1);
 		break;
 	case PROP_WEP_KEY2:
-		g_free (priv->wep_key2);
-		priv->wep_key2 = g_value_dup_string (value);
+		g_value_set_string (value, priv->wep_key2);
 		break;
 	case PROP_WEP_KEY3:
-		g_free (priv->wep_key3);
-		priv->wep_key3 = g_value_dup_string (value);
+		g_value_set_string (value, priv->wep_key3);
 		break;
 	case PROP_WEP_KEY_FLAGS:
-		priv->wep_key_flags = g_value_get_flags (value);
+		g_value_set_flags (value, priv->wep_key_flags);
 		break;
 	case PROP_PSK:
-		g_free (priv->psk);
-		priv->psk = g_value_dup_string (value);
+		g_value_set_string (value, priv->psk);
 		break;
 	case PROP_PSK_FLAGS:
-		priv->psk_flags = g_value_get_flags (value);
+		g_value_set_flags (value, priv->psk_flags);
 		break;
 	case PROP_LEAP_PASSWORD:
-		g_free (priv->leap_password);
-		priv->leap_password = g_value_dup_string (value);
+		g_value_set_string (value, priv->leap_password);
 		break;
 	case PROP_LEAP_PASSWORD_FLAGS:
-		priv->leap_password_flags = g_value_get_flags (value);
+		g_value_set_flags (value, priv->leap_password_flags);
 		break;
 	case PROP_WEP_KEY_TYPE:
-		priv->wep_key_type = g_value_get_enum (value);
+		g_value_set_enum (value, priv->wep_key_type);
 		break;
 	case PROP_WPS_METHOD:
-		priv->wps_method = g_value_get_uint (value);
+		g_value_set_uint (value, priv->wps_method);
 		break;
 	case PROP_FILS:
-		priv->fils = g_value_get_int (value);
+		g_value_set_int (value, nm_setting_wireless_security_get_fils (setting));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1355,72 +1299,87 @@ set_property (GObject *object, guint prop_id,
 }
 
 static void
-get_property (GObject *object, guint prop_id,
-              GValue *value, GParamSpec *pspec)
+set_property (GObject *object, guint prop_id,
+              const GValue *value, GParamSpec *pspec)
 {
 	NMSettingWirelessSecurity *setting = NM_SETTING_WIRELESS_SECURITY (object);
 	NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
+	const char *str;
 
 	switch (prop_id) {
 	case PROP_KEY_MGMT:
-		g_value_set_string (value, priv->key_mgmt);
+		g_free (priv->key_mgmt);
+		str = g_value_get_string (value);
+		priv->key_mgmt = str ? g_ascii_strdown (str, -1) : NULL;
 		break;
 	case PROP_WEP_TX_KEYIDX:
-		g_value_set_uint (value, priv->wep_tx_keyidx);
+		priv->wep_tx_keyidx = g_value_get_uint (value);
 		break;
 	case PROP_AUTH_ALG:
-		g_value_set_string (value, priv->auth_alg);
+		g_free (priv->auth_alg);
+		str = g_value_get_string (value);
+		priv->auth_alg = str ? g_ascii_strdown (str, -1) : NULL;
 		break;
 	case PROP_PROTO:
-		g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->proto, TRUE));
+		g_slist_free_full (priv->proto, g_free);
+		priv->proto = _nm_utils_strv_to_slist (g_value_get_boxed (value), TRUE);
 		break;
 	case PROP_PAIRWISE:
-		g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->pairwise, TRUE));
+		g_slist_free_full (priv->pairwise, g_free);
+		priv->pairwise = _nm_utils_strv_to_slist (g_value_get_boxed (value), TRUE);
 		break;
 	case PROP_GROUP:
-		g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->group, TRUE));
+		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:
-		g_value_set_int (value, nm_setting_wireless_security_get_pmf (setting));
+		priv->pmf = g_value_get_int (value);
 		break;
 	case PROP_LEAP_USERNAME:
-		g_value_set_string (value, priv->leap_username);
+		g_free (priv->leap_username);
+		priv->leap_username = g_value_dup_string (value);
 		break;
 	case PROP_WEP_KEY0:
-		g_value_set_string (value, priv->wep_key0);
+		g_free (priv->wep_key0);
+		priv->wep_key0 = g_value_dup_string (value);
 		break;
 	case PROP_WEP_KEY1:
-		g_value_set_string (value, priv->wep_key1);
+		g_free (priv->wep_key1);
+		priv->wep_key1 = g_value_dup_string (value);
 		break;
 	case PROP_WEP_KEY2:
-		g_value_set_string (value, priv->wep_key2);
+		g_free (priv->wep_key2);
+		priv->wep_key2 = g_value_dup_string (value);
 		break;
 	case PROP_WEP_KEY3:
-		g_value_set_string (value, priv->wep_key3);
+		g_free (priv->wep_key3);
+		priv->wep_key3 = g_value_dup_string (value);
 		break;
 	case PROP_WEP_KEY_FLAGS:
-		g_value_set_flags (value, priv->wep_key_flags);
+		priv->wep_key_flags = g_value_get_flags (value);
 		break;
 	case PROP_PSK:
-		g_value_set_string (value, priv->psk);
+		g_free (priv->psk);
+		priv->psk = g_value_dup_string (value);
 		break;
 	case PROP_PSK_FLAGS:
-		g_value_set_flags (value, priv->psk_flags);
+		priv->psk_flags = g_value_get_flags (value);
 		break;
 	case PROP_LEAP_PASSWORD:
-		g_value_set_string (value, priv->leap_password);
+		g_free (priv->leap_password);
+		priv->leap_password = g_value_dup_string (value);
 		break;
 	case PROP_LEAP_PASSWORD_FLAGS:
-		g_value_set_flags (value, priv->leap_password_flags);
+		priv->leap_password_flags = g_value_get_flags (value);
 		break;
 	case PROP_WEP_KEY_TYPE:
-		g_value_set_enum (value, priv->wep_key_type);
+		priv->wep_key_type = g_value_get_enum (value);
 		break;
 	case PROP_WPS_METHOD:
-		g_value_set_uint (value, priv->wps_method);
+		priv->wps_method = g_value_get_uint (value);
 		break;
 	case PROP_FILS:
-		g_value_set_int (value, nm_setting_wireless_security_get_fils (setting));
+		priv->fils = g_value_get_int (value);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1428,6 +1387,49 @@ get_property (GObject *object, guint prop_id,
 	}
 }
 
+/*****************************************************************************/
+
+static void
+nm_setting_wireless_security_init (NMSettingWirelessSecurity *setting)
+{
+}
+
+/**
+ * nm_setting_wireless_security_new:
+ *
+ * Creates a new #NMSettingWirelessSecurity object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingWirelessSecurity object
+ **/
+NMSetting *
+nm_setting_wireless_security_new (void)
+{
+	return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRELESS_SECURITY, NULL);
+}
+
+static void
+finalize (GObject *object)
+{
+	NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (object);
+	NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self);
+
+	g_free (priv->key_mgmt);
+	g_free (priv->auth_alg);
+	g_free (priv->leap_username);
+	g_free (priv->wep_key0);
+	g_free (priv->wep_key1);
+	g_free (priv->wep_key2);
+	g_free (priv->wep_key3);
+	g_free (priv->psk);
+	g_free (priv->leap_password);
+
+	g_slist_free_full (priv->proto, g_free);
+	g_slist_free_full (priv->pairwise, g_free);
+	g_slist_free_full (priv->group, g_free);
+
+	G_OBJECT_CLASS (nm_setting_wireless_security_parent_class)->finalize (object);
+}
+
 static void
 nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 {
@@ -1437,8 +1439,8 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 
 	g_type_class_add_private (klass, sizeof (NMSettingWirelessSecurityPrivate));
 
-	object_class->set_property = set_property;
 	object_class->get_property = get_property;
+	object_class->set_property = set_property;
 	object_class->finalize     = finalize;
 
 	setting_class->verify           = verify;
@@ -1452,8 +1454,8 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 *
 	 * Key management used for the connection.  One of "none" (WEP), "ieee8021x"
 	 * (Dynamic WEP), "wpa-none" (Ad-Hoc WPA-PSK), "wpa-psk" (infrastructure
-	 * WPA-PSK), or "wpa-eap" (WPA-Enterprise).  This property must be set for
-	 * any Wi-Fi connection that uses security.
+	 * WPA-PSK), "sae" (SAE) or "wpa-eap" (WPA-Enterprise).
+	 * This property must be set for any Wi-Fi connection that uses security.
 	 **/
 	/* ---ifcfg-rh---
 	 * property: key-mgmt
@@ -1462,13 +1464,12 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: Key management menthod.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_KEY_MGMT,
-		 g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "", "",
-		                      NULL,
-		                      G_PARAM_READWRITE |
-		                      NM_SETTING_PARAM_REQUIRED |
-		                      G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_KEY_MGMT] =
+	    g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "", "",
+	                         NULL,
+	                         G_PARAM_READWRITE |
+	                         NM_SETTING_PARAM_REQUIRED |
+	                         G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:wep-tx-keyidx:
@@ -1486,13 +1487,12 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: Index of active WEP key.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_WEP_TX_KEYIDX,
-		 g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, "", "",
-		                    0, 3, 0,
-		                    G_PARAM_READWRITE |
-		                    G_PARAM_CONSTRUCT |
-		                    G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_WEP_TX_KEYIDX] =
+	    g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, "", "",
+	                       0, 3, 0,
+	                       G_PARAM_READWRITE |
+	                       G_PARAM_CONSTRUCT |
+	                       G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:auth-alg:
@@ -1510,12 +1510,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: Authentication algorithm for WEP.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_AUTH_ALG,
-		 g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "", "",
-		                      NULL,
-		                      G_PARAM_READWRITE |
-		                      G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_AUTH_ALG] =
+	    g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "", "",
+	                         NULL,
+	                         G_PARAM_READWRITE |
+	                         G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:proto:
@@ -1532,12 +1531,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: Allowed WPA protocols, WPA and WPA2 (RSN).
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_PROTO,
-		 g_param_spec_boxed (NM_SETTING_WIRELESS_SECURITY_PROTO, "", "",
-		                     G_TYPE_STRV,
-		                     G_PARAM_READWRITE |
-		                     G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_PROTO] =
+	    g_param_spec_boxed (NM_SETTING_WIRELESS_SECURITY_PROTO, "", "",
+	                        G_TYPE_STRV,
+	                        G_PARAM_READWRITE |
+	                        G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:pairwise:
@@ -1555,12 +1553,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 *   separated list.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_PAIRWISE,
-		 g_param_spec_boxed (NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "", "",
-		                     G_TYPE_STRV,
-		                     G_PARAM_READWRITE |
-		                     G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_PAIRWISE] =
+	    g_param_spec_boxed (NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "", "",
+	                        G_TYPE_STRV,
+	                        G_PARAM_READWRITE |
+	                        G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:group:
@@ -1578,12 +1575,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 *   separated list.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_GROUP,
-		 g_param_spec_boxed (NM_SETTING_WIRELESS_SECURITY_GROUP, "", "",
-		                     G_TYPE_STRV,
-		                     G_PARAM_READWRITE |
-		                     G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_GROUP] =
+	    g_param_spec_boxed (NM_SETTING_WIRELESS_SECURITY_GROUP, "", "",
+	                        G_TYPE_STRV,
+	                        G_PARAM_READWRITE |
+	                        G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:pmf:
@@ -1607,14 +1603,13 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * example: PMF=required
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_PMF,
-		 g_param_spec_int (NM_SETTING_WIRELESS_SECURITY_PMF, "", "",
-		                   G_MININT32, G_MAXINT32, 0,
-		                   G_PARAM_READWRITE |
-		                   G_PARAM_CONSTRUCT |
-		                   NM_SETTING_PARAM_FUZZY_IGNORE |
-		                   G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_PMF] =
+	    g_param_spec_int (NM_SETTING_WIRELESS_SECURITY_PMF, "", "",
+	                      G_MININT32, G_MAXINT32, 0,
+	                      G_PARAM_READWRITE |
+	                      G_PARAM_CONSTRUCT |
+	                      NM_SETTING_PARAM_FUZZY_IGNORE |
+	                      G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:leap-username:
@@ -1628,12 +1623,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: Login name for LEAP.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_LEAP_USERNAME,
-		 g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "", "",
-		                      NULL,
-		                      G_PARAM_READWRITE |
-		                      G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_LEAP_USERNAME] =
+	    g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "", "",
+	                         NULL,
+	                         G_PARAM_READWRITE |
+	                         G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:wep-key0:
@@ -1647,13 +1641,12 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: The first WEP key (used in most networks). See also DEFAULTKEY for key index.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_WEP_KEY0,
-		 g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "", "",
-		                      NULL,
-		                      G_PARAM_READWRITE |
-		                      NM_SETTING_PARAM_SECRET |
-		                      G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_WEP_KEY0] =
+	    g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "", "",
+	                         NULL,
+	                         G_PARAM_READWRITE |
+	                         NM_SETTING_PARAM_SECRET |
+	                         G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:wep-key1:
@@ -1667,13 +1660,12 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: WEP key with index 1. See also DEFAULTKEY for key index.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_WEP_KEY1,
-		 g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, "", "",
-		                      NULL,
-		                      G_PARAM_READWRITE |
-		                      NM_SETTING_PARAM_SECRET |
-		                      G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_WEP_KEY1] =
+	    g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, "", "",
+	                         NULL,
+	                         G_PARAM_READWRITE |
+	                         NM_SETTING_PARAM_SECRET |
+	                         G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:wep-key2:
@@ -1687,13 +1679,12 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: WEP key with index 2. See also DEFAULTKEY for key index.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_WEP_KEY2,
-		 g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, "", "",
-		                      NULL,
-		                      G_PARAM_READWRITE |
-		                      NM_SETTING_PARAM_SECRET |
-		                      G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_WEP_KEY2] =
+	    g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, "", "",
+	                         NULL,
+	                         G_PARAM_READWRITE |
+	                         NM_SETTING_PARAM_SECRET |
+	                         G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:wep-key3:
@@ -1707,13 +1698,12 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: WEP key with index 3. See also DEFAULTKEY for key index.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_WEP_KEY3,
-		 g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, "", "",
-		                      NULL,
-		                      G_PARAM_READWRITE |
-		                      NM_SETTING_PARAM_SECRET |
-		                      G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_WEP_KEY3] =
+	    g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, "", "",
+	                         NULL,
+	                         G_PARAM_READWRITE |
+	                         NM_SETTING_PARAM_SECRET |
+	                         G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:wep-key-flags:
@@ -1729,23 +1719,21 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: Password flags for KEY<i>, KEY_PASSPHRASE<i> password.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_WEP_KEY_FLAGS,
-		 g_param_spec_flags (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, "", "",
-		                     NM_TYPE_SETTING_SECRET_FLAGS,
-		                     NM_SETTING_SECRET_FLAG_NONE,
-		                     G_PARAM_READWRITE |
-		                     G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_WEP_KEY_FLAGS] =
+	    g_param_spec_flags (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, "", "",
+	                        NM_TYPE_SETTING_SECRET_FLAGS,
+	                        NM_SETTING_SECRET_FLAG_NONE,
+	                        G_PARAM_READWRITE |
+	                        G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:psk:
 	 *
-	 * 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.
+	 * Pre-Shared-Key for WPA networks. For WPA-PSK, it's either an ASCII
+	 * passphrase of 8 to 63 characters that is (as specified in the 802.11i
+	 * standard) hashed to derive the actual key, or the key in form of 64
+	 * hexadecimal character. The WPA3-Personal networks use a passphrase
+	 * of any length for SAE authentication.
 	 **/
 	/* ---ifcfg-rh---
 	 * property: psk
@@ -1753,13 +1741,12 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: Pre-Shared-Key for WPA networks.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_PSK,
-		 g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PSK, "", "",
-		                      NULL,
-		                      G_PARAM_READWRITE |
-		                      NM_SETTING_PARAM_SECRET |
-		                      G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_PSK] =
+	    g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PSK, "", "",
+	                         NULL,
+	                         G_PARAM_READWRITE |
+	                         NM_SETTING_PARAM_SECRET |
+	                         G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:psk-flags:
@@ -1775,13 +1762,12 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * example: WPA_PSK_FLAGS=user
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_PSK_FLAGS,
-		 g_param_spec_flags (NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, "", "",
-		                     NM_TYPE_SETTING_SECRET_FLAGS,
-		                     NM_SETTING_SECRET_FLAG_NONE,
-		                     G_PARAM_READWRITE |
-		                     G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_PSK_FLAGS] =
+	    g_param_spec_flags (NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, "", "",
+	                        NM_TYPE_SETTING_SECRET_FLAGS,
+	                        NM_SETTING_SECRET_FLAG_NONE,
+	                        G_PARAM_READWRITE |
+	                        G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:leap-password:
@@ -1796,13 +1782,12 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 *  lookaside file, or it can be owned by a secret agent.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_LEAP_PASSWORD,
-		 g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "", "",
-		                      NULL,
-		                      G_PARAM_READWRITE |
-		                      NM_SETTING_PARAM_SECRET |
-		                      G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_LEAP_PASSWORD] =
+	    g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "", "",
+	                         NULL,
+	                         G_PARAM_READWRITE |
+	                         NM_SETTING_PARAM_SECRET |
+	                         G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:leap-password-flags:
@@ -1817,13 +1802,12 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * description: Password flags for IEEE_8021X_PASSWORD_FLAGS.
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_LEAP_PASSWORD_FLAGS,
-		 g_param_spec_flags (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, "", "",
-		                     NM_TYPE_SETTING_SECRET_FLAGS,
-		                     NM_SETTING_SECRET_FLAG_NONE,
-		                     G_PARAM_READWRITE |
-		                     G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_LEAP_PASSWORD_FLAGS] =
+	    g_param_spec_flags (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, "", "",
+	                        NM_TYPE_SETTING_SECRET_FLAGS,
+	                        NM_SETTING_SECRET_FLAG_NONE,
+	                        G_PARAM_READWRITE |
+	                        G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:wep-key-type:
@@ -1845,18 +1829,16 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * example: KEY1=s:ahoj, KEY1=0a1c45bc02, KEY_PASSPHRASE1=mysupersecretkey
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_WEP_KEY_TYPE,
-		 g_param_spec_enum (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, "", "",
-		                    NM_TYPE_WEP_KEY_TYPE,
-		                    NM_WEP_KEY_TYPE_UNKNOWN,
-		                    G_PARAM_READWRITE |
-		                    G_PARAM_CONSTRUCT |
-		                    G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_WEP_KEY_TYPE] =
+	    g_param_spec_enum (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, "", "",
+	                       NM_TYPE_WEP_KEY_TYPE,
+	                       NM_WEP_KEY_TYPE_UNKNOWN,
+	                       G_PARAM_READWRITE |
+	                       G_PARAM_CONSTRUCT |
+	                       G_PARAM_STATIC_STRINGS);
 
 	_properties_override_add_transform (properties_override,
-	                                    g_object_class_find_property (G_OBJECT_CLASS (setting_class),
-	                                                                  NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE),
+	                                    obj_properties[PROP_WEP_KEY_TYPE],
 	                                    G_VARIANT_TYPE_UINT32,
 	                                    wep_key_type_to_dbus,
 	                                    NULL);
@@ -1882,14 +1864,13 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * example: WPS_METHOD=disabled, WPS_METHOD="pin pbc"
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_WPS_METHOD,
-		 g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WPS_METHOD, "", "",
-		                    0, G_MAXUINT32, NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT,
-		                    G_PARAM_READWRITE |
-		                    G_PARAM_CONSTRUCT |
-		                    NM_SETTING_PARAM_FUZZY_IGNORE |
-		                    G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_WPS_METHOD] =
+	    g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WPS_METHOD, "", "",
+	                       0, G_MAXUINT32, NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT,
+	                       G_PARAM_READWRITE |
+	                       G_PARAM_CONSTRUCT |
+	                       NM_SETTING_PARAM_FUZZY_IGNORE |
+	                       G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * NMSettingWirelessSecurity:fils:
@@ -1913,14 +1894,15 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *klass)
 	 * example: FILS=required
 	 * ---end---
 	 */
-	g_object_class_install_property
-		(object_class, PROP_FILS,
-		 g_param_spec_int (NM_SETTING_WIRELESS_SECURITY_FILS, "", "",
-		                   G_MININT32, G_MAXINT32, 0,
-		                   G_PARAM_READWRITE |
-		                   G_PARAM_CONSTRUCT |
-		                   NM_SETTING_PARAM_FUZZY_IGNORE |
-		                   G_PARAM_STATIC_STRINGS));
+	obj_properties[PROP_FILS] =
+	    g_param_spec_int (NM_SETTING_WIRELESS_SECURITY_FILS, "", "",
+	                      G_MININT32, G_MAXINT32, 0,
+	                      G_PARAM_READWRITE |
+	                      G_PARAM_CONSTRUCT |
+	                      NM_SETTING_PARAM_FUZZY_IGNORE |
+	                      G_PARAM_STATIC_STRINGS);
+
+	g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
 
 	_nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_WIRELESS_SECURITY,
 	                               NULL, properties_override);