Use the user’s OARS filter to prevent installation or upgrade of
apps which have more extreme content than the user is allowed to see.
This uses libmalcontent to load the user’s enforced OARS filter, which
describes the extremeness of each type of content the user is allowed to
see. If an app they are trying to install exceeds the filter value in
any OARS section, installation is disallowed and an error is returned.
libmalcontent stores the parental controls policy per-user in
accountsservice, which enforces access control on the policies.
The app filter is also allowed to prevent app installation entirely,
which overrides the OARS values. This is independent from the app-install
polkit action, which determines whether an unprivileged user may install
an app system-wide. Being stored in accountsservice, the new boolean is
also easier to set per-user without having to programmatically write a
polkit JS policy file which handles multiple users (and parse it back
again).
The parental controls checks are done at deploy time, either in the
`flatpak` process (for user repositories) or in the
`flatpak-system-helper` (for system repositories). The checks use
content rating data extracted from the app’s AppData XML and stored in
the `FlatpakDeploy` cache. The checks are passed through polkit (even
for user repositories) so that users can get an admin override to
install apps which would otherwise be too extreme. This uses the new
`org.freedesktop.Flatpak.parental-controls` polkit rule.
The checks have to be done at deploy time, as that’s when the AppData
XML for the app is parsed. The downside of this arrangement is that an
app must be entirely downloaded before the parental checks can be done.
This won’t be much of an issue on normal desktops, however, since we can
assume that gnome-software will check an app’s appropriateness before
showing it to the user in the first place.
Parental controls are not enforced for non-apps/runtimes, which includes
the ostree-metadata and appstream/* refs.
One thorny issue is that flatpak unit tests may be run in an environment
with no system D-Bus available to connect to (a Jenkins instance, for
example), which means the call to `mct_manager_get_app_filter()` in
`flatpak_dir_check_parental_controls()` fails.
So this commit skips the parental controls check if the system bus is
unavailable and the environment variable
`FLATPAK_SYSTEM_HELPER_ON_SESSION` is set, since the testlibrary already
sets that variable so that the system-helper will be started on the
session bus.
The feature can be tested using something like:
```
$ malcontent-client set philip \
violence-realistic=none app/org.freedesktop.Bustle/x86_64/stable
App filter for user 1000 set
$ flatpak run org.freedesktop.Bustle
error: Running app/org.freedesktop.Bustle/x86_64/stable is not allowed by the policy set by your administrator
$ flatpak --user install flathub io.github.FreeDM
error: Failed to install io.github.FreeDM: Installing app/io.github.FreeDM/x86_64/stable is not allowed by the policy set by your administrator
```
Includes work by André Magalhães and Umang Jain.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Flatpak is a system for building, distributing, and running sandboxed desktop applications on Linux.
See https://flatpak.org/ for more information.
Community discussion happens in #flatpak on Freenode and on the mailing list.
Read documentation for Flatpak, its commandline tools, and for the libflatpak library API.
Contributing
Flatpak welcomes contributions from anyone! Here are some ways you can help:
- Fix one of the issues and submit a PR
- Update flatpak's translations and submit a PR
- Improve flatpak's documentation, hosted at http://docs.flatpak.org and developed over in flatpak-docs
- Find a bug and submit a detailed report including your OS, flatpak version, and the steps to reproduce
- Add your favorite application to Flathub by writing a flatpak-builder manifest and submitting it
- Improve the Flatpak support in your favorite Linux distribution
Hacking
Flatpak uses a traditional autoconf-style build mechanism. To build just do
./autogen.sh
./configure [args]
make
make install
To automatically install dependencies on apt-based distributions you can try
running apt build-dep flatpak and on dnf ones try dnf builddep flatpak.
Dependencies you will need include: autoconf, automake, libtool, bison,
gettext, gtk-doc, gobject-introspection, libcap, libarchive, libxml2, libsoup,
gpgme, polkit, libXau, ostree, json-glib, appstream, libseccomp (or their devel
packages).
Most configure arguments are documented in ./configure --help. However,
there are some options that are a bit more complicated.
Flatpak relies on a project called Bubblewrap for the
low-level sandboxing. By default, an in-tree copy of this is built
(distributed in the tarball or using git submodules in the git
tree). This will build a helper called flatpak-bwrap. If your system
has a recent enough version of Bubblewrap already, you can use
--with-system-bubblewrap to use that instead.
Bubblewrap can run in two modes, either using unprivileged user
namespaces or setuid mode. This requires that the kernel supports this,
which some distributions disable. For instance, Debian and Arch
(linux kernel v4.14.5
or later), support user namespaces with the kernel.unprivileged_userns_clone
sysctl enabled.
If unprivileged user namespaces are not available, then Bubblewrap must be built as setuid root. This is believed to be safe, as it is designed to do this. Any build of Bubblewrap supports both unprivileged and setuid mode, you just need to set the setuid bit for it to change mode.
However, this does complicate the installation a bit. If you pass
--with-priv-mode=setuid to configure (of Flatpak or Bubblewrap) then
make install will try to set the setuid bit. However that means you
have to run make install as root. Alternatively, you can pass
--enable-sudo to configure and it will call sudo when setting the
setuid bit. Alternatively you can enable setuid completely outside of
the installation, which is common for example when packaging Bubblewrap
in a .deb or .rpm.
There are some complications when building Flatpak to a different
prefix than the system-installed version. First of all, the newly
built Flatpak will look for system-installed flatpaks in
$PREFIX/var/lib/flatpak, which will not match existing installations.
You can use --with-system-install-dir=/var/lib/flatpak to make both
installations use the same location.
Secondly, Flatpak ships with a root-privileged PolicyKit helper for
system-wide installation, called flatpak-system-helper. It is D-Bus
activated (on the system bus) and if you install in a non-standard
location it is likely that D-Bus will not find it and PolicyKit
integration will not work. However, if the system installation is
synchronized, you can often use the system installed helper instead—
at least if the two versions are close in versions.
This repository
The Flatpak project consists of multiple pieces, and it can be a bit challenging to find your way around at first. Here is a quick intro to the major components of the flatpak repo:
common: contains the library, libflatpak. It also contains various pieces of code that are shared between the library, the client and the services. Non-public code can be recognized by having a-private.hheader file.app: the commandline client. Each command has aflatpak-builtins-source filedata: D-Bus interface definition filessession-helper: The flatpak-session-helper service, which provides various helpers for the sandbox setup at runtimesystem-helper: The flatpak-system-helper service, which runs as root on the system bus and allows non-root users to modify system installationsportal: The Flatpak portal service, which lets sandboxed apps request the creation of new sandboxesdoc: The sources for the documentation, both man pages and library documentationtests: The testsuitebubblewrap: Flatpak's unprivileged sandboxing tool which is developed separately and exists here as a submodulelibglnx: a small utility library for projects that use GLib on Linux, as a submoduledbus-proxy: a filtering proxy for D-Bus connections, as a submodule