[glib/sandboxed-dbus-activation] Make dbus activation sandbox-aware
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/sandboxed-dbus-activation] Make dbus activation sandbox-aware
- Date: Sat, 13 May 2017 17:41:19 +0000 (UTC)
commit d4e6eae516a5c1968d66b9965e01bf1e702a6393
Author: Matthias Clasen <mclasen redhat com>
Date: Sat May 6 14:22:38 2017 -0400
Make dbus activation sandbox-aware
When we call org.freedesktop.Application.Open to activate
an application and pass file uris, the application may not
be able to see the files due to a flatpak sandbox. Flatpak
puts an X-Flatpak marker in desktop files that it exports,
so we can easily recognize applications that may be affected
by this. In this case, call the document portal to export
the files and pass the resulting uri's instead of the original
ones.
gio/gdesktopappinfo.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 173 insertions(+), 7 deletions(-)
---
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index 81dff27..0f0b256 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -36,6 +36,7 @@
#include "gdesktopappinfo.h"
#ifdef G_OS_UNIX
#include "glib-unix.h"
+#include "gunixfdlist.h"
#endif
#include "gfile.h"
#include "gioerror.h"
@@ -2835,17 +2836,15 @@ g_desktop_app_info_make_platform_data (GDesktopAppInfo *info,
return g_variant_builder_end (&builder);
}
-static gboolean
-g_desktop_app_info_launch_uris_with_dbus (GDesktopAppInfo *info,
- GDBusConnection *session_bus,
- GList *uris,
- GAppLaunchContext *launch_context)
+static void
+launch_uris_with_dbus (GDesktopAppInfo *info,
+ GDBusConnection *session_bus,
+ GList *uris,
+ GAppLaunchContext *launch_context)
{
GVariantBuilder builder;
gchar *object_path;
- g_return_val_if_fail (info != NULL, FALSE);
-
g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
if (uris)
@@ -2865,10 +2864,177 @@ g_desktop_app_info_launch_uris_with_dbus (GDesktopAppInfo *info,
* This is what startup-notification's job is...
*/
object_path = object_path_from_appid (info->app_id);
+
g_dbus_connection_call (session_bus, info->app_id, object_path, "org.freedesktop.Application",
uris ? "Open" : "Activate", g_variant_builder_end (&builder),
NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
+
g_free (object_path);
+}
+
+#ifdef G_OS_UNIX
+typedef struct {
+ GDesktopAppInfo *info;
+ GAppLaunchContext *context;
+ GList *uris;
+ gboolean *as_is;
+} LaunchData;
+
+static void
+free_launch_data (LaunchData *data)
+{
+ g_object_unref (data->info);
+ g_object_unref (data->context);
+ g_list_free_full (data->uris, g_free);
+ g_free (data->as_is);
+ g_free (data);
+}
+
+static void
+rewrite_uris_done (GObject *source,
+ GAsyncResult *res,
+ gpointer data)
+{
+ GDBusConnection *session_bus = G_DBUS_CONNECTION (source);
+ LaunchData *ld = data;
+ g_autoptr(GVariant) ret = NULL;
+ g_autoptr(GError) error = NULL;
+ char *mountpoint;
+ char **doc_ids;
+ GList *l;
+ GList *ruris;
+ int i, j;
+
+ ret = g_dbus_connection_call_with_unix_fd_list_finish (session_bus, NULL, res, &error);
+ if (ret == NULL)
+ {
+ g_warning ("Failed to call AddMany: %s", error->message);
+ launch_uris_with_dbus (ld->info, session_bus, ld->uris, ld->context);
+ free_launch_data (ld);
+ return;
+ }
+
+ g_variant_get (ret, "(^a&s^&ay)", &doc_ids, &mountpoint);
+
+ ruris = NULL;
+
+ for (l = ld->uris, i = 0, j = 0; l; l = l->next, i++)
+ {
+ char *uri = l->data;
+ char *ruri;
+
+ if (ld->as_is[i])
+ ruri = g_strdup (uri);
+ else if (strcmp (doc_ids[j], "") == 0) /* use as-is */
+ {
+ ruri = g_strdup (uri);
+ j++;
+ }
+ else
+ {
+ char *basename = g_path_get_basename (uri + strlen ("file:"));
+ char *doc_path = g_build_filename (mountpoint, doc_ids[j], basename, NULL);
+ ruri = g_strconcat ("file:", doc_path, NULL);
+ g_free (basename);
+ g_free (doc_path);
+ j++;
+ }
+
+ ruris = g_list_append (ruris, ruri);
+ }
+
+ launch_uris_with_dbus (ld->info, session_bus, ruris, ld->context);
+ free_launch_data (ld);
+ g_list_free_full (ruris, g_free);
+}
+
+static void
+rewrite_uris_for_portal (GDesktopAppInfo *info,
+ GDBusConnection *session_bus,
+ GList *uris,
+ GAppLaunchContext *context)
+{
+ GVariantBuilder builder;
+ GUnixFDList *fd_list = NULL;
+ GList *l;
+ int i;
+ LaunchData *data;
+
+ data = g_new (LaunchData, 1);
+ data->info = g_object_ref (info);
+ data->context = g_object_ref (context);
+ data->uris = g_list_copy_deep (uris, (GCopyFunc)g_strdup, NULL);
+ data->as_is = g_new (gboolean, g_list_length (uris));
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
+ g_variant_builder_add (&builder, "s", info->app_id);
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("ah"));
+
+ fd_list = g_unix_fd_list_new ();
+ for (l = uris, i = 0; l; l = l->next, i++)
+ {
+ const char *uri = l->data;
+ int idx = -1;
+
+ if (g_str_has_prefix (uri, "file:"))
+ {
+ const char *path;
+ int fd;
+
+ path = uri + strlen ("file:");
+
+ fd = open (path, O_CLOEXEC | O_PATH);
+ if (fd >= 0)
+ {
+ idx = g_unix_fd_list_append (fd_list, fd, NULL);
+ close (fd);
+ }
+ }
+
+ data->as_is[i] = idx != -1;
+ if (idx != -1)
+ g_variant_builder_add (&builder, "h", idx);
+ }
+
+ g_variant_builder_close (&builder);
+
+ g_dbus_connection_call_with_unix_fd_list (session_bus,
+ "org.freedesktop.portal.Documents",
+ "/org/freedesktop/portal/documents",
+ "org.freedesktop.portal.Documents",
+ "AddMany",
+ g_variant_builder_end (&builder),
+ G_VARIANT_TYPE ("(asay)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ fd_list,
+ NULL,
+ rewrite_uris_done,
+ data);
+ g_object_unref (fd_list);
+}
+
+static gboolean
+should_rewrite_uris_for_portal (GDesktopAppInfo *info)
+{
+ return g_desktop_app_info_get_boolean (info, "X-Flatpak");
+}
+#endif
+
+static gboolean
+g_desktop_app_info_launch_uris_with_dbus (GDesktopAppInfo *info,
+ GDBusConnection *session_bus,
+ GList *uris,
+ GAppLaunchContext *launch_context)
+{
+ g_return_val_if_fail (info != NULL, FALSE);
+
+#ifdef G_OS_UNIX
+ if (should_rewrite_uris_for_portal (info))
+ rewrite_uris_for_portal (info, session_bus, uris, launch_context);
+ else
+#endif
+ launch_uris_with_dbus (info, session_bus, uris, launch_context);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]