mirror of
https://github.com/flatpak/flatpak.git
synced 2026-03-13 20:52:39 -04:00
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:
committed by
Alexander Larsson
parent
75b84b4bfe
commit
153dd18a7d
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user