Blob Blame History Raw
From dfb7062565889a716b727909e0ab0c8b0e580b42 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Fri, 2 Sep 2016 14:58:56 +0200
Subject: [PATCH 1/3] shared: add helper macros nm_str_not_empty() and
 nm_strdup_not_empty()

(cherry picked from commit 3227b9017bbfa9e8339d32924aa4e73bcd8a75ce)
(cherry picked from commit 4aad70a61d0ed00ed0e3181a86376a93592ce753)
---
 shared/nm-utils/nm-macros-internal.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index 73075c6..c66cb53 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -302,6 +302,22 @@ _NM_IN_STRSET_streq (const char *x, const char *s)
 
 /*****************************************************************************/
 
+#define nm_str_not_empty(str) \
+	({ \
+		/* implemented as macro to preserve constness */ \
+		typeof (str) __str = (str); \
+		_nm_unused const char *__str_type_check = __str; \
+		((__str && __str[0]) ? __str : ((char *) NULL)); \
+	})
+
+static inline char *
+nm_strdup_not_empty (const char *str)
+{
+	return str && str[0] ? g_strdup (str) : NULL;
+}
+
+/*****************************************************************************/
+
 #define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \
 	(cond) ? (prefix) : "", \
 	(cond) ? (str) : (str_else), \
-- 
2.7.4


From 5a4ac7613ed28cd692372879d0058e6063e28ffe Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Fri, 2 Sep 2016 15:06:24 +0200
Subject: [PATCH 2/3] libnm-core: replace local helper with
 nm_stdup_not_empty()

(cherry picked from commit f4d7db964e735480e97b9d3ae53bc4fb95442a47)
(cherry picked from commit 1fdf026e2d564cd51b0f0de8c01ef86bc4fbfe50)
---
 libnm-core/nm-setting-8021x.c | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c
index aa9d461..12dc5a6 100644
--- a/libnm-core/nm-setting-8021x.c
+++ b/libnm-core/nm-setting-8021x.c
@@ -2915,15 +2915,6 @@ set_cert_prop_helper (const GValue *value, const char *prop_name, GError **error
 	return bytes;
 }
 
-static char *
-_g_value_dup_string_not_empty (const GValue *value)
-{
-	const gchar *str;
-
-	str = g_value_get_string (value);
-	return str && str[0] ? g_strdup (str) : NULL;
-}
-
 static void
 set_property (GObject *object, guint prop_id,
               const GValue *value, GParamSpec *pspec)
