summary refs log tree commit diff
path: root/libnm-core
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-core')
-rw-r--r--libnm-core/Makefile.in34
-rw-r--r--libnm-core/nm-connection.c68
-rw-r--r--libnm-core/nm-core-enum-types.c4
-rw-r--r--libnm-core/nm-core-internal.h4
-rw-r--r--libnm-core/nm-dbus-interface.h10
-rw-r--r--libnm-core/nm-errors.c2
-rw-r--r--libnm-core/nm-setting-8021x.c6
-rw-r--r--libnm-core/nm-setting-adsl.c11
-rw-r--r--libnm-core/nm-setting-bond.c35
-rw-r--r--libnm-core/nm-setting-bridge.c10
-rw-r--r--libnm-core/nm-setting-cdma.c11
-rw-r--r--libnm-core/nm-setting-connection.c3
-rw-r--r--libnm-core/nm-setting-dcb.c14
-rw-r--r--libnm-core/nm-setting-gsm.c11
-rw-r--r--libnm-core/nm-setting-ip4-config.c9
-rw-r--r--libnm-core/nm-setting-ip6-config.c9
-rw-r--r--libnm-core/nm-setting-team-port.c12
-rw-r--r--libnm-core/nm-setting-wired.c33
-rw-r--r--libnm-core/nm-setting-wireless-security.c52
-rw-r--r--libnm-core/nm-setting.c112
-rw-r--r--libnm-core/nm-utils.c75
-rw-r--r--libnm-core/nm-version.h4
-rw-r--r--libnm-core/nm-version.h.in2
-rw-r--r--libnm-core/tests/Makefile.am1
-rw-r--r--libnm-core/tests/Makefile.in32
-rw-r--r--libnm-core/tests/test-crypto.c3
-rw-r--r--libnm-core/tests/test-general.c202
-rw-r--r--libnm-core/tests/test-secrets.c7
-rw-r--r--libnm-core/tests/test-setting-8021x.c3
-rw-r--r--libnm-core/tests/test-setting-dcb.c11
30 files changed, 603 insertions, 187 deletions
diff --git a/libnm-core/Makefile.in b/libnm-core/Makefile.in
index 8ec1414e..7ceb3cfa 100644
--- a/libnm-core/Makefile.in
+++ b/libnm-core/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,17 @@
 
 
 VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -83,9 +93,6 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-DIST_COMMON = $(srcdir)/Makefile.libnm-core $(srcdir)/Makefile.in \
-	$(srcdir)/Makefile.am $(srcdir)/nm-version.h.in \
-	$(top_srcdir)/build-aux/depcomp $(libnminclude_HEADERS)
 @WITH_GNUTLS_TRUE@am__append_1 = $(LIBGCRYPT_CFLAGS) $(GNUTLS_CFLAGS)
 @WITH_GNUTLS_TRUE@am__append_2 = crypto_gnutls.c
 @WITH_GNUTLS_TRUE@am__append_3 = $(LIBGCRYPT_LIBS) $(GNUTLS_LIBS)
@@ -109,6 +116,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \
 	$(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(libnminclude_HEADERS) \
+	$(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES = nm-version.h
@@ -274,6 +283,8 @@ am__define_uniq_tagged_files = \
 ETAGS = etags
 CTAGS = ctags
 DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.libnm-core \
+	$(srcdir)/nm-version.h.in $(top_srcdir)/build-aux/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -325,7 +336,6 @@ CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
-DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
 DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@
 DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@
@@ -360,6 +370,7 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
 GNUTLS_LIBS = @GNUTLS_LIBS@
 GREP = @GREP@
 GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
 GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
@@ -684,7 +695,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Ma
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libnm-core/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu libnm-core/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -693,7 +703,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
-$(srcdir)/Makefile.libnm-core:
+$(srcdir)/Makefile.libnm-core $(am__empty):
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -769,14 +779,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -1343,6 +1353,8 @@ uninstall-am: uninstall-libnmincludeHEADERS
 	pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
 	uninstall-libnmincludeHEADERS
 
+.PRECIOUS: Makefile
+
 include $(GLIB_MAKEFILE)
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c
index 907713bd..acdc8b89 100644
--- a/libnm-core/nm-connection.c
+++ b/libnm-core/nm-connection.c
@@ -30,6 +30,7 @@
 #include "nm-utils.h"
 #include "nm-setting-private.h"
 #include "nm-core-internal.h"
+#include "gsystem-local-alloc.h"
 
 /**
  * SECTION:nm-connection
@@ -304,6 +305,8 @@ nm_connection_replace_settings (NMConnection *connection,
 	for (s = settings; s; s = s->next)
 		_nm_connection_add_setting (connection, s->data);
 
+	g_slist_free (settings);
+
 	if (changed)
 		g_signal_emit (connection, signals[CHANGED], 0);
 	return TRUE;
@@ -723,6 +726,27 @@ _normalize_infiniband_mtu (NMConnection *self, GHashTable *parameters)
 	return FALSE;
 }
 
+static gboolean
+_normalize_bond_mode (NMConnection *self, GHashTable *parameters)
+{
+	NMSettingBond *s_bond = nm_connection_get_setting_bond (self);
+
+	/* Convert mode from numeric to string notation */
+	if (s_bond) {
+		const char *mode = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE);
+		int mode_int = nm_utils_bond_mode_string_to_int (mode);
+
+		if (mode_int != -1) {
+			const char *mode_new = nm_utils_bond_mode_int_to_string (mode_int);
+			if (g_strcmp0 (mode_new, mode) != 0) {
+				nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_MODE, mode_new);
+				return TRUE;
+			}
+		}
+	}
+	return FALSE;
+}
+
 /**
  * nm_connection_verify:
  * @connection: the #NMConnection to verify
@@ -936,6 +960,7 @@ nm_connection_normalize (NMConnection *connection,
 	was_modified |= _normalize_connection_slave_type (connection);
 	was_modified |= _normalize_ip_config (connection, parameters);
 	was_modified |= _normalize_infiniband_mtu (connection, parameters);
+	was_modified |= _normalize_bond_mode (connection, parameters);
 
 	/* Verify anew. */
 	success = _nm_connection_verify (connection, error);
@@ -1282,6 +1307,19 @@ nm_connection_is_type (NMConnection *connection, const char *type)
 	return (g_strcmp0 (type2, type) == 0);
 }
 
