[libvirt PATCH 06/14] src/util/virpolkit: convert to use GLib DBus

Pavel Hrdina phrdina at redhat.com
Thu Sep 17 08:29:41 UTC 2020


Signed-off-by: Pavel Hrdina <phrdina at 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 at a{sv})s at 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 at a{sv})&sa{ss}@u at 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 at 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




More information about the libvir-list mailing list