@@ -2964,7 +2955,7 @@ set_property (GObject *object, guint prop_id,
 		break;
 	case PROP_SUBJECT_MATCH:
 		g_free (priv->subject_match);
-		priv->subject_match = _g_value_dup_string_not_empty (value);
+		priv->subject_match = nm_strdup_not_empty (g_value_get_string (value));
 		break;
 	case PROP_ALTSUBJECT_MATCHES:
 		g_slist_free_full (priv->altsubject_matches, g_free);
@@ -2972,7 +2963,7 @@ set_property (GObject *object, guint prop_id,
 		break;
 	case PROP_DOMAIN_SUFFIX_MATCH:
 		g_free (priv->domain_suffix_match);
-		priv->domain_suffix_match = _g_value_dup_string_not_empty (value);
+		priv->domain_suffix_match = nm_strdup_not_empty (g_value_get_string (value));
 		break;
 	case PROP_CLIENT_CERT:
 		if (priv->client_cert)
@@ -3018,7 +3009,7 @@ set_property (GObject *object, guint prop_id,
 		break;
 	case PROP_PHASE2_SUBJECT_MATCH:
 		g_free (priv->phase2_subject_match);
-		priv->phase2_subject_match = _g_value_dup_string_not_empty (value);
+		priv->phase2_subject_match = nm_strdup_not_empty (g_value_get_string (value));
 		break;
 	case PROP_PHASE2_ALTSUBJECT_MATCHES:
 		g_slist_free_full (priv->phase2_altsubject_matches, g_free);
@@ -3026,7 +3017,7 @@ set_property (GObject *object, guint prop_id,
 		break;
 	case PROP_PHASE2_DOMAIN_SUFFIX_MATCH:
 		g_free (priv->phase2_domain_suffix_match);
-		priv->phase2_domain_suffix_match = _g_value_dup_string_not_empty (value);
+		priv->phase2_domain_suffix_match = nm_strdup_not_empty (g_value_get_string (value));
 		break;
 	case PROP_PHASE2_CLIENT_CERT:
 		if (priv->phase2_client_cert)
-- 
2.7.4


From 9d5f6a51ed94c035a2da5c47bf3a11d9b61ac7d4 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Fri, 2 Sep 2016 15:00:08 +0200
Subject: [PATCH 3/3] libnm: fix regression serializing empty
 "cloned-mac-address"

For "cloned-mac-address", the empty string "" is an invalid
value that is rejected by verify().

Commit 8eed671 changed how the property is serialized to D-Bus.
Before, it was serialized using _nm_utils_hwaddr_to_dbus().
For invalid or empty addresses, this would not serialize the
value on D-Bus (or before commit 76aa6f8e0, it would create
a bogus value with no array elements).

With commit 8eed671, the cloned-mac-address gets also serialized
as "assigned-mac-address" via _nm_utils_hwaddr_cloned_data_synth(),
which would pass on invalid strings that the server would then reject.

That breaks for example nmtui. Try editing a connection with
"cloned-mac-address" set to NULL. Note, as long as you don't edit
the cloned MAC address in nmtui, you can save the modification.
Once you start modifying the entry, you can no longer set an empty
MAC address as the server now receives the invalid empty string.
Thus, the "OK" button fails with
   Unable to save connection:
   802-3-ethernet.cloned-mac-address:
   is not a valid MAC address
It also means, nmtui cannot modify the "cloned-mac-address" field to
become empty.

Fix that problem at various places by coercing "" to NULL.

Fixes: 8eed67122c58540360b617eb42d5df8328e21b5d

https://bugzilla.redhat.com/show_bug.cgi?id=1372799
(cherry picked from commit 814784aa46004023739ccb29bc806d1abfb63bb2)
(cherry picked from commit 742bf5671f24efa138d7127e501963d233bf508f)
---
 clients/tui/nmt-mac-entry.c |  3 ++-
 libnm-core/nm-utils.c       | 19 +++++++++++++++++--
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/clients/tui/nmt-mac-entry.c b/clients/tui/nmt-mac-entry.c
index da7f55f..b954d2e 100644
--- a/clients/tui/nmt-mac-entry.c
+++ b/clients/tui/nmt-mac-entry.c
@@ -201,7 +201,8 @@ nmt_mac_entry_get_property (GObject    *object,
 		g_value_set_int (value, priv->mac_length);
 		break;
 	case PROP_MAC_ADDRESS:
-		g_value_set_string (value, nmt_newt_entry_get_text (NMT_NEWT_ENTRY (object)));
+		g_value_set_string (value,
+		                    nm_str_not_empty (nmt_newt_entry_get_text (NMT_NEWT_ENTRY (object))));
 		break;
 	case PROP_ENTRY_TYPE:
 		g_value_set_int (value, priv->entry_type);
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index a31a919..df75d56 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -3425,7 +3425,22 @@ _nm_utils_hwaddr_cloned_data_synth (NMSetting *setting,
 	              "cloned-mac-address",
 	              &addr,
 	              NULL);
-	return addr ? g_variant_new_string (addr) : NULL;
+
+	/* Before introducing the extended "cloned-mac-address" (and its D-Bus
+	 * field "assigned-mac-address"), libnm's _nm_utils_hwaddr_to_dbus()
+	 * would drop invalid values as it was unable to serialize them.
+	 *
+	 * Now, we would like to send invalid values as "assigned-mac-address"
+	 * over D-Bus and let the server reject them.
+	 *
+	 * However, clients used to set the cloned-mac-address property
+	 * to "" and it just worked as the value was not serialized in
+	 * an ill form.
+	 *
+	 * To preserve that behavior, seralize "" as NULL.
+	 */
+
+	return addr && addr[0] ? g_variant_new_string (addr) : NULL;
 }
 
 gboolean
@@ -3443,7 +3458,7 @@ _nm_utils_hwaddr_cloned_data_set (NMSetting *setting,
 
 	g_object_set (setting,
 	              "cloned-mac-address",
-	              g_variant_get_string (value, NULL),
+	              nm_str_not_empty (g_variant_get_string (value, NULL)),
 	              NULL);
 	return TRUE;
 }
-- 
2.7.4