+static int
+_for_each_sort (NMSetting **p_a, NMSetting **p_b, void *unused)
+{
+	NMSetting *a = *p_a;
+	NMSetting *b = *p_b;
+	int c;
+
+	c = _nm_setting_compare_priority (a, b);
+	if (c != 0)
+		return c;
+	return strcmp (nm_setting_get_name (a), nm_setting_get_name (b));
+}
+
 /**
  * nm_connection_for_each_setting_value:
  * @connection: the #NMConnection
@@ -1296,15 +1334,39 @@ nm_connection_for_each_setting_value (NMConnection *connection,
                                       NMSettingValueIterFn func,
                                       gpointer user_data)
 {
+	NMConnectionPrivate *priv;
+	gs_free NMSetting **arr_free = NULL;
+	NMSetting *arr_temp[20], **arr;
 	GHashTableIter iter;
 	gpointer value;
+	guint i, size;
 
 	g_return_if_fail (NM_IS_CONNECTION (connection));
 	g_return_if_fail (func != NULL);
 
-	g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings);
-	while (g_hash_table_iter_next (&iter, NULL, &value))
-		nm_setting_enumerate_values (NM_SETTING (value), func, user_data);
+	priv = NM_CONNECTION_GET_PRIVATE (connection);
+
+	size = g_hash_table_size (priv->settings);
+	if (!size)
+		return;
+
+	if (size > G_N_ELEMENTS (arr_temp))
+		arr = arr_free = g_new (NMSetting *, size);
+	else
+		arr = arr_temp;
+
+	g_hash_table_iter_init (&iter, priv->settings);
+	for (i = 0; g_hash_table_iter_next (&iter, NULL, &value); i++)
+		arr[i] = NM_SETTING (value);
+	g_assert (i == size);
+
+	/* sort the settings. This has an effect on the order in which keyfile
+	 * prints them. */
+	if (size > 1)
+		g_qsort_with_data (arr, size, sizeof (NMSetting *), (GCompareDataFunc) _for_each_sort, NULL);
+
+	for (i = 0; i < size; i++)
+		nm_setting_enumerate_values (arr[i], func, user_data);
 }
 
 /**
diff --git a/libnm-core/nm-core-enum-types.c b/libnm-core/nm-core-enum-types.c
index d7d4291b..e4cf177c 100644
--- a/libnm-core/nm-core-enum-types.c
+++ b/libnm-core/nm-core-enum-types.c
@@ -180,6 +180,9 @@ nm_device_wifi_capabilities_get_type (void)
         { NM_WIFI_DEVICE_CAP_RSN, "NM_WIFI_DEVICE_CAP_RSN", "rsn" },
         { NM_WIFI_DEVICE_CAP_AP, "NM_WIFI_DEVICE_CAP_AP", "ap" },
         { NM_WIFI_DEVICE_CAP_ADHOC, "NM_WIFI_DEVICE_CAP_ADHOC", "adhoc" },
+        { NM_WIFI_DEVICE_CAP_FREQ_VALID, "NM_WIFI_DEVICE_CAP_FREQ_VALID", "freq-valid" },
+        { NM_WIFI_DEVICE_CAP_FREQ_2GHZ, "NM_WIFI_DEVICE_CAP_FREQ_2GHZ", "freq-2ghz" },
+        { NM_WIFI_DEVICE_CAP_FREQ_5GHZ, "NM_WIFI_DEVICE_CAP_FREQ_5GHZ", "freq-5ghz" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
@@ -397,6 +400,7 @@ nm_device_state_reason_get_type (void)
         { NM_DEVICE_STATE_REASON_MODEM_FAILED, "NM_DEVICE_STATE_REASON_MODEM_FAILED", "modem-failed" },
         { NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, "NM_DEVICE_STATE_REASON_MODEM_AVAILABLE", "modem-available" },
         { NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT, "NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT", "sim-pin-incorrect" },
+        { NM_DEVICE_STATE_REASON_NEW_ACTIVATION, "NM_DEVICE_STATE_REASON_NEW_ACTIVATION", "new-activation" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 5af90267..9f4b33e3 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -132,4 +132,8 @@ GByteArray *nm_utils_rsa_key_encrypt (const guint8 *data,
                                       char **out_password,
                                       GError **error);
 
+/* These are public API in NM 1.2, but private on nm-1-0. */
+int nm_utils_bond_mode_string_to_int (const char *mode);
+const char *nm_utils_bond_mode_int_to_string (int mode);
+
 #endif
diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h
index dd2b70a0..9bab80f3 100644
--- a/libnm-core/nm-dbus-interface.h
+++ b/libnm-core/nm-dbus-interface.h
@@ -199,6 +199,9 @@ typedef enum { /*< flags >*/
  * @NM_WIFI_DEVICE_CAP_RSN: device supports WPA2/RSN authentication
  * @NM_WIFI_DEVICE_CAP_AP: device supports Access Point mode
  * @NM_WIFI_DEVICE_CAP_ADHOC: device supports Ad-Hoc mode
+ * @NM_WIFI_DEVICE_CAP_FREQ_VALID: device reports frequency capabilities
+ * @NM_WIFI_DEVICE_CAP_FREQ_2GHZ: device supports 2.4GHz frequencies
+ * @NM_WIFI_DEVICE_CAP_FREQ_5GHZ: device supports 5GHz frequencies
  *
  * 802.11 specific device encryption and authentication capabilities.
  *
@@ -213,7 +216,10 @@ typedef enum { /*< flags >*/
 	NM_WIFI_DEVICE_CAP_WPA           = 0x00000010,
 	NM_WIFI_DEVICE_CAP_RSN           = 0x00000020,
 	NM_WIFI_DEVICE_CAP_AP            = 0x00000040,
-	NM_WIFI_DEVICE_CAP_ADHOC         = 0x00000080
+	NM_WIFI_DEVICE_CAP_ADHOC         = 0x00000080,
+	NM_WIFI_DEVICE_CAP_FREQ_VALID    = 0x00000100,
+	NM_WIFI_DEVICE_CAP_FREQ_2GHZ     = 0x00000200,
+	NM_WIFI_DEVICE_CAP_FREQ_5GHZ     = 0x00000400,
 } NMDeviceWifiCapabilities;
 
 
@@ -460,6 +466,7 @@ typedef enum {
  * @NM_DEVICE_STATE_REASON_MODEM_FAILED: Modem failed or no longer available
  * @NM_DEVICE_STATE_REASON_MODEM_AVAILABLE: Modem now ready and available
  * @NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: SIM PIN was incorrect
+ * @NM_DEVICE_STATE_REASON_NEW_ACTIVATION: New connection activation was enqueued
  *
  * Device state change reason codes
  *
@@ -526,6 +533,7 @@ typedef enum {
 	NM_DEVICE_STATE_REASON_MODEM_FAILED = 57,
 	NM_DEVICE_STATE_REASON_MODEM_AVAILABLE = 58,
 	NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT = 59,
+	NM_DEVICE_STATE_REASON_NEW_ACTIVATION = 60,
 } NMDeviceStateReason;
 
 
diff --git a/libnm-core/nm-errors.c b/libnm-core/nm-errors.c
index 229f14a0..3b1b1bc9 100644
--- a/libnm-core/nm-errors.c
+++ b/libnm-core/nm-errors.c
@@ -85,6 +85,6 @@ _nm_dbus_errors_init (void)
 	                       NM_DBUS_INTERFACE_SETTINGS,
 	                       NM_TYPE_SETTINGS_ERROR);
 	register_error_domain (NM_VPN_PLUGIN_ERROR,
-	                       NM_VPN_DBUS_PLUGIN_INTERFACE,
+	                       NM_DBUS_VPN_ERROR_PREFIX,
 	                       NM_TYPE_VPN_PLUGIN_ERROR);
 }
diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c
index f739f2c7..41559e0c 100644
--- a/libnm-core/nm-setting-8021x.c
+++ b/libnm-core/nm-setting-8021x.c
@@ -1884,6 +1884,7 @@ nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting)
 			g_error_free (error);
 			return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
 		}
+		g_error_free (error);
 		return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY;
 	default:
 		break;
@@ -2164,6 +2165,7 @@ nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting)
 			g_error_free (error);
 			return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
 		}
+		g_error_free (error);
 		return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY;
 	default:
 		break;
