Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/util/virpolkit.c | 115 +++++++++++++++++++++---------------------
tests/meson.build | 11 ++--
tests/virpolkittest.c | 112 +++++++++++++++-------------------------
3 files changed, 104 insertions(+), 134 deletions(-)
diff --git a/src/util/virpolkit.c b/src/util/virpolkit.c
index 1570d667ee..2ad00fd206 100644
--- a/src/util/virpolkit.c
+++ b/src/util/virpolkit.c
@@ -28,7 +28,7 @@
#include "virstring.h"
#include "virprocess.h"
#include "viralloc.h"
-#include "virdbus.h"
+#include "virgdbus.h"
#include "virfile.h"
#include "virutil.h"
@@ -63,80 +63,81 @@ int virPolkitCheckAuth(const char *actionid,
const char **details,
bool allowInteraction)
{
- DBusConnection *sysbus;
- DBusMessage *reply = NULL;
- char **retdetails = NULL;
- size_t nretdetails = 0;
- bool is_authorized;
- bool is_challenge;
+ GDBusConnection *sysbus;
+ GVariantBuilder builder;
+ GVariant *gprocess = NULL;
+ GVariant *gdetails = NULL;
+ g_autoptr(GVariant) message = NULL;
+ g_autoptr(GVariant) reply = NULL;
+ g_autoptr(GVariantIter) iter = NULL;
+ char *retkey;
+ char *retval;
+ gboolean is_authorized;
+ gboolean is_challenge;
bool is_dismissed = false;
size_t i;
- int ret = -1;
- if (!(sysbus = virDBusGetSystemBus()))
- goto cleanup;
+ if (!(sysbus = virGDBusGetSystemBus()))
+ return -1;
VIR_INFO("Checking PID %lld running as %d",
(long long) pid, uid);
- if (virDBusCallMethod(sysbus,
- &reply,
- NULL,
- "org.freedesktop.PolicyKit1",
- "/org/freedesktop/PolicyKit1/Authority",
- "org.freedesktop.PolicyKit1.Authority",
- "CheckAuthorization",
- "(sa{sv})sa&{ss}us",
- "unix-process",
- 3,
- "pid", "u", (unsigned int)pid,
- "start-time", "t", startTime,
- "uid", "i", (int)uid,
- actionid,
- virStringListLength(details) / 2,
- details,
- allowInteraction,
- "" /* cancellation ID */) < 0)
- goto cleanup;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(&builder, "{sv}", "pid",
g_variant_new_uint32(pid));
+ g_variant_builder_add(&builder, "{sv}", "start-time",
g_variant_new_uint64(startTime));
+ g_variant_builder_add(&builder, "{sv}", "uid",
g_variant_new_int32(uid));
+ gprocess = g_variant_builder_end(&builder);
- if (virDBusMessageDecode(reply,
- "(bba&{ss})",
- &is_authorized,
- &is_challenge,
- &nretdetails,
- &retdetails) < 0)
- goto cleanup;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}"));
+ for (i = 0; i < virStringListLength(details); i += 2)
+ g_variant_builder_add(&builder, "{ss}", details[i], details[i +
1]);
+ gdetails = g_variant_builder_end(&builder);
- for (i = 0; i < (nretdetails / 2); i++) {
- if (STREQ(retdetails[(i * 2)], "polkit.dismissed") &&
- STREQ(retdetails[(i * 2) + 1], "true"))
+ message = g_variant_new("((s@a{sv})s@a{ss}us)",
+ "unix-process",
+ gprocess,
+ actionid,
+ gdetails,
+ allowInteraction,
+ "" /* cancellation ID */);
+
+ if (virGDBusCallMethod(sysbus,
+ &reply,
+ NULL,
+ "org.freedesktop.PolicyKit1",
+ "/org/freedesktop/PolicyKit1/Authority",
+ "org.freedesktop.PolicyKit1.Authority",
+ "CheckAuthorization",
+ message) < 0)
+ return -1;
+
+ g_variant_get(reply, "((bba{ss}))", &is_authorized, &is_challenge,
&iter);
+
+ while (g_variant_iter_loop(iter, "{ss}", &retkey, &retval)) {
+ if (STREQ(retkey, "polkit.dismissed") && STREQ(retval,
"true"))
is_dismissed = true;
}
VIR_DEBUG("is auth %d is challenge %d",
is_authorized, is_challenge);
- if (is_authorized) {
- ret = 0;
+ if (is_authorized)
+ return 0;
+
+ if (is_dismissed) {
+ virReportError(VIR_ERR_AUTH_CANCELLED, "%s",
+ _("user cancelled authentication process"));
+ } else if (is_challenge) {
+ virReportError(VIR_ERR_AUTH_UNAVAILABLE,
+ _("no polkit agent available to authenticate action
'%s'"),
+ actionid);
} else {
- ret = -2;
- if (is_dismissed)
- virReportError(VIR_ERR_AUTH_CANCELLED, "%s",
- _("user cancelled authentication process"));
- else if (is_challenge)
- virReportError(VIR_ERR_AUTH_UNAVAILABLE,
- _("no polkit agent available to authenticate "
- "action '%s'"),
- actionid);
- else
- virReportError(VIR_ERR_AUTH_FAILED, "%s",
- _("access denied by policy"));
+ virReportError(VIR_ERR_AUTH_FAILED, "%s",
+ _("access denied by policy"));
}
- cleanup:
- virStringListFreeCount(retdetails, nretdetails);
- virDBusMessageUnref(reply);
- return ret;
+ return -2;
}
diff --git a/tests/meson.build b/tests/meson.build
index 0f3e4bfdd7..75bfb3effe 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -365,11 +365,6 @@ if conf.has('WITH_DBUS')
{ 'name': 'virsystemdtest', 'deps': [ dbus_dep ] },
]
- if conf.has('WITH_POLKIT')
- tests += [
- { 'name': 'virpolkittest', 'deps': [ dbus_dep ] },
- ]
- endif
endif
if conf.has('WITH_ESX')
@@ -446,6 +441,12 @@ if conf.has('WITH_OPENVZ')
]
endif
+if conf.has('WITH_POLKIT')
+ tests += [
+ { 'name': 'virpolkittest' },
+ ]
+endif
+
if conf.has('WITH_QEMU')
tests += [
{ 'name': 'qemuagenttest', 'link_with': [
test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole': [
test_utils_qemu_lib ] },
diff --git a/tests/virpolkittest.c b/tests/virpolkittest.c
index fe7a3b5b91..011d83a506 100644
--- a/tests/virpolkittest.c
+++ b/tests/virpolkittest.c
@@ -22,10 +22,8 @@
#if defined(__ELF__)
-# include <dbus/dbus.h>
-
# include "virpolkit.h"
-# include "virdbus.h"
+# include "virgdbus.h"
# include "virlog.h"
# include "virmock.h"
# define VIR_FROM_THIS VIR_FROM_NONE
@@ -37,54 +35,43 @@ VIR_LOG_INIT("tests.systemdtest");
# define THE_TIME 11011000001
# define THE_UID 1729
-VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block,
- DBusMessage *,
- DBusConnection *, connection,
- DBusMessage *, message,
- int, timeout_milliseconds,
- DBusError *, error)
+VIR_MOCK_WRAP_RET_ARGS(g_dbus_connection_call_sync,
+ GVariant *,
+ GDBusConnection *, connection,
+ const gchar *, bus_name,
+ const gchar *, object_path,
+ const gchar *, interface_name,
+ const gchar *, method_name,
+ GVariant *, parameters,
+ const GVariantType *, reply_type,
+ GDBusCallFlags, flags,
+ gint, timeout_msec,
+ GCancellable *, cancellable,
+ GError **, error)
{
- DBusMessage *reply = NULL;
- const char *service = dbus_message_get_destination(message);
- const char *member = dbus_message_get_member(message);
+ GVariant *reply = NULL;
+ g_autoptr(GVariant) params = parameters;
- VIR_MOCK_REAL_INIT(dbus_connection_send_with_reply_and_block);
+ VIR_MOCK_REAL_INIT(g_dbus_connection_call_sync);
- if (STREQ(service, "org.freedesktop.PolicyKit1") &&
- STREQ(member, "CheckAuthorization")) {
+ if (STREQ(bus_name, "org.freedesktop.PolicyKit1") &&
+ STREQ(method_name, "CheckAuthorization")) {
+ g_autoptr(GVariantIter) iter = NULL;
+ GVariantBuilder builder;
char *type;
- char *pidkey;
- unsigned int pidval;
- char *timekey;
- unsigned long long timeval;
- char *uidkey;
- int uidval;
char *actionid;
- char **details;
- size_t detailslen;
- int allowInteraction;
- char *cancellationId;
- const char **retdetails = NULL;
- size_t retdetailslen = 0;
- const char *retdetailscancelled[] = {
- "polkit.dismissed", "true",
- };
int is_authorized = 1;
int is_challenge = 0;
- if (virDBusMessageDecode(message,
- "(sa{sv})sa&{ss}us",
- &type,
- 3,
- &pidkey, "u", &pidval,
- &timekey, "t", &timeval,
- &uidkey, "i", &uidval,
- &actionid,
- &detailslen,
- &details,
- &allowInteraction,
- &cancellationId) < 0)
- goto error;
+ g_variant_get(params, "((&s@a{sv})&sa{ss}@u@s)",
+ &type,
+ NULL,
+ &actionid,
+ &iter,
+ NULL,
+ NULL);
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("a{ss}"));
if (STREQ(actionid, "org.libvirt.test.success")) {
is_authorized = 1;
@@ -95,17 +82,15 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block,
} else if (STREQ(actionid, "org.libvirt.test.cancelled")) {
is_authorized = 0;
is_challenge = 0;
- retdetails = retdetailscancelled;
- retdetailslen = G_N_ELEMENTS(retdetailscancelled) / 2;
+ g_variant_builder_add(&builder, "{ss}",
"polkit.dismissed", "true");
} else if (STREQ(actionid, "org.libvirt.test.details")) {
- size_t i;
+ char *key;
+ char *val;
is_authorized = 0;
is_challenge = 0;
- for (i = 0; i < detailslen / 2; i++) {
- if (STREQ(details[i * 2],
- "org.libvirt.test.person") &&
- STREQ(details[(i * 2) + 1],
- "Fred")) {
+
+ while (g_variant_iter_loop(iter, "{ss}", &key, &val)) {
+ if (STREQ(key, "org.libvirt.test.person") && STREQ(val,
"Fred")) {
is_authorized = 1;
is_challenge = 0;
}
@@ -115,30 +100,13 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block,
is_challenge = 0;
}
- VIR_FREE(type);
- VIR_FREE(pidkey);
- VIR_FREE(timekey);
- VIR_FREE(uidkey);
- VIR_FREE(actionid);
- VIR_FREE(cancellationId);
- virStringListFreeCount(details, detailslen);
-
- if (virDBusCreateReply(&reply,
- "(bba&{ss})",
- is_authorized,
- is_challenge,
- retdetailslen,
- retdetails) < 0)
- goto error;
+ reply = g_variant_new("((bb@a{ss}))", is_authorized, is_challenge,
+ g_variant_builder_end(&builder));
} else {
- reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ reply = g_variant_new("()");
}
return reply;
-
- error:
- virDBusMessageUnref(reply);
- return NULL;
}
@@ -322,7 +290,7 @@ mymain(void)
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
-VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("virdbus"))
+VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("virgdbus"))
#else /* ! __ELF__ */
int
--
2.26.2