From 7ff1dc5818747650942109e7ea6aee7d0a200318 Mon Sep 17 00:00:00 2001
From: David Kupka <dkupka@redhat.com>
Date: Mon, 11 Aug 2014 15:01:56 +0200
Subject: [PATCH] Get/Set external-helper using D-Bus Property interface.

---
 src/tdbush.c | 23 +++++++++++++++-------
 src/tdbusm.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/tdbusm.h |  5 +++++
 3 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/src/tdbush.c b/src/tdbush.c
index 3bd7ddb2f57278e13a987ca9da2dc2b2b69f7e9d..6f621d4d3caa4cd2333a4bf43eb80a6fb47a6476 100644
--- a/src/tdbush.c
+++ b/src/tdbush.c
@@ -4779,6 +4779,9 @@ cm_tdbush_property_set(DBusConnection *conn,
 	long l;
 	DBusMessage *rep;
 	const char *properties[2];
+	union cm_tdbusm_variant v;
+	int dbus_type;
+
 
 	path = dbus_message_get_path(msg);
 	type = cm_tdbush_classify_path(ctx, path);
@@ -4883,16 +4886,22 @@ cm_tdbush_property_set(DBusConnection *conn,
 	/* Read the argument and set the data. */
 	switch (prop->cm_local_type) {
 	case cm_tdbush_property_char_p:
-		if (cm_tdbusm_get_sss(msg, parent, &interface, &property,
-				      &wp) != 0) {
+		if (cm_tdbusm_get_ssv(msg, parent, &interface, &property,
+					&v, &dbus_type) != 0) {
 			cm_log(1, "Error parsing arguments.\n");
 			dbus_message_unref(rep);
 			talloc_free(parent);
 			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 		}
+
+		if (dbus_type != DBUS_TYPE_STRING) {
+			talloc_free(parent);
+			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+		}
+
 		record += prop->cm_offset;
 		wpp = (char **) record;
-		*wpp = maybe_strdup(record - prop->cm_offset, wp);
+		*wpp = maybe_strdup(record - prop->cm_offset, v.s);
 		break;
 	case cm_tdbush_property_char_pp:
 		if (cm_tdbusm_get_ssas(msg, parent, &interface, &property,
@@ -6578,10 +6587,10 @@ cm_tdbush_iface_ca(void)
 							 make_property(CM_DBUS_PROP_EXTERNAL_HELPER,
 								       cm_tdbush_property_string,
 								       cm_tdbush_property_readwrite,
-								       cm_tdbush_property_special,
-								       0,
-								       ca_prop_get_external_helper, NULL, NULL, NULL, NULL,
-								       ca_prop_set_external_helper, NULL, NULL, NULL, NULL,
+								       cm_tdbush_property_char_p,
+								       offsetof(struct cm_store_ca, cm_ca_external_helper),
+								       NULL, NULL, NULL, NULL, NULL,
+								       NULL, NULL, NULL, NULL, NULL,
 								       NULL),
 				     make_interface_item(cm_tdbush_interface_method,
 							 make_method("get_issuer_names",
diff --git a/src/tdbusm.c b/src/tdbusm.c
index 9bae222f2910f1a6c74e7899cd08cf02916d8d53..14933a5cc94fb696f2437985ee473ee44147f74d 100644
--- a/src/tdbusm.c
+++ b/src/tdbusm.c
@@ -461,6 +461,70 @@ cm_tdbusm_get_sss(DBusMessage *msg, void *parent, char **s1, char **s2,
 }
 
 int
+cm_tdbusm_get_ssv(DBusMessage *msg, void *parent, char **s1, char **s2,
+		   union cm_tdbusm_variant *v, int *dbus_type)
+{
+	DBusError err;
+	DBusMessageIter iter, var_iter;
+	int type;
+	void *t = NULL;
+	*s1 = *s2 = NULL;
+
+	dbus_error_init(&err);
+	dbus_message_iter_init(msg, &iter);
+
+	/* get first string */
+	if ((type = dbus_message_iter_get_arg_type(&iter)) != DBUS_TYPE_STRING) {
+		/* unexpected type */
+		return -1;
+	} else {
+		dbus_message_iter_get_basic(&iter, (void*)s1);
+	}
+
+	if (dbus_message_iter_next(&iter) != TRUE) {
+		/* nothing more */
+		return -1;
+	}
+
+	/* get second string */
+	if ((type = dbus_message_iter_get_arg_type(&iter)) != DBUS_TYPE_STRING) {
+		/* unexpected type */
+		return -1;
+	} else {
+		dbus_message_iter_get_basic(&iter, (void*)s2);
+	}
+
+	if (dbus_message_iter_next(&iter) != TRUE) {
+		/* nothing more */
+		return -1;
+	}
+
+	/* get variant */
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
+		/* unexpected type */
+		return -1;
+	} else {
+		dbus_message_iter_recurse(&iter, &var_iter);
+		*dbus_type = type = dbus_message_iter_get_arg_type(&var_iter);
+		dbus_message_iter_get_basic(&var_iter, (void*)&t);
+	}
+
+	switch (type) {
+	case DBUS_TYPE_STRING:
+		v->s = t ? talloc_strdup(parent, t) : NULL;
+		break;
+	default:
+		/* add other cases if needed, edit cm_tdbusm_variant union as well */
+		return -1;
+		break;
+	}
+	*s1 = *s1 ? talloc_strdup(parent, *s1) : NULL;
+	*s2 = *s2 ? talloc_strdup(parent, *s2) : NULL;
+
+	return 0;
+}
+
+int
 cm_tdbusm_get_ssb(DBusMessage *msg, void *parent, char **s1, char **s2,
 		  dbus_bool_t *b)
 {
diff --git a/src/tdbusm.h b/src/tdbusm.h
index 683dfe91632c5078e30649eedaa41fcd33b4129e..a69d06eae781b7c72c1645edab2d1ec89ecd8194 100644
--- a/src/tdbusm.h
+++ b/src/tdbusm.h
@@ -78,6 +78,9 @@ struct cm_tdbusm_dict {
 		const struct cm_tdbusm_dict **d;
 	} value;
 };
+union cm_tdbusm_variant {
+	char *s;
+};
 int cm_tdbusm_get_d(DBusMessage *msg, void *parent, struct cm_tdbusm_dict ***d);
 int cm_tdbusm_get_sd(DBusMessage *msg, void *parent,
 		     char **s, struct cm_tdbusm_dict ***d);
@@ -96,6 +99,8 @@ int cm_tdbusm_set_as(DBusMessage *msg, const char **s);
 int cm_tdbusm_set_ass(DBusMessage *msg, const char **ss);
 int cm_tdbusm_set_sss(DBusMessage *msg,
 		      const char *s1, const char *s2, const char *s3);
+int cm_tdbusm_get_ssv(DBusMessage *msg, void *parent, char **s1, char **s2,
+		      union cm_tdbusm_variant *v, int *dbus_type);
 int cm_tdbusm_set_ssb(DBusMessage *msg,
 		      const char *s1, const char *s2, dbus_bool_t b);
 int cm_tdbusm_set_ssn(DBusMessage *msg,
-- 
1.9.3