@@ -3258,8 +3260,8 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
 	 * no verification of the server certificate's altSubjectName is performed.
 	 **/
 	/* ---ifcfg-rh---
-	 * property: altubject-matches
-	 * variable: IEEE_8021X_AlTSUBJECT_MATCHES(+)
+	 * property: altsubject-matches
+	 * variable: IEEE_8021X_ALTSUBJECT_MATCHES(+)
 	 * description: List of strings to be matched against the altSubjectName.
 	 * example: IEEE_8021X_ALTSUBJECT_MATCHES="s1.domain.cc"
 	 * ---end---
diff --git a/libnm-core/nm-setting-adsl.c b/libnm-core/nm-setting-adsl.c
index 00bcef54..2e71f8e7 100644
--- a/libnm-core/nm-setting-adsl.c
+++ b/libnm-core/nm-setting-adsl.c
@@ -199,15 +199,6 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 		return FALSE;
 	}
 
-	if (priv->password && !strlen (priv->password)) {
-		g_set_error_literal (error,
-		                     NM_CONNECTION_ERROR,
-		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		                     _("property is empty"));
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PASSWORD);
-		return FALSE;
-	}
-
 	if (   !priv->protocol
 	    || (   strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA)
 	        && strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE)
@@ -242,7 +233,7 @@ need_secrets (NMSetting *setting)
 	NMSettingAdslPrivate *priv = NM_SETTING_ADSL_GET_PRIVATE (setting);
 	GPtrArray *secrets = NULL;
 
-	if (priv->password)
+	if (priv->password && *priv->password)
 		return NULL;
 
 	if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) {
diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c
index bb053125..5441a090 100644
--- a/libnm-core/nm-setting-bond.c
+++ b/libnm-core/nm-setting-bond.c
@@ -440,15 +440,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 	NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (setting);
 	GHashTableIter iter;
 	const char *key, *value;
-	const char *valid_modes[] = { "balance-rr",
-	                              "active-backup",
-	                              "balance-xor",
-	                              "broadcast",
-	                              "802.3ad",
-	                              "balance-tlb",
-	                              "balance-alb",
-	                              NULL };
-	int miimon = 0, arp_interval = 0;
+	int mode, miimon = 0, arp_interval = 0;
+	const char *mode_orig, *mode_new;
 	const char *arp_ip_target = NULL;
 	const char *lacp_rate;
 	const char *primary;
@@ -484,7 +477,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
 	}
 
-	value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MODE);
+	/* Verify bond mode */
+	mode_orig = value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MODE);
 	if (!value) {
 		g_set_error (error,
 		             NM_CONNECTION_ERROR,
@@ -494,7 +488,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
 		return FALSE;
 	}
-	if (!_nm_utils_string_in_list (value, valid_modes)) {
+	mode = nm_utils_bond_mode_string_to_int (value);
+	if (mode == -1) {
 		g_set_error (error,
 		             NM_CONNECTION_ERROR,
 		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
@@ -503,6 +498,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
 		return FALSE;
 	}
+	mode_new = value = nm_utils_bond_mode_int_to_string (mode);
 
 	/* Make sure mode is compatible with other settings */
 	if (   strcmp (value, "balance-alb") == 0
@@ -645,7 +641,22 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 		return FALSE;
 	}
 
-	return _nm_connection_verify_required_interface_name (connection, error);
+	if (!_nm_connection_verify_required_interface_name (connection, error))
+		return FALSE;
+
+	/* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */
+
+	if (g_strcmp0 (mode_orig, mode_new) != 0) {
+		g_set_error (error,
+		             NM_CONNECTION_ERROR,
+		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
+		             _("'%s' option should be string"),
+		             NM_SETTING_BOND_OPTION_MODE);
+		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
+		return NM_SETTING_VERIFY_NORMALIZABLE;
+	}
+
+	return TRUE;
 }
 
 static void
diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c
index 51c6ac5a..d00271b7 100644
--- a/libnm-core/nm-setting-bridge.c
+++ b/libnm-core/nm-setting-bridge.c
@@ -196,10 +196,14 @@ static inline gboolean
 check_range (guint32 val,
              guint32 min,
              guint32 max,
+             gboolean zero,
              const char *prop,
              GError **error)
 {
-	if ((val != 0) && (val < min || val > max)) {
+	if (zero && val == 0)
+		return TRUE;
+
+	if (val < min || val > max) {
 		g_set_error (error,
 		             NM_CONNECTION_ERROR,
 		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
@@ -228,6 +232,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 	if (!check_range (priv->forward_delay,
 	                  BR_MIN_FORWARD_DELAY,
 	                  BR_MAX_FORWARD_DELAY,
+	                  !priv->stp,
 	                  NM_SETTING_BRIDGE_FORWARD_DELAY,
 	                  error))
 		return FALSE;
@@ -235,6 +240,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 	if (!check_range (priv->hello_time,
 	                  BR_MIN_HELLO_TIME,
 	                  BR_MAX_HELLO_TIME,
+	                  !priv->stp,
 	                  NM_SETTING_BRIDGE_HELLO_TIME,
 	                  error))
 		return FALSE;
@@ -242,6 +248,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 	if (!check_range (priv->max_age,
 	                  BR_MIN_MAX_AGE,
 	                  BR_MAX_MAX_AGE,
+	                  !priv->stp,
 	                  NM_SETTING_BRIDGE_MAX_AGE,
 	                  error))
 		return FALSE;
@@ -249,6 +256,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 	if (!check_range (priv->ageing_time,
 	                  BR_MIN_AGEING_TIME,
 	                  BR_MAX_AGEING_TIME,
+	                  !priv->stp,
 	                  NM_SETTING_BRIDGE_AGEING_TIME,
 	                  error))
 		return FALSE;
diff --git a/libnm-core/nm-setting-cdma.c b/libnm-core/nm-setting-cdma.c
index ebbbda74..ecc387c8 100644
--- a/libnm-core/nm-setting-cdma.c
+++ b/libnm-core/nm-setting-cdma.c
@@ -160,15 +160,6 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 		return FALSE;
 	}
 
-	if (priv->password && !strlen (priv->password)) {
-		g_set_error_literal (error,
-		                     NM_CONNECTION_ERROR,
-		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		                     _("property is empty"));
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_PASSWORD);
-		return FALSE;
-	}
-
 	return TRUE;
 }
 
@@ -178,7 +169,7 @@ need_secrets (NMSetting *setting)
 	NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE (setting);
 	GPtrArray *secrets = NULL;
 
-	if (priv->password)
+	if (priv->password && *priv->password)
 		return NULL;
 
 	if (priv->username) {
diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c
index 01f5d423..7bc927bc 100644
--- a/libnm-core/nm-setting-connection.c
+++ b/libnm-core/nm-setting-connection.c
@@ -968,8 +968,9 @@ find_virtual_interface_name (GVariant *connection_dict)
 
 	/* All of the deprecated virtual interface name properties were named "interface-name". */
 	if (!g_variant_lookup (setting_dict, "interface-name", "&s", &interface_name))
-		return NULL;
+		interface_name = NULL;
 
+	g_variant_unref (setting_dict);
 	return interface_name;
 }
 
diff --git a/libnm-core/nm-setting-dcb.c b/libnm-core/nm-setting-dcb.c
index a4fa00c8..915cc41f 100644
--- a/libnm-core/nm-setting-dcb.c
+++ b/libnm-core/nm-setting-dcb.c
@@ -50,7 +50,7 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_DCB)
 typedef struct {
 	NMSettingDcbFlags app_fcoe_flags;
 	gint              app_fcoe_priority;
-	const char *      app_fcoe_mode;
+	char *            app_fcoe_mode;
 
 	NMSettingDcbFlags app_iscsi_flags;
 	gint              app_iscsi_priority;
@@ -793,6 +793,7 @@ set_property (GObject *object, guint prop_id,
 		priv->app_fcoe_priority = g_value_get_int (value);
 		break;
 	case PROP_APP_FCOE_MODE:
+		g_free (priv->app_fcoe_mode);
 		priv->app_fcoe_mode = g_value_dup_string (value);
 		break;
 	case PROP_APP_ISCSI_FLAGS:
@@ -897,6 +898,16 @@ get_property (GObject *object, guint prop_id,
 }
 
 static void
+finalize (GObject *object)
+{
+	NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE (object);
+
+	g_free (priv->app_fcoe_mode);
+
+	G_OBJECT_CLASS (nm_setting_dcb_parent_class)->finalize (object);
+}
+
+static void
 nm_setting_dcb_class_init (NMSettingDcbClass *setting_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
@@ -907,6 +918,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class)
 	/* virtual methods */
 	object_class->set_property = set_property;
 	object_class->get_property = get_property;
+	object_class->finalize = finalize;
 	parent_class->verify       = verify;
 
 	/* Properties */
diff --git a/libnm-core/nm-setting-gsm.c b/libnm-core/nm-setting-gsm.c
index 22f8cdba..36557a25 100644
--- a/libnm-core/nm-setting-gsm.c
+++ b/libnm-core/nm-setting-gsm.c
@@ -285,15 +285,6 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 		return FALSE;
 	}
 
-	if (priv->password && !strlen (priv->password)) {
-		g_set_error_literal (error,
-		                     NM_CONNECTION_ERROR,
-		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		                     _("property is empty"));
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_USERNAME);
-		return FALSE;
-	}
-
 	if (priv->network_id) {
 		guint32 nid_len = strlen (priv->network_id);
 		guint32 i;
@@ -331,7 +322,7 @@ need_secrets (NMSetting *setting)
 	NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (setting);
 	GPtrArray *secrets = NULL;
 
-	if (priv->password)
+	if (priv->password && *priv->password)
 		return NULL;
 
 	if (priv->username) {
diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c
index 68619267..81cc1f88 100644
--- a/libnm-core/nm-setting-ip4-config.c
+++ b/libnm-core/nm-setting-ip4-config.c
@@ -571,6 +571,15 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class)
 	 * ---end---
 	 */
 
+	/* ---ifcfg-rh---
+	 * property: route-metric
+	 * variable: IPV4_ROUTE_METRIC(+)
+	 * default: -1
+	 * description: IPV4_ROUTE_METRIC is the default IPv4 metric for routes on this connection.
+	 *   If set to -1, a default metric based on the device type is used.
+	 * ---end---
+	 */
+
 	/**
 	 * NMSettingIP4Config:dhcp-client-id:
 	 *
diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c
index f5d90334..29ca5515 100644
--- a/libnm-core/nm-setting-ip6-config.c
+++ b/libnm-core/nm-setting-ip6-config.c
@@ -488,6 +488,15 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
 	 * ---end---
 	 */
 
+	/* ---ifcfg-rh---
+	 * property: route-metric
+	 * variable: IPV6_ROUTE_METRIC(+)
+	 * default: -1
+	 * description: IPV6_ROUTE_METRIC is the default IPv6 metric for routes on this connection.
+	 *   If set to -1, a default metric based on the device type is used.
+	 * ---end---
+	 */
+
 	/**
 	 * NMSettingIP6Config:ip6-privacy:
 	 *
diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c
index b5125753..7fbf8620 100644
--- a/libnm-core/nm-setting-team-port.c
+++ b/libnm-core/nm-setting-team-port.c
@@ -130,6 +130,7 @@ set_property (GObject *object, guint prop_id,
 
 	switch (prop_id) {
 	case PROP_CONFIG:
+		g_free (priv->config);
 		priv->config = g_value_dup_string (value);
 		break;
 	default:
@@ -155,6 +156,16 @@ get_property (GObject *object, guint prop_id,
 }
 
 static void
+finalize (GObject *object)
+{
+	NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (object);
+
+	g_free (priv->config);
+
+	G_OBJECT_CLASS (nm_setting_team_port_parent_class)->finalize (object);
+}
+
+static void
 nm_setting_team_port_class_init (NMSettingTeamPortClass *setting_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
@@ -165,6 +176,7 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *setting_class)
 	/* virtual methods */
 	object_class->set_property = set_property;
 	object_class->get_property = get_property;
+	object_class->finalize = finalize;
 	parent_class->verify       = verify;
 
 	/* Properties */
diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c
index ac143e45..2a747940 100644
--- a/libnm-core/nm-setting-wired.c
+++ b/libnm-core/nm-setting-wired.c
@@ -434,27 +434,24 @@ nm_setting_wired_get_s390_option (NMSettingWired *setting,
                                   const char **out_key,
                                   const char **out_value)
 {
-	NMSettingWiredPrivate *priv;
-	guint32 num_keys;
-	GList *keys;
-	const char *_key = NULL, *_value = NULL;
+	const char *_key, *_value;
+	GHashTableIter iter;
+	guint i = 0;
 
 	g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
 
-	priv = NM_SETTING_WIRED_GET_PRIVATE (setting);
-
-	num_keys = nm_setting_wired_get_num_s390_options (setting);
-	g_return_val_if_fail (idx < num_keys, FALSE);
-
-	keys = g_hash_table_get_keys (priv->s390_options);
-	_key = g_list_nth_data (keys, idx);
-	_value = g_hash_table_lookup (priv->s390_options, _key);
-
-	if (out_key)
-		*out_key = _key;
-	if (out_value)
-		*out_value = _value;
-	return TRUE;
+	g_hash_table_iter_init (&iter, NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options);
+	while (g_hash_table_iter_next (&iter, (gpointer) &_key, (gpointer) &_value)) {
+		if (i == idx) {
+			if (out_key)
+				*out_key = _key;
+			if (out_value)
+				*out_value = _value;
+			return TRUE;
+		}
+		i++;
+	}
+	g_return_val_if_reached (FALSE);
 }
 
 /**
diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c
index c95f9243..a56a8e97 100644
--- a/libnm-core/nm-setting-wireless-security.c
+++ b/libnm-core/nm-setting-wireless-security.c
@@ -822,7 +822,7 @@ need_secrets (NMSetting *setting)
 	if (   priv->auth_alg
 	    && !strcmp (priv->auth_alg, "leap")
 	    && !strcmp (priv->key_mgmt, "ieee8021x")) {
-		if (!priv->leap_password || !strlen (priv->leap_password)) {
+		if (!priv->leap_password || !*priv->leap_password) {
 			g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD);
 			return secrets;
 		}
@@ -893,14 +893,6 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME);
 			return FALSE;
 		}
-		if (priv->leap_password && !strlen (priv->leap_password)) {
-			g_set_error_literal (error,
-			                     NM_CONNECTION_ERROR,
-			                     NM_CONNECTION_ERROR_MISSING_PROPERTY,
-			                     _("property is empty"));
-			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD);
-			return FALSE;
-		}
 	} else {
 		if (   (strcmp (priv->key_mgmt, "ieee8021x") == 0)
 		    || (strcmp (priv->key_mgmt, "wpa-eap") == 0)) {
@@ -945,39 +937,6 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 		return FALSE;
 	}
 
-	if (priv->wep_key0 && !nm_utils_wep_key_valid (priv->wep_key0, priv->wep_key_type)) {
-		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_WEP_KEY0);
-		return FALSE;
-	}
-	if (priv->wep_key1 && !nm_utils_wep_key_valid (priv->wep_key1, priv->wep_key_type)) {
-		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_WEP_KEY1);
-		return FALSE;
-	}
-	if (priv->wep_key2 && !nm_utils_wep_key_valid (priv->wep_key2, priv->wep_key_type)) {
-		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_WEP_KEY2);
-		return FALSE;
-	}
-	if (priv->wep_key3 && !nm_utils_wep_key_valid (priv->wep_key3, priv->wep_key_type)) {
-		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_WEP_KEY3);
-		return FALSE;
-	}
-
 	if (priv->auth_alg && !_nm_utils_string_in_list (priv->auth_alg, valid_auth_algs)) {
 		g_set_error_literal (error,
 		                     NM_CONNECTION_ERROR,
@@ -987,15 +946,6 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 		return FALSE;
 	}
 
-	if (priv->psk && !nm_utils_wpa_psk_valid (priv->psk)) {
-		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_PSK);
-		return FALSE;
-	}
-
 	if (priv->proto && !_nm_utils_string_slist_validate (priv->proto, valid_protos)) {
 		g_set_error_literal (error,
 		                     NM_CONNECTION_ERROR,
diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c
index 037baa6b..b78d9376 100644
--- a/libnm-core/nm-setting.c
+++ b/libnm-core/nm-setting.c
@@ -660,17 +660,40 @@ get_property_for_dbus (NMSetting *setting,
 	return dbus_value;
 }
 
-static void
-set_property_from_dbus (const NMSettingProperty *property, GVariant *src_value, GValue *dst_value)
+static gboolean
+set_property_from_dbus (const NMSettingProperty *property,
+                        GVariant *src_value,
+                        GValue *dst_value)
 {
-	g_return_if_fail (property->param_spec != NULL);
+	g_return_val_if_fail (property->param_spec != NULL, FALSE);
+
+	if (property->from_dbus) {
+		if (!g_variant_type_equal (g_variant_get_type (src_value), property->dbus_type))
+			return FALSE;
 
-	if (property->from_dbus)
 		property->from_dbus (src_value, dst_value);
-	else if (dst_value->g_type == G_TYPE_BYTES)
+	} else if (dst_value->g_type == G_TYPE_BYTES) {
+		if (!g_variant_is_of_type (src_value, G_VARIANT_TYPE_BYTESTRING))
+			return FALSE;
+
 		_nm_utils_bytes_from_dbus (src_value, dst_value);
-	else
-		g_dbus_gvariant_to_gvalue (src_value, dst_value);
+	} else {
+		GValue tmp = G_VALUE_INIT;
+
+		g_dbus_gvariant_to_gvalue (src_value, &tmp);
+		if (G_VALUE_TYPE (&tmp) == G_VALUE_TYPE (dst_value))
+			*dst_value = tmp;
+		else {
+			gboolean success;
+
+			success = g_value_transform (&tmp, dst_value);
+			g_value_unset (&tmp);
+			if (!success)
+				return FALSE;
+		}
+	}
+
+	return TRUE;
 }
 
 
@@ -766,7 +789,6 @@ _nm_setting_new_from_dbus (GType setting_type,
                            GVariant *connection_dict,
                            GError **error)
 {
-	NMSettingClass *class;
 	NMSetting *setting;
 	const NMSettingProperty *properties;
 	guint n_properties;
@@ -781,11 +803,6 @@ _nm_setting_new_from_dbus (GType setting_type,
 	if (connection_dict)
 		g_return_val_if_fail (g_variant_is_of_type (connection_dict, NM_VARIANT_TYPE_CONNECTION), NULL);
 
-	/* g_type_class_ref() ensures the setting class is created if it hasn't
-	 * already been used.
-	 */
-	class = g_type_class_ref (setting_type);
-
 	/* Build the setting object from the properties we know about; we assume
 	 * that any propreties in @setting_dict that we don't know about can
 	 * either be ignored or else has a backward-compatibility equivalent
@@ -793,12 +810,33 @@ _nm_setting_new_from_dbus (GType setting_type,
 	 */
 	setting = (NMSetting *) g_object_new (setting_type, NULL);
 
-	properties = nm_setting_class_get_properties (class, &n_properties);
+	properties = nm_setting_class_get_properties (NM_SETTING_GET_CLASS (setting), &n_properties);
 	for (i = 0; i < n_properties; i++) {
 		const NMSettingProperty *property = &properties[i];
-		GVariant *value = g_variant_lookup_value (setting_dict, property->name, NULL);
+		GVariant *value;
+
+		if (property->param_spec && !(property->param_spec->flags & G_PARAM_WRITABLE))
+			continue;
+
+		value = g_variant_lookup_value (setting_dict, property->name, NULL);
 
 		if (value && property->set_func) {
+			if (!g_variant_type_equal (g_variant_get_type (value), property->dbus_type)) {
+			property_type_error:
+				g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
+				             _("can't set property of type '%s' from value of type '%s'"),
+				             property->dbus_type ?
+				                 g_variant_type_peek_string (property->dbus_type) :
+				                 property->param_spec ?
+				                     g_type_name (property->param_spec->value_type) : "(unknown)",
+				             g_variant_get_type_string (value));
+				g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), property->name);
+
+				g_variant_unref (value);
+				g_object_unref (setting);
+				return NULL;
+			}
+
 			property->set_func (setting,
 			                    connection_dict,
 			                    property->name,
@@ -810,11 +848,10 @@ _nm_setting_new_from_dbus (GType setting_type,
 		} else if (value && property->param_spec) {
 			GValue object_value = { 0, };
 
-			if (!(property->param_spec->flags & G_PARAM_WRITABLE))
-				continue;
-
 			g_value_init (&object_value, property->param_spec->value_type);
-			set_property_from_dbus (property, value, &object_value);
+			if (!set_property_from_dbus (property, value, &object_value))
+				goto property_type_error;
+
 			g_object_set_property (G_OBJECT (setting), property->param_spec->name, &object_value);
 			g_value_unset (&object_value);
 		}
@@ -823,8 +860,6 @@ _nm_setting_new_from_dbus (GType setting_type,
 			g_variant_unref (value);
 	}
 
-	g_type_class_unref (class);
-
 	return setting;
 }
 
@@ -1279,6 +1314,33 @@ nm_setting_diff (NMSetting *a,
 	return !(*results);
 }
 
+#define CMP_AND_RETURN(n_a, n_b, name) \
+	G_STMT_START { \
+		gboolean _is = (strcmp (n_a, ""name) == 0); \
+		\
+		if (_is || (strcmp (n_b, ""name) == 0)) \
+			return _is ? -1 : 1; \
+	} G_STMT_END
+
+static int
+_enumerate_values_sort (GParamSpec **p_a, GParamSpec **p_b, GType *p_type)
+{
+	const char *n_a = (*p_a)->name;
+	const char *n_b = (*p_b)->name;
+	int c = strcmp (n_a, n_b);
+
+	if (c) {
+		if (*p_type == NM_TYPE_SETTING_CONNECTION) {
+			/* for [connection], report first id, uuid, type in that order. */
+			CMP_AND_RETURN (n_a, n_b, NM_SETTING_CONNECTION_ID);
+			CMP_AND_RETURN (n_a, n_b, NM_SETTING_CONNECTION_UUID);
+			CMP_AND_RETURN (n_a, n_b, NM_SETTING_CONNECTION_TYPE);
+		}
+	}
+	return c;
+}
+#undef CMP_AND_RETURN
+
 /**
  * nm_setting_enumerate_values:
  * @setting: the #NMSetting
@@ -1296,11 +1358,19 @@ nm_setting_enumerate_values (NMSetting *setting,
 	GParamSpec **property_specs;
 	guint n_property_specs;
 	int i;
+	GType type;
 
 	g_return_if_fail (NM_IS_SETTING (setting));
 	g_return_if_fail (func != NULL);
 
 	property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs);
+
+	/* sort the properties. This has an effect on the order in which keyfile
+	 * prints them. */
+	type = G_OBJECT_TYPE (setting);
+	g_qsort_with_data (property_specs, n_property_specs, sizeof (gpointer),
+	                   (GCompareDataFunc) _enumerate_values_sort, &type);
+
 	for (i = 0; i < n_property_specs; i++) {
 		GParamSpec *prop_spec = property_specs[i];
 		GValue value = G_VALUE_INIT;
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index e14775ff..5d4f1163 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -998,9 +998,13 @@ nm_utils_wep_key_valid (const char *key, NMWepKeyType wep_type)
 	if (!key)
 		return FALSE;
 
+	if (wep_type == NM_WEP_KEY_TYPE_UNKNOWN) {
+		return nm_utils_wep_key_valid (key, NM_WEP_KEY_TYPE_KEY) ||
+		       nm_utils_wep_key_valid (key, NM_WEP_KEY_TYPE_PASSPHRASE);
+	}
+
 	keylen = strlen (key);
-	if (   wep_type == NM_WEP_KEY_TYPE_KEY
-	    || wep_type == NM_WEP_KEY_TYPE_UNKNOWN) {
+	if (wep_type == NM_WEP_KEY_TYPE_KEY) {
 		if (keylen == 10 || keylen == 26) {
 			/* Hex key */
 			for (i = 0; i < keylen; i++) {
@@ -1015,7 +1019,6 @@ nm_utils_wep_key_valid (const char *key, NMWepKeyType wep_type)
 			}
 		} else
 			return FALSE;
-
 	} else if (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE) {
 		if (!keylen || keylen > 64)
 			return FALSE;
@@ -1802,6 +1805,7 @@ nm_utils_ip_addresses_from_variant (GVariant *value,
 			g_variant_unref (attr_val);
 		}
 
+		g_variant_unref (addr_var);
 		g_ptr_array_add (addresses, addr);
 	}
 
@@ -2218,7 +2222,7 @@ nm_utils_file_is_pkcs12 (const char *filename)
  *   for additional checks. This check is performed after the check for
  *   @file_test_flags. You cannot omit both @file_test_flags and @predicate.
  * @user_data: (closure): (allow-none): user data for @predicate function.
- * @error: on failure, a "not found" error using @error_domain and @error_code
+ * @error: (allow-none): on failure, set a "not found" error %G_IO_ERROR %G_IO_ERROR_NOT_FOUND.
  *
  * Searches for a @progname file in a list of search @paths.
  *
@@ -2771,7 +2775,7 @@ nm_utils_hwaddr_canonical (const char *asc, gssize length)
 	if (nm_utils_hwaddr_aton (asc, buf, length) == NULL)
 		return NULL;
 
-	return g_strdup (nm_utils_hwaddr_ntoa (buf, length));
+	return nm_utils_hwaddr_ntoa (buf, length);
 }
 
 /* This is used to possibly canonicalize values passed to MAC address property
@@ -3213,3 +3217,64 @@ nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_typ
 		return FALSE;
 	}
 }
+
+typedef struct {
+	const char *str;
+	const char *num;
+} BondMode;
+
+static BondMode bond_mode_table[] = {
+	[0] = { "balance-rr",    "0" },
+	[1] = { "active-backup", "1" },
+	[2] = { "balance-xor",   "2" },
+	[3] = { "broadcast",     "3" },
+	[4] = { "802.3ad",       "4" },
+	[5] = { "balance-tlb",   "5" },
+	[6] = { "balance-alb",   "6" },
+};
+
+/**
+ * nm_utils_bond_mode_int_to_string:
+ * @mode: bonding mode as a numeric value
+ *
+ * Convert bonding mode from integer value to descriptive name.
+ * See https://www.kernel.org/doc/Documentation/networking/bonding.txt for
+ * available modes.
+ *
+ * Returns: bonding mode string, or NULL on error
+*/
+
+const char *
+nm_utils_bond_mode_int_to_string (int mode)
+{
+	if (mode >= 0 && mode < G_N_ELEMENTS (bond_mode_table))
+		return bond_mode_table[mode].str;
+	return NULL;
+}
+
+/**
+ * nm_utils_bond_mode_string_to_int:
+ * @mode: bonding mode as string
+ *
+ * Convert bonding mode from string representation to numeric value.
+ * See https://www.kernel.org/doc/Documentation/networking/bonding.txt for
+ * available modes.
+ * The @mode string can be either a descriptive name or a number (as string).
+ *
+ * Returns: numeric bond mode, or -1 on error
+*/
+int
+nm_utils_bond_mode_string_to_int (const char *mode)
+{
+	int i;
+
+	if (!mode || !*mode)
+		return -1;
+
+	for (i = 0; i < G_N_ELEMENTS (bond_mode_table); i++) {
+		if (   strcmp (mode, bond_mode_table[i].str) == 0
+		    || strcmp (mode, bond_mode_table[i].num) == 0)
+			return i;
+	}
+	return -1;
+}
diff --git a/libnm-core/nm-version.h b/libnm-core/nm-version.h
index 39cfd63f..46103544 100644
--- a/libnm-core/nm-version.h
+++ b/libnm-core/nm-version.h
@@ -43,7 +43,7 @@
  * Evaluates to the micro version number of NetworkManager which this source
  * compiled against.
  */
-#define NM_MICRO_VERSION (0)
+#define NM_MICRO_VERSION (2)
 
 /**
  * NM_CHECK_VERSION:
@@ -68,7 +68,7 @@
 #define NM_VERSION_0_9_10 (NM_ENCODE_VERSION (0, 9, 10))
 #define NM_VERSION_1_0    (NM_ENCODE_VERSION (1, 0, 0))
 
-#define NM_VERSION_CUR_STABLE  NM_VERSION_0_9_10
+#define NM_VERSION_CUR_STABLE  NM_VERSION_1_0
 #define NM_VERSION_NEXT_STABLE NM_VERSION_1_0
 
 #if !defined (NM_VERSION_MIN_REQUIRED) || (NM_VERSION_MIN_REQUIRED == 0)
diff --git a/libnm-core/nm-version.h.in b/libnm-core/nm-version.h.in
index 0a33ac29..bbbf993a 100644
--- a/libnm-core/nm-version.h.in
+++ b/libnm-core/nm-version.h.in
@@ -68,7 +68,7 @@
 #define NM_VERSION_0_9_10 (NM_ENCODE_VERSION (0, 9, 10))
 #define NM_VERSION_1_0    (NM_ENCODE_VERSION (1, 0, 0))
 
-#define NM_VERSION_CUR_STABLE  NM_VERSION_0_9_10
+#define NM_VERSION_CUR_STABLE  NM_VERSION_1_0
 #define NM_VERSION_NEXT_STABLE NM_VERSION_1_0
 
 #if !defined (NM_VERSION_MIN_REQUIRED) || (NM_VERSION_MIN_REQUIRED == 0)
diff --git a/libnm-core/tests/Makefile.am b/libnm-core/tests/Makefile.am
index a21c131c..79aa73db 100644
--- a/libnm-core/tests/Makefile.am
+++ b/libnm-core/tests/Makefile.am
@@ -24,6 +24,7 @@ LDADD = \
 	$(top_builddir)/libnm-core/libnm-core.la \
 	$(GLIB_LIBS)
 
+@VALGRIND_RULES@
 TESTS = $(noinst_PROGRAMS)
 
 endif
diff --git a/libnm-core/tests/Makefile.in b/libnm-core/tests/Makefile.in
index b62df8b4..c2b15c6a 100644
--- a/libnm-core/tests/Makefile.in
+++ b/libnm-core/tests/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -15,7 +15,17 @@
 @SET_MAKE@
 
 VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -85,8 +95,6 @@ host_triplet = @host@
 @ENABLE_TESTS_TRUE@	test-setting-dcb$(EXEEXT) \
 @ENABLE_TESTS_TRUE@	test-settings-defaults$(EXEEXT)
 subdir = libnm-core/tests
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/build-aux/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \
 	$(top_srcdir)/m4/compiler_warnings.m4 \
@@ -103,6 +111,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \
 	$(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -241,6 +250,8 @@ am__tty_colors = { \
     std=''; \
   fi; \
 }
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+	$(top_srcdir)/build-aux/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
@@ -267,7 +278,6 @@ CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
-DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
 DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@
 DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@
@@ -302,6 +312,7 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
 GNUTLS_LIBS = @GNUTLS_LIBS@
 GREP = @GREP@
 GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
 GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
@@ -559,7 +570,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libnm-core/tests/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu libnm-core/tests/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -634,14 +644,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -953,6 +963,10 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags tags-am uninstall uninstall-am
 
+.PRECIOUS: Makefile
+
+
+@ENABLE_TESTS_TRUE@@VALGRIND_RULES@
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/libnm-core/tests/test-crypto.c b/libnm-core/tests/test-crypto.c
index 1c8ae477..e4ca8086 100644
--- a/libnm-core/tests/test-crypto.c
+++ b/libnm-core/tests/test-crypto.c
@@ -98,7 +98,7 @@ out:
 static void
 test_cert (gconstpointer test_data)
 {
-	char *path;
+	gs_free char *path = NULL;
 	GByteArray *array;
 	NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
 	GError *error = NULL;
@@ -226,6 +226,7 @@ test_is_pkcs12 (const char *path, gboolean expect_fail)
 	if (expect_fail) {
 		g_assert_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_INVALID_DATA);
 		g_assert (!is_pkcs12);
+		g_clear_error (&error);
 	} else {
 		g_assert_no_error (error);
 		g_assert (is_pkcs12);
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index d309c800..7df4e57a 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -25,6 +25,7 @@
 #include <string.h>
 
 #include <nm-utils.h>
+#include "gsystem-local-alloc.h"
 
 #include "nm-setting-private.h"
 #include "nm-utils.h"
@@ -648,7 +649,7 @@ test_setting_ip4_config_address_data (void)
 static void
 test_setting_gsm_apn_spaces (void)
 {
-	NMSettingGsm *s_gsm;
+	gs_unref_object NMSettingGsm *s_gsm = NULL;
 	const char *tmp;
 
 	s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
@@ -676,7 +677,7 @@ test_setting_gsm_apn_spaces (void)
 static void
 test_setting_gsm_apn_bad_chars (void)
 {
-	NMSettingGsm *s_gsm;
+	gs_unref_object NMSettingGsm *s_gsm = NULL;
 
 	s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
 	ASSERT (s_gsm != NULL,
@@ -714,7 +715,7 @@ test_setting_gsm_apn_bad_chars (void)
 static void
 test_setting_gsm_apn_underscore (void)
 {
-	NMSettingGsm *s_gsm;
+	gs_unref_object NMSettingGsm *s_gsm = NULL;
 
 	s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
 	g_assert (s_gsm);
@@ -729,7 +730,7 @@ test_setting_gsm_apn_underscore (void)
 static void
 test_setting_gsm_without_number (void)
 {
-	NMSettingGsm *s_gsm;
+	gs_unref_object NMSettingGsm *s_gsm = NULL;
 
 	s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
 	g_assert (s_gsm);
@@ -1140,6 +1141,183 @@ test_setting_new_from_dbus_enum (void)
 	g_object_unref (s_serial);
 }
 
+static void
+test_setting_new_from_dbus_bad (void)
+{
+	NMSetting *setting;
+	NMConnection *conn;
+	GBytes *ssid;
+	GPtrArray *addrs;
+	GVariant *orig_dict, *dict;
+	GError *error = NULL;
+
+	/* We want to test:
+	 * - ordinary scalar properties
+	 * - string properties
+	 * - GBytes-valued properties (which are handled specially by set_property_from_dbus())
+	 * - enum/flags-valued properties
+	 * - overridden properties
+	 * - transformed properties
+	 *
+	 * No single setting class has examples of all of these, so we need two settings.
+	 */
+
+	conn = nm_simple_connection_new ();
+
+	setting = nm_setting_connection_new ();
+	g_object_set (setting,
+	              NM_SETTING_CONNECTION_ID, "test",
+	              NM_SETTING_CONNECTION_UUID, "83c5a841-1759-4cdb-bfce-8d4087956497",
+	              NULL);
+	nm_connection_add_setting (conn, setting);
+
+	setting = nm_setting_wireless_new ();
+	ssid = g_bytes_new ("my-ssid", 7);
+	g_object_set (setting,
+	              /* scalar */
+	              NM_SETTING_WIRELESS_RATE, 100,
+	              /* string */
+	              NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA,
+	              /* GBytes */
+	              NM_SETTING_WIRELESS_SSID, ssid,
+	              /* transformed */
+	              NM_SETTING_WIRELESS_BSSID, "00:11:22:33:44:55",
+	              NULL);
+	g_bytes_unref (ssid);
+	nm_connection_add_setting (conn, setting);
+
+	setting = nm_setting_ip6_config_new ();
+	addrs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
+	g_ptr_array_add (addrs, nm_ip_address_new (AF_INET6, "1234::5678", 64, NULL));
+	g_object_set (setting,
+	              /* enum */
+	              NM_SETTING_IP6_CONFIG_IP6_PRIVACY, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR,
+	              /* overridden */
+	              NM_SETTING_IP_CONFIG_ADDRESSES, addrs,
+	              /* (needed in order to verify()) */
+	              NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
+	              NULL);
+	g_ptr_array_unref (addrs);
+	nm_connection_add_setting (conn, setting);
+
+	orig_dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL);
+	g_object_unref (conn);
+
+	/* sanity-check */
+	conn = nm_simple_connection_new_from_dbus (orig_dict, &error);
+	g_assert_no_error (error);
+	g_assert (conn);
+	g_object_unref (conn);
+
+	/* Compatible mismatches */
+
+	dict = g_variant_ref (orig_dict);
+	NMTST_VARIANT_EDITOR (dict,
+	                      NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
+	                                                     NM_SETTING_WIRELESS_RATE,
+	                                                     "i", 10);
+	                      );
+	conn = nm_simple_connection_new_from_dbus (dict, &error);
+	g_assert (conn);
+	g_assert_no_error (error);
+	setting = nm_connection_get_setting (conn, NM_TYPE_SETTING_WIRELESS);
+	g_assert (setting);
+	g_assert_cmpint (nm_setting_wireless_get_rate (NM_SETTING_WIRELESS (setting)), ==, 10);
+	g_object_unref (conn);
+	g_variant_unref (dict);
+
+	dict = g_variant_ref (orig_dict);
+	NMTST_VARIANT_EDITOR (dict,
+	                      NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
+	                                                     NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
+	                                                     "i", NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR);
+	                      );
+	conn = nm_simple_connection_new_from_dbus (dict, &error);
+	g_assert (conn);
+	g_assert_no_error (error);
+	setting = nm_connection_get_setting (conn, NM_TYPE_SETTING_IP6_CONFIG);
+	g_assert (setting);
+	g_assert_cmpint (nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (setting)), ==, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR);
+	g_object_unref (conn);
+	g_variant_unref (dict);
+
+	/* Incompatible mismatches */
+
+	dict = g_variant_ref (orig_dict);
+	NMTST_VARIANT_EDITOR (dict,
+	                      NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
+	                                                     NM_SETTING_WIRELESS_RATE,
+	                                                     "s", "ten");
+	                      );
+	conn = nm_simple_connection_new_from_dbus (dict, &error);
+	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
+	g_assert (g_str_has_prefix (error->message, "802-11-wireless.rate:"));
+	g_clear_error (&error);
+	g_variant_unref (dict);
+
+	dict = g_variant_ref (orig_dict);
+	NMTST_VARIANT_EDITOR (dict,
+	                      NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
+	                                                     NM_SETTING_WIRELESS_MODE,
+	                                                     "b", FALSE);
+	                      );
+	conn = nm_simple_connection_new_from_dbus (dict, &error);
+	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
+	g_assert (g_str_has_prefix (error->message, "802-11-wireless.mode:"));
+	g_clear_error (&error);
+	g_variant_unref (dict);
+
+	dict = g_variant_ref (orig_dict);
+	NMTST_VARIANT_EDITOR (dict,
+	                      NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
+	                                                     NM_SETTING_WIRELESS_SSID,
+	                                                     "s", "fred");
+	                      );
+	conn = nm_simple_connection_new_from_dbus (dict, &error);
+	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
+	g_assert (g_str_has_prefix (error->message, "802-11-wireless.ssid:"));
+	g_clear_error (&error);
+	g_variant_unref (dict);
+
+	dict = g_variant_ref (orig_dict);
+	NMTST_VARIANT_EDITOR (dict,
+	                      NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
+	                                                     NM_SETTING_WIRELESS_BSSID,
+	                                                     "i", 42);
+	                      );
+	conn = nm_simple_connection_new_from_dbus (dict, &error);
+	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
+	g_assert (g_str_has_prefix (error->message, "802-11-wireless.bssid:"));
+	g_clear_error (&error);
+	g_variant_unref (dict);
+
+	dict = g_variant_ref (orig_dict);
+	NMTST_VARIANT_EDITOR (dict,
+	                      NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
+	                                                     NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
+	                                                     "s", "private");
+	                      );
+	conn = nm_simple_connection_new_from_dbus (dict, &error);
+	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
+	g_assert (g_str_has_prefix (error->message, "ipv6.ip6-privacy:"));
+	g_clear_error (&error);
+	g_variant_unref (dict);
+
+	dict = g_variant_ref (orig_dict);
+	NMTST_VARIANT_EDITOR (dict,
+	                      NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
+	                                                     NM_SETTING_IP_CONFIG_ADDRESSES,
+	                                                     "s", "1234::5678");
+	                      );
+	conn = nm_simple_connection_new_from_dbus (dict, &error);
+	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
+	g_assert (g_str_has_prefix (error->message, "ipv6.addresses:"));
+	g_clear_error (&error);
+	g_variant_unref (dict);
+
+	g_variant_unref (orig_dict);
+}
+
 static NMConnection *
 new_test_connection (void)
 {
@@ -1374,6 +1552,7 @@ test_connection_replace_settings_bad (void)
 	connection = new_test_connection ();
 	success = nm_connection_replace_settings (connection, new_settings, &error);
 	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING);
