mirror of
https://github.com/flatpak/flatpak.git
synced 2026-01-26 14:13:26 +00:00
flatpak-run: Add parental controls support for filtering apps
Prevent the user from running a flatpak app if that app is filtered by the parental controls applied to the user. If flatpak is running as a system user (UID < 1000), ignore failure to load the app filter. This could happen if a flatpak is run in the gnome-initial-setup session, before the user’s account is created. Includes contributions by André Magalhães. Signed-off-by: Philip Withnall <withnall@endlessm.com> https://github.com/flatpak/flatpak/pull/2797
This commit is contained in:
parent
c16d6f9166
commit
ab5c0968e6
@ -161,6 +161,7 @@ libflatpak_common_la_CFLAGS = \
|
||||
$(INTERNAL_GPGME_CFLAGS) \
|
||||
$(JSON_CFLAGS) \
|
||||
$(LIBSECCOMP_CFLAGS) \
|
||||
$(MALCONTENT_CFLAGS) \
|
||||
$(OSTREE_CFLAGS) \
|
||||
$(SOUP_CFLAGS) \
|
||||
$(SYSTEMD_CFLAGS) \
|
||||
@ -175,6 +176,7 @@ libflatpak_common_la_LIBADD = \
|
||||
$(INTERNAL_GPGME_LIBS) \
|
||||
$(JSON_LIBS) \
|
||||
$(LIBSECCOMP_LIBS) \
|
||||
$(MALCONTENT_LIBS) \
|
||||
$(OSTREE_LIBS) \
|
||||
$(SOUP_LIBS) \
|
||||
$(SYSTEMD_LIBS) \
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/utsname.h>
|
||||
@ -36,6 +37,9 @@
|
||||
#ifdef HAVE_DCONF
|
||||
#include <dconf/dconf.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIBMALCONTENT
|
||||
#include <libmalcontent/malcontent.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SECCOMP
|
||||
#include <seccomp.h>
|
||||
@ -3167,6 +3171,92 @@ regenerate_ld_cache (GPtrArray *base_argv_array,
|
||||
return glnx_steal_fd (&ld_so_fd);
|
||||
}
|
||||
|
||||
/* Check that this user is actually allowed to run this app. When running
|
||||
* from the gnome-initial-setup session, an app filter might not be available. */
|
||||
static gboolean
|
||||
check_parental_controls (const char *app_ref,
|
||||
FlatpakDeploy *deploy,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
#ifdef HAVE_LIBMALCONTENT
|
||||
g_auto(GStrv) app_ref_parts = NULL;
|
||||
g_autoptr(MctManager) manager = NULL;
|
||||
g_autoptr(MctAppFilter) app_filter = NULL;
|
||||
g_autoptr(GAsyncResult) app_filter_result = NULL;
|
||||
g_autoptr(GDBusConnection) system_bus = NULL;
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
g_autoptr(GDesktopAppInfo) app_info = NULL;
|
||||
gboolean allowed = FALSE;
|
||||
|
||||
app_ref_parts = flatpak_decompose_ref (app_ref, error);
|
||||
if (app_ref_parts == NULL)
|
||||
return FALSE;
|
||||
|
||||
system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
|
||||
if (system_bus == NULL)
|
||||
return FALSE;
|
||||
|
||||
manager = mct_manager_new (system_bus);
|
||||
app_filter = mct_manager_get_app_filter (manager, getuid (),
|
||||
MCT_GET_APP_FILTER_FLAGS_INTERACTIVE,
|
||||
cancellable, &local_error);
|
||||
if (g_error_matches (local_error, MCT_APP_FILTER_ERROR, MCT_APP_FILTER_ERROR_DISABLED))
|
||||
{
|
||||
g_debug ("Skipping parental controls check for %s since parental "
|
||||
"controls are disabled globally", app_ref);
|
||||
return TRUE;
|
||||
}
|
||||
else if (local_error != NULL)
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Always filter by app ID. Additionally, filter by app info (which runs
|
||||
* multiple checks, including whether the app ID, executable path and
|
||||
* content types are allowed) if available. If the flatpak contains
|
||||
* multiple .desktop files, we use the main one. The app ID check is
|
||||
* always done, as the binary executed by `flatpak run` isn’t necessarily
|
||||
* extracted from a .desktop file. */
|
||||
allowed = mct_app_filter_is_flatpak_ref_allowed (app_filter, app_ref);
|
||||
|
||||
/* Look up the app’s main .desktop file. */
|
||||
if (deploy != NULL && allowed)
|
||||
{
|
||||
g_autoptr(GFile) deploy_dir = NULL;
|
||||
const char *deploy_path;
|
||||
g_autofree char *desktop_file_name = NULL;
|
||||
g_autofree char *desktop_file_path = NULL;
|
||||
|
||||
deploy_dir = flatpak_deploy_get_dir (deploy);
|
||||
deploy_path = flatpak_file_get_path_cached (deploy_dir);
|
||||
|
||||
desktop_file_name = g_strconcat (app_ref_parts[1], ".desktop", NULL);
|
||||
desktop_file_path = g_build_path (G_DIR_SEPARATOR_S,
|
||||
deploy_path,
|
||||
"export",
|
||||
"share",
|
||||
"applications",
|
||||
desktop_file_name,
|
||||
NULL);
|
||||
app_info = g_desktop_app_info_new_from_filename (desktop_file_path);
|
||||
}
|
||||
|
||||
if (app_info != NULL)
|
||||
allowed = allowed && mct_app_filter_is_appinfo_allowed (app_filter,
|
||||
G_APP_INFO (app_info));
|
||||
|
||||
if (!allowed)
|
||||
return flatpak_fail_error (error, FLATPAK_ERROR_PERMISSION_DENIED,
|
||||
/* Translators: The placeholder is for an app ref. */
|
||||
_("Running %s is not allowed by the policy set by your administrator"),
|
||||
app_ref);
|
||||
#endif /* HAVE_LIBMALCONTENT */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
flatpak_run_app (const char *app_ref,
|
||||
FlatpakDeploy *app_deploy,
|
||||
@ -3225,6 +3315,11 @@ flatpak_run_app (const char *app_ref,
|
||||
if (app_ref_parts == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Check the user is allowed to run this flatpak. */
|
||||
if (!check_parental_controls (app_ref, app_deploy, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
/* Construct the bwrap context. */
|
||||
bwrap = flatpak_bwrap_new (NULL);
|
||||
flatpak_bwrap_add_arg (bwrap, flatpak_get_bwrap ());
|
||||
|
||||
|
||||
@ -222,6 +222,11 @@ PKG_CHECK_MODULES(SYSTEMD, [libsystemd], [have_libsystemd=yes], [have_libsystemd
|
||||
if test $have_libsystemd = yes; then
|
||||
AC_DEFINE(HAVE_LIBSYSTEMD, 1, [Define if libsystemd is available])
|
||||
fi
|
||||
PKG_CHECK_MODULES([MALCONTENT], [malcontent-0 >= 0.4.0], [have_libmalcontent=yes], [have_libmalcontent=no])
|
||||
AS_IF([test "$have_libmalcontent" = "yes"],[
|
||||
AC_DEFINE([HAVE_LIBMALCONTENT], [1], [Define if libmalcontent is available])
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_LIBMALCONTENT],[test "$have_libmalcontent" = "yes"])
|
||||
|
||||
PKG_CHECK_MODULES(GLIB260, glib-2.0 >= 2.60,
|
||||
[AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_60, [Ignore massive GTimeVal deprecation warnings in 2.62])],
|
||||
@ -532,4 +537,5 @@ echo " Privileged group: $PRIVILEGED_GROUP"
|
||||
echo " Privilege mode: $with_priv_mode"
|
||||
echo " Use dconf: $have_dconf"
|
||||
echo " Use libsystemd: $have_libsystemd"
|
||||
echo " Use libmalcontent: $have_libmalcontent"
|
||||
echo ""
|
||||
|
||||
@ -112,6 +112,11 @@
|
||||
Flatpak sets the environment variable <envar>FLATPAK_ID</envar> to the application
|
||||
ID of the running app.
|
||||
</para>
|
||||
<para>
|
||||
If parental controls support is enabled, flatpak will check the
|
||||
current user’s parental controls settings, and will refuse to
|
||||
run an app if it is blacklisted for the current user.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user