document-portal: add support to activate paths inside /app

When the document portal is called from within the sandbox with an
app-private file path, translate the path to a document portal URI in
order to make it available to other applications.
tingping/wmclass
Cosimo Cecchi 2016-07-11 13:48:13 -07:00
parent d488914614
commit 90a3522148
3 changed files with 100 additions and 5 deletions

View File

@ -46,6 +46,8 @@ AM_CPPFLAGS = \
-I$(srcdir)/libglnx \
-I$(srcdir)/common \
-I$(builddir)/common \
-I$(srcdir)/lib \
-I$(builddir)/lib \
$(NULL)
if WITH_SYSTEM_BWRAP

View File

@ -33,5 +33,5 @@ xdg_document_portal_SOURCES = \
document-portal/xdp-fuse.c \
$(NULL)
xdg_document_portal_LDADD = $(BASE_LIBS) $(FUSE_LIBS) libflatpak-common.la
xdg_document_portal_CFLAGS = $(BASE_CFLAGS) $(OSTREE_CFLAGS) $(SOUP_CFLAGS) $(FUSE_CFLAGS) -I$(srcdir)/document-portal -I$(builddir)/document-portal -I$(srcdir)/permission-store -I$(builddir)/permission-store
xdg_document_portal_LDADD = $(BASE_LIBS) $(FUSE_LIBS) libflatpak-common.la libflatpak.la
xdg_document_portal_CFLAGS = $(BASE_CFLAGS) $(OSTREE_CFLAGS) $(SOUP_CFLAGS) $(FUSE_CFLAGS) -I$(srcdir)/document-portal -I$(builddir)/document-portal -I$(srcdir)/permission-store -I$(builddir)/permission-store -DFLATPAK_COMPILATION

View File

@ -16,6 +16,8 @@
#include "xdp-util.h"
#include "flatpak-db.h"
#include "flatpak-dbus.h"
#include "flatpak-installation.h"
#include "flatpak-installed-ref.h"
#include "flatpak-utils.h"
#include "flatpak-portal-error.h"
#include "permission-store/permission-store-dbus.h"
@ -365,6 +367,45 @@ validate_fd_common (int fd,
return TRUE;
}
static char *
resolve_flatpak_path (const char *path,
const char *app_id)
{
g_autoptr(FlatpakInstalledRef) app_ref = NULL;
g_autoptr(FlatpakInstallation) user_install =
flatpak_installation_new_user (NULL, NULL);
if (user_install)
{
app_ref =
flatpak_installation_get_current_installed_app (user_install,
app_id,
NULL, NULL);
}
if (!app_ref)
{
g_autoptr(FlatpakInstallation) system_install =
flatpak_installation_new_system (NULL, NULL);
if (system_install)
{
app_ref =
flatpak_installation_get_current_installed_app (system_install,
app_id,
NULL, NULL);
}
}
if (!app_ref)
return NULL;
const char *deploy_dir = flatpak_installed_ref_get_deploy_dir (app_ref);
return g_build_filename (deploy_dir, "files", path, NULL);
}
static gboolean
validate_parent_dir (const char *path,
struct stat *st_buf,
@ -399,6 +440,45 @@ validate_parent_dir (const char *path,
return TRUE;
}
static gboolean
validate_sandboxed_fd (int fd,
const char *app_id,
struct stat *st_buf,
struct stat *real_parent_st_buf,
char *path_buffer,
GError **error)
{
char sandboxed_path_buffer[PATH_MAX + 1];
char *rel_path;
g_autofree char *app_path = NULL;
if (!validate_fd_common (fd, st_buf, sandboxed_path_buffer, error))
return FALSE;
rel_path = strstr (sandboxed_path_buffer, "/app");
if (rel_path != NULL)
{
rel_path += strlen ("/app");
app_path = resolve_flatpak_path (rel_path, app_id);
}
if (app_path == NULL)
{
g_set_error (error,
FLATPAK_PORTAL_ERROR, FLATPAK_PORTAL_ERROR_INVALID_ARGUMENT,
"Invalid fd passed");
return FALSE;
}
strncpy (path_buffer, app_path, PATH_MAX);
if (!validate_parent_dir (path_buffer, st_buf, real_parent_st_buf, error))
return FALSE;
return TRUE;
}
static gboolean
validate_fd (int fd,
struct stat *st_buf,
@ -443,10 +523,23 @@ portal_add (GDBusMethodInvocation *invocation,
fd = fds[fd_id];
}
if (!validate_fd (fd, &st_buf, &real_parent_st_buf, path_buffer, &error))
if (strcmp (app_id, "") != 0)
{
g_dbus_method_invocation_take_error (invocation, error);
return;
/* Called from inside the sandbox */
if (!validate_sandboxed_fd (fd, app_id, &st_buf, &real_parent_st_buf, path_buffer, &error))
{
g_dbus_method_invocation_take_error (invocation, error);
return;
}
}
else
{
/* Called from outside of the sandbox */
if (!validate_fd (fd, &st_buf, &real_parent_st_buf, path_buffer, &error))
{
g_dbus_method_invocation_take_error (invocation, error);
return;
}
}
if (st_buf.st_dev == fuse_dev)