+	g_clear_error (&error);
 	g_assert (!success);
 
 	g_assert (nm_connection_verify (connection, NULL));
@@ -2211,7 +2390,7 @@ test_connection_bad_base_types (void)
 static void
 test_setting_compare_id (void)
 {
-	NMSetting *old, *new;
+	gs_unref_object NMSetting *old = NULL, *new = NULL;
 	gboolean success;
 
 	old = nm_setting_connection_new ();
@@ -2235,7 +2414,7 @@ test_setting_compare_id (void)
 static void
 test_setting_compare_timestamp (void)
 {
-	NMSetting *old, *new;
+	gs_unref_object NMSetting *old = NULL, *new = NULL;
 	gboolean success;
 
 	old = nm_setting_connection_new ();
@@ -2280,7 +2459,7 @@ static void
 test_setting_compare_secrets (gconstpointer test_data)
 {
 	const TestDataCompareSecrets *data = test_data;
-	NMSetting *old, *new;
+	gs_unref_object NMSetting *old = NULL, *new = NULL;
 	gboolean success;
 
 	/* Make sure that a connection with transient/unsaved secrets compares
@@ -2311,7 +2490,7 @@ static void
 test_setting_compare_vpn_secrets (gconstpointer test_data)
 {
 	const TestDataCompareSecrets *data = test_data;
-	NMSetting *old, *new;
+	gs_unref_object NMSetting *old = NULL, *new = NULL;
 	gboolean success;
 
 	/* Make sure that a connection with transient/unsaved secrets compares
@@ -2587,7 +2766,7 @@ test_setting_connection_changed_signal (void)
 	NMConnection *connection;
 	gboolean changed = FALSE;
 	NMSettingConnection *s_con;
-	char *uuid;
+	gs_free char *uuid = NULL;
 
 	connection = nm_simple_connection_new ();
 	g_signal_connect (connection,
@@ -2993,7 +3172,7 @@ test_setting_802_1x_changed_signal (void)
 static void
 test_setting_old_uuid (void)
 {
-	NMSetting *setting;
+	gs_unref_object NMSetting *setting = NULL;
 
 	/* NetworkManager-0.9.4.0 generated 40-character UUIDs with no dashes,
 	 * like this one. Test that we maintain compatibility. */
@@ -3702,6 +3881,7 @@ test_setting_ip6_gateway (void)
 	value = g_variant_lookup_value (ip6_dict, NM_SETTING_IP_CONFIG_GATEWAY, G_VARIANT_TYPE_STRING);
 	g_assert (value != NULL);
 	g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "abcd::1");
+	g_variant_unref (value);
 
 	value = g_variant_lookup_value (ip6_dict, NM_SETTING_IP_CONFIG_ADDRESSES, G_VARIANT_TYPE ("a(ayuay)"));
 	g_assert (value != NULL);
@@ -3798,6 +3978,7 @@ test_hexstr2bin (void)
 			g_assert (b);
 			g_assert_cmpint (g_bytes_get_size (b), ==, items[i].expected_len);
 			g_assert (memcmp (g_bytes_get_data (b, NULL), items[i].expected, g_bytes_get_size (b)) == 0);
+			g_bytes_unref (b);
 		} else
 			g_assert (b == NULL);
 	}
