Implement file forwarding for flatpak_run_app

Add a flag that triggers extra processing of the 'rest'
commandline arguments, as follows: When we see arguments
that are enclosed in a pair of '@@' arguments, we interpret
them as file paths, export them in the document store, and
pass the resulting document path to the launched application.

Currently, the files are exported non-persistent (i.e. only
for the current session), and with read and write permissions
for the app.
This commit is contained in:
Matthias Clasen
2017-04-28 17:55:12 -04:00
committed by Alexander Larsson
parent 75b84b4bfe
commit 153dd18a7d
2 changed files with 109 additions and 2 deletions

View File

@@ -29,6 +29,8 @@
#include <sys/ioctl.h>
#include <sys/personality.h>
#include <grp.h>
#include <unistd.h>
#include <gio/gunixfdlist.h>
#ifdef ENABLE_SECCOMP
#include <seccomp.h>
@@ -48,6 +50,7 @@
#include "flatpak-utils.h"
#include "flatpak-dir.h"
#include "flatpak-systemd-dbus.h"
#include "document-portal/xdp-dbus.h"
#define DEFAULT_SHELL "/bin/sh"
@@ -4175,6 +4178,104 @@ child_setup (gpointer user_data)
fcntl (g_array_index (fd_array, int, i), F_SETFD, 0);
}
static gboolean
forward_file (XdpDbusDocuments *documents,
const char *app_id,
const char *file,
char **out_doc_id,
GError **error)
{
int fd, fd_id;
g_autofree char *doc_id;
g_autoptr(GUnixFDList) fd_list = NULL;
const char *perms[] = { "read", "write", NULL };
fd = open (file, O_PATH | O_CLOEXEC);
if (fd == -1)
return flatpak_fail (error, "Failed to open '%s'", file);
fd_list = g_unix_fd_list_new ();
fd_id = g_unix_fd_list_append (fd_list, fd, error);
close (fd);
if (!xdp_dbus_documents_call_add_sync (documents,
g_variant_new ("h", fd_id),
TRUE, /* reuse */
FALSE, /* not persistent */
fd_list,
&doc_id,
NULL,
NULL,
error))
return FALSE;
if (!xdp_dbus_documents_call_grant_permissions_sync (documents,
doc_id,
app_id,
perms,
NULL,
error))
return FALSE;
*out_doc_id = g_steal_pointer (&doc_id);
return TRUE;
}
static gboolean
add_rest_args (const char *app_id,
gboolean file_forwarding,
GPtrArray *argv_array,
char *args[],
int n_args,
GError **error)
{
g_autoptr(XdpDbusDocuments) documents = NULL;
g_autofree char *mountpoint = NULL;
gboolean forwarding = FALSE;
int i;
documents = xdp_dbus_documents_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, 0,
"org.freedesktop.portal.Documents",
"/org/freedesktop/portal/documents",
NULL,
error);
if (documents == NULL)
return FALSE;
if (!xdp_dbus_documents_call_get_mount_point_sync (documents, &mountpoint, NULL, error))
return FALSE;
for (i = 0; i < n_args; i++)
{
if (file_forwarding && strcmp (args[i], "@@") == 0)
{
forwarding = !forwarding;
continue;
}
if (forwarding)
{
g_autofree char *doc_id = NULL;
g_autofree char *basename = NULL;
char *doc_path;
if (!forward_file (documents, app_id, args[i], &doc_id, error))
return FALSE;
basename = g_path_get_basename (args[i]);
doc_path = g_build_filename (mountpoint, doc_id, basename, NULL);
g_debug ("Forwarding file '%s' as '%s' to %s", args[i], doc_path, app_id);
g_ptr_array_add (argv_array, doc_path);
}
else
g_ptr_array_add (argv_array, g_strdup (args[i]));
}
return TRUE;
}
gboolean
flatpak_run_app (const char *app_ref,
@@ -4210,6 +4311,7 @@ flatpak_run_app (const char *app_ref,
g_autoptr(FlatpakContext) app_context = NULL;
g_autoptr(FlatpakContext) overrides = NULL;
g_auto(GStrv) app_ref_parts = NULL;
g_autofree char *commandline = NULL;
app_ref_parts = flatpak_decompose_ref (app_ref, error);
if (app_ref_parts == NULL)
@@ -4390,11 +4492,15 @@ flatpak_run_app (const char *app_ref,
}
g_ptr_array_add (real_argv_array, g_strdup (command));
for (i = 0; i < n_args; i++)
g_ptr_array_add (real_argv_array, g_strdup (args[i]));
if (!add_rest_args (app_ref_parts[1], (flags & FLATPAK_RUN_FLAG_FILE_FORWARDING) != 0,
real_argv_array, args, n_args, error))
return FALSE;
g_ptr_array_add (real_argv_array, NULL);
commandline = flatpak_quote_argv ((const char **) real_argv_array->pdata);
g_debug ("Running '%s'", commandline);
if ((flags & FLATPAK_RUN_FLAG_BACKGROUND) != 0)
{
if (!g_spawn_async (NULL,

View File

@@ -85,6 +85,7 @@ typedef enum {
FLATPAK_RUN_FLAG_NO_SESSION_BUS_PROXY = (1 << 7),
FLATPAK_RUN_FLAG_NO_SYSTEM_BUS_PROXY = (1 << 8),
FLATPAK_RUN_FLAG_SET_PERSONALITY = (1 << 9),
FLATPAK_RUN_FLAG_FILE_FORWARDING = (1 << 10),
} FlatpakRunFlags;
gboolean flatpak_run_add_extension_args (GPtrArray *argv_array,