libappstream-glib is mostly unmaintained, and libappstream is more
actively developed (and up to date with the AppStream specification).
Port from libappstream-glib to libappstream. Handily, a lot of the APIs
are exactly the same. The main changes are:
* `AsApp` → `AsComponent`
* `AsStore` → `AsMetadata`
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
(Mostly done by Philip, then Phaedrus finished this)
This commit re-works how we automatically "pin" runtimes that are
explicitly installed, to prevent them from being removed automatically.
In this implementation we do the update to the config as part of the
deploy, which has the following advantages:
(1) It ensures that there's never a confusing polkit prompt about
configuring the software installation when the user asked for a runtime
to be installed (https://github.com/flatpak/flatpak/issues/4200)
(2) It means we don't have to rely on the code on the error path of
flatpak_transaction_real_run() to un-pin the runtime in case something
went wrong with the installation, since we pin it almost atomically with
the deploy.
Fixes#4200
The system helper was already correctly using the `NO_INTERACTION` flag
in the D-Bus call flags to determine whether polkit calls from
`flatpak_authorize_method_handler()` should allow interactivity.
However, the system helper was not setting the no-interaction property
on the `FlatpakDir` used in the subsequent operation. When parental
controls are enabled, this sometimes results in polkit allowing
interaction when prompting for the `override-parental-controls` action,
even if the D-Bus call which activated the system helper specified the
`NO_INTERACTION` flag.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
For updates in remotes with a local (file:) uri we just do a deploy
with a LOCAL_PULL flag set and an empty arg_repo_path. However, our
arg_repo_path checking at some point seemed to stop properly handling
the case where it is empty. I got it to report "No such file" wich
broke the tests.
I don't think this error code path will really be hit in practice,
except perhaps for a maliciously crafted D-Bus message trying to get the
system helper to crash.
Currently when a polkit prompt is created for an app uninstallation, the
message is something like "Authentication is required to uninstall
app/us.zoom.Zoom/x86_64/stable" which is not very friendly for
non-technical users. Change it to "Authentication is required to
uninstall Zoom".
For many of the other polkit actions used by the system-helper, we just
say "software" rather than specifying the app/runtime, since we use the
authorization from one action for others via imply annotations, so the
user is really authorizing several things at once in some cases. In the
case of app-uninstall actions, the only implied action is
runtime-uninstall, and runtimes aren't something users should generally
have to worry about anyway, so it seems alright to specify the app. I
presume that was why commit 21f845c1a didn't remove the ref from the
app-uninstall action message.
As discussed here [1], we want a way to mark runtimes to be kept even
when they are unused by any apps and we are removing such runtimes.
Currently this is a command that can be run manually; a subsequent
commit will pin runtimes automatically if they are installed
independently of any app.
A unit test is included.
[1] https://github.com/flatpak/flatpak/issues/2639#issuecomment-662311756
Currently with the sideload implementation of offline updates you have
to manually create a symlink to your USB drive to sideload from it,
which is a regression compared to the previous implementation which
scanned all mounted filesystems in OstreeRepoFinderMount in libostree.
So this commit adds a few systemd units and a bash script so that any
time a USB drive is plugged in and automatically mounted by udisks, a
symlink to it is created in /run/flatpak/sideload-repos. When the drive
is unplugged the symlink is removed.
However this solution still has a lot of moving parts, so we may want to
instead have libflatpak use GVolumeMonitor and find the mounted
filesystems itself; see https://github.com/flatpak/flatpak/issues/3705
Fixes https://github.com/flatpak/flatpak/issues/3490
If the magical io.github.containers.DeltaUrl label is set in the
index, then try to download this to use as the delta manifest for the
image. This allows servers to store deltas outside the registry
itself. The label is propagated to the xa.delta-url metadata in the
generated "fake summary" for the remote, and read back on pull.
Note that the delta manifest layers descriptor will need to have a
"urls" key where it references the blobs if the blobs are also not
stored on the registry.
If the specified manifest doesn't exist or doesn't apply to the target
image we fall back to resolving via the _deltaindex tag.
To avoid the complexities of passing (and chaining) OstreeAsyncProgress
objects around, we only create one just before calling to ostree.
The rest of flatpak only ever uses the new FlatpakProgress object.
Co-authored by: Philip Chimento <philip@endlessm.com>
This used to not be set for collection-id remotes as we used the
ostree-metadata branch for resolving. However, we now use the summary
always when doing a remote install (and not ostree-metadata for local
sideloads), so we still want to verify summary.
The signature on the summary is a nice security feature, but it is also
a very efficient small file to download to verify that no new summary
needs to be downloaded in the no-op update case.
Most code that looks for a regular collection id set on the remote is
removed, as these should never happen in flatpak repo setups now.
Some is replaces with looking at xa.sideload-collection-id:
* The libflatpak FlatpakRef::collection-id property now comes comes from the sideload id
* Various CLI commands showing or changing the collection-id for a remote now uses the sideload id
* Collection id deploy in update now sets the sideload-collection-id instead
* Setting the collection id for a remote in libflatpak now sets the sideload id
Additionally we now delete the code that allows unsigned summaries
when there is a collection id (because there is none).
create-usb now uses the sideload id as as collection id source when exporting.
The direct repo operations (export, bundle, commit-from) still support
collection ids, because on the server we do want to set it so that we
can sideload.
This adds a xa.sideload-collection-id option to the remote
configuration and a global xa.sideload-repos option (which is a list
of paths to local repos).
When resolving or listing refs, if we fail to download the real remote
summary (i.e. we're offline) then we instead look into the configured
sideloaded repos for refs that match ref and the sideloaded collection
id for the remote.
For the transaction to resolve the ref we need more metadata. In the
regular summary case we use the metadata from the summary, but that
is not available in the (partial) summary in the sideload repo, so
there we load the actual commit object and use the data from there.
(The ostree-metadata branch is not used/needed.)
This actually also fixes a longstanding issue when you "flatpak update
--checksum=XYZ" because we now handle this correctly by downloading
the commit object from the remote. Before we used the metadata in the
summary which is not right for non-HEAD commits.
To handle the sideloading we record the path to the sideload repo
when sideloading and pass the url to the repo as the remote name
when pulling, which will do a direct local pull.
We avoid using sideloaded refs when offline if the timestamp in the
commits is older than what is already installed locally.
We're using the metadata from the summary, ostree-metadata or available
commit when making security sensitive decisions, so lets verify this
matches what we get in the actual commit we pulled.
We already did check that this then actually also matches what gets deployed,
so the new check shares code with that.
Note, we don't do this for OCI installs, because it seems the current
fedora flatpaks don't have this set, and we don't want to break
existing remotes.
This is a g_autoptr version of OstreeAsyncProgress that also
calls ostree_async_progress_finish() before being freed.
This should be used in all "leaf" functions that creates an asyncprogress
to avoid leaking any idle change idle sources. Using a auto* means
some code can be cleaned up to avoid goto out style handling for this.
Also, this adds a missing finish() in
_flatpak_dir_fetch_remote_state_metadata_branch().
Due to bug #3215 some systems have refs in refs/mirrors/ in addition to
the usual refs/remotes/ location. The remote refs are always at least as
new as the mirror ones since the repo_pull() invocation in
flatpak_dir_pull() which does not use OSTREE_PULL_FLAGS_MIRROR happened
after the one that did. Cleaning up these mirror refs is important since
otherwise when the remote ref is either updated or removed (by an
uninstall) disk space will be leaked since the mirror ref will point to
a no longer needed commit.
So, remove (almost) all mirror refs during flatpak repair, uninstall,
or update operations. And for the uninstall and update operations do it
in FlatpakDir so that it happens regardless of if the CLI of libflatpak
are used.
Also, add a unit test for this.
Fixes https://github.com/flatpak/flatpak/issues/3222
After an unprivileged client calls GetRevokefsFd(), the `revokefs-fuse
--backend` process busyloops as follows:
poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}], 2, -1) = 1 ([{fd=4, revents=POLLIN}])
Here is the command line for this process:
revokefs-fuse --backend --socket=3 --exit-with-fd=4 /var/lib/flatpak/repo/tmp/flatpak-cache-JBUHB0
The intention here is to poll() until fd 3 is readable (at which
point the writer process serves a client request and writes back a
response, synchronously) or fd 4 encounters an error. fd 4 is meant to
be one side of a pipe that the system helper holds the other end of;
when the pipe is broken, the system helper must have gone away, and the
`revokefs-fuse --backend` process treats this as a signal to exit.
However, fd 4 is not a pipe. In fact, it is the dirfd for the target directory:
root@camille:/var/roothome# ls -l /proc/31717/fd
total 0
lr-x------ 1 wjt wjt 64 Nov 19 21:21 0 -> /dev/null
lrwx------ 1 wjt wjt 64 Nov 19 21:21 1 -> /dev/pts/1
lrwx------ 1 wjt wjt 64 Nov 19 21:21 2 -> /dev/pts/1
lrwx------ 1 wjt wjt 64 Nov 19 21:21 3 -> 'socket:[2558007]'
lr-x------ 1 wjt wjt 64 Nov 19 21:21 4 -> /var/lib/flatpak/repo/tmp/flatpak-cache-JBUHB0
This is because revokefs_fuse_backend_child_setup() erroneously closes
fd 4 before the `revokefs-fuse --backend` process is exec()d. This
regressed in d91660fe2a.
Fix this by only closing fds 5 and above. With this change, we see the
expected set of open file descriptors:
root@camille:/var/roothome# ls -l /proc/32493/fd
total 0
lr-x------ 1 wjt wjt 64 Nov 19 21:24 0 -> /dev/null
lrwx------ 1 wjt wjt 64 Nov 19 21:24 1 -> /dev/pts/1
lrwx------ 1 wjt wjt 64 Nov 19 21:24 2 -> /dev/pts/1
lrwx------ 1 wjt wjt 64 Nov 19 21:24 3 -> 'socket:[2552594]'
lr-x------ 1 wjt wjt 64 Nov 19 21:24 4 -> 'pipe:[2552596]'
lr-x------ 1 wjt wjt 64 Nov 19 21:24 5 -> /var/lib/flatpak/repo/tmp/flatpak-cache-JBUHB0
Fixes#2882.
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>
As per https://gitlab.gnome.org/GNOME/glib/merge_requests/490
there is a bug in glib < 2.60 where g_spawn_* can sometimes deadlock
due to using malloc in the child func to close fds.
We work around this in places where the code is (potentially) threaded
by passing glib flags to leave fds alone and then do a very naive
(but safe) fd cloexec loop ourselves.
Currently flatpak_installation_fetch_remote_ref_sync() does not work
offline. It returns an error when it fails to fetch the remote's summary
in flatpak_dir_get_remote_state(). This is a problem since GNOME
Software (or at least the Endless fork) uses this library function to
display apps it finds on a USB drive (see gs_plugin_refine_item_origin()
in gs-flatpak.c) and that's something that should work even offline.
So this commit changes flatpak_dir_get_remote_state_optional() so that
it accepts the only_cached option, and updates the call sites. Also have
fetch_remote_ref_sync() use flatpak_dir_get_remote_state_optional(),
which means that when we're offline we will use the xa.cache data in the
ostree-metadata ref as a list of refs list instead of using a summary.
However since the commit checksums are not in xa.cache, we don't have
enough information to form a FlatpakRemoteRef. So also call
ostree_repo_find_remotes_async() to get the commit from any LAN or USB
sources that may be available. This may not be very performant but at
least it only happens if the ref wasn't found in a remote summary; see
https://github.com/flatpak/flatpak/issues/1862
It's sad this code is so long-winded but it's difficult to break out a
helper function that could be shared with
list_remotes_for_configured_remote() above. Longer term we could improve
the ostree_repo_find_remotes_async() API and add options to remove the
need to manually handle OstreeRepoFinder objects.
Closes: #3114
Approved by: alexlarsson
If xa.languages is set, use these, and no others. Otherwise, take the union
of xa.extra-languages, and the system default locales for system repos;
xa.extra-languages for user repo and the langs based on the user's locale
Fixes https://github.com/flatpak/flatpak/issues/3043
We now pull the image config as well as the manifest and fall
back on the labels field if the keys we're looking for are not
in the annotations field.
This lets us support docker manifests too, which don't have
annotations (but do have labels).
Closes: #2978
Approved by: alexlarsson