@@ -3901,6 +4082,7 @@ int main (int argc, char **argv)
 	g_test_add_func ("/core/general/test_setting_new_from_dbus", test_setting_new_from_dbus);
 	g_test_add_func ("/core/general/test_setting_new_from_dbus_transform", test_setting_new_from_dbus_transform);
 	g_test_add_func ("/core/general/test_setting_new_from_dbus_enum", test_setting_new_from_dbus_enum);
+	g_test_add_func ("/core/general/test_setting_new_from_dbus_bad", test_setting_new_from_dbus_bad);
 	g_test_add_func ("/core/general/test_connection_replace_settings", test_connection_replace_settings);
 	g_test_add_func ("/core/general/test_connection_replace_settings_from_connection", test_connection_replace_settings_from_connection);
 	g_test_add_func ("/core/general/test_connection_replace_settings_bad", test_connection_replace_settings_bad);
diff --git a/libnm-core/tests/test-secrets.c b/libnm-core/tests/test-secrets.c
index 1254dfff..a915ae7d 100644
--- a/libnm-core/tests/test-secrets.c
+++ b/libnm-core/tests/test-secrets.c
@@ -176,6 +176,7 @@ test_need_tls_secrets_path (void)
 			"need-tls-secrets-path-key-password",
 			"expected to require private key password, but it wasn't");
 
+	g_ptr_array_free (hints, TRUE);
 	g_object_unref (connection);
 }
 
@@ -219,6 +220,7 @@ test_need_tls_secrets_blob (void)
 			"need-tls-secrets-blob-key-password",
 			"expected to require private key password, but it wasn't");
 
+	g_ptr_array_free (hints, TRUE);
 	g_object_unref (connection);
 }
 
@@ -345,6 +347,7 @@ test_need_tls_phase2_secrets_path (void)
 			"need-tls-phase2-secrets-path-key-password",
 			"expected to require private key password, but it wasn't");
 
+	g_ptr_array_free (hints, TRUE);
 	g_object_unref (connection);
 }
 
@@ -389,6 +392,7 @@ test_need_tls_phase2_secrets_blob (void)
 			"need-tls-phase2-secrets-blob-key-password",
 			"expected to require private key password, but it wasn't");
 
+	g_ptr_array_free (hints, TRUE);
 	g_object_unref (connection);
 }
 
@@ -559,8 +563,8 @@ test_update_secrets_wifi_bad_setting_name (void)
 	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND);
 	g_assert (success == FALSE);
 
+	g_clear_error (&error);
 	g_variant_unref (secrets);
-
 	g_object_unref (connection);
 }
 
@@ -668,6 +672,7 @@ test_update_secrets_whole_connection_bad_setting (void)
 	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND);
 	g_assert (success == FALSE);
 
+	g_clear_error (&error);
 	g_variant_unref (copy);
 	g_object_unref (connection);
 }
diff --git a/libnm-core/tests/test-setting-8021x.c b/libnm-core/tests/test-setting-8021x.c
index 637ab81c..992379c7 100644
--- a/libnm-core/tests/test-setting-8021x.c
+++ b/libnm-core/tests/test-setting-8021x.c
@@ -186,6 +186,7 @@ test_phase2_private_key_import (const char *path,
 		g_object_get (s_8021x, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, &tmp_key, NULL);
 		ASSERT (tmp_key != NULL, "phase2-private-key-import", "missing private key value");
 		check_scheme_path (tmp_key, path);
+		g_bytes_unref (tmp_key);
 	} else
 		g_assert_not_reached ();
 
@@ -245,6 +246,7 @@ test_wrong_password_keeps_data (const char *path, const char *password)
 	        "wrong-password-keeps-data", "unexpected missing error");
 	ASSERT (format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN,
 	        "wrong-password-keeps-data", "unexpected success reading private key format");
+	g_clear_error (&error);
 
 	/* Make sure the password hasn't changed */
 	pw = nm_setting_802_1x_get_private_key_password (s_8021x);
@@ -342,6 +344,7 @@ test_wrong_phase2_password_keeps_data (const char *path, const char *password)
 	        "wrong-phase2-password-keeps-data", "unexpected missing error");
 	ASSERT (format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN,
 	        "wrong-phase2-password-keeps-data", "unexpected success reading private key format");
+	g_clear_error (&error);
 
 	/* Make sure the password hasn't changed */
 	pw = nm_setting_802_1x_get_phase2_private_key_password (s_8021x);
diff --git a/libnm-core/tests/test-setting-dcb.c b/libnm-core/tests/test-setting-dcb.c
index 8adab8ce..f7554e81 100644
--- a/libnm-core/tests/test-setting-dcb.c
+++ b/libnm-core/tests/test-setting-dcb.c
@@ -28,6 +28,7 @@
 #include "nm-setting-dcb.h"
 #include "nm-connection.h"
 #include "nm-errors.h"
+#include "gsystem-local-alloc.h"
 
 #define DCB_FLAGS_ALL (NM_SETTING_DCB_FLAG_ENABLE | \
                        NM_SETTING_DCB_FLAG_ADVERTISE | \
@@ -36,7 +37,7 @@
 static void
 test_dcb_flags_valid (void)
 {
-	NMSettingDcb *s_dcb;
+	gs_unref_object NMSettingDcb *s_dcb = NULL;
 	GError *error = NULL;
 	gboolean success;
 	guint i;
@@ -89,7 +90,7 @@ test_dcb_flags_valid (void)
 static void
 test_dcb_flags_invalid (void)
 {
-	NMSettingDcb *s_dcb;
+	gs_unref_object NMSettingDcb *s_dcb = NULL;
 	GError *error = NULL;
 	gboolean success;
 
@@ -148,7 +149,7 @@ test_dcb_flags_invalid (void)
 static void
 test_dcb_app_priorities (void)
 {
-	NMSettingDcb *s_dcb;
+	gs_unref_object NMSettingDcb *s_dcb = NULL;
 	GError *error = NULL;
 	gboolean success;
 
@@ -210,7 +211,7 @@ test_dcb_app_priorities (void)
 static void
 test_dcb_priorities_valid (void)
 {
-	NMSettingDcb *s_dcb;
+	gs_unref_object NMSettingDcb *s_dcb = NULL;
 	GError *error = NULL;
 	gboolean success;
 	guint i;
@@ -269,7 +270,7 @@ test_dcb_priorities_valid (void)
 static void
 test_dcb_bandwidth_sums (void)
 {
-	NMSettingDcb *s_dcb;
+	gs_unref_object NMSettingDcb *s_dcb = NULL;
 	GError *error = NULL;
 	gboolean success;