Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AppImage: automatically detect profile #4355

Open
reinerh opened this issue Jun 11, 2021 · 11 comments
Open

AppImage: automatically detect profile #4355

reinerh opened this issue Jun 11, 2021 · 11 comments
Labels
enhancement New feature request

Comments

@reinerh
Copy link
Collaborator

reinerh commented Jun 11, 2021

When you want to start an AppImage with firejail, it currently loads the default.profile by default (when you don't explicitely specify which profile to load).
The default profile is in most cases not very helpful, so you have to manually specify --profile= to load the right profile.

It would be nice if firejail could automatically detect which profile to load.

@reinerh reinerh added the enhancement New feature request label Jun 11, 2021
@rusty-snake
Copy link
Collaborator

I always thought that this is not possible because an AI can have any name and the notation often varies (e.g. KeePassXC vs. keepassxc). Do the most AI have a consistent name inside?

@reinerh
Copy link
Collaborator Author

reinerh commented Jun 11, 2021

I don't know enough about AppImages. Maybe a profile name could be determined heuristically via the AppImage filename?

And we should maybe also mention in the manpage that probably a profile needs to be specified as well. (just noticed it has already been added to the manpage in d9458eb)

Edit: But you are right, with mixed cases in the name, it's probably difficult to find the right profile. But maybe it could work for some cases. If $name.profile exists or lowercase($name).profile exists, use that, otherwise fall back to default.profile...

@kmk3
Copy link
Collaborator

kmk3 commented Jun 12, 2021

I think that the only way to properly detect the declared program name would be
to read some sort of "manifest" inside of the AppImage (either in the image or
directly in the binary).

The good news is that the specification says that every image should
contain one (and only one) .desktop file in the root dir:

myapp.desktop

A desktop file located in the root directory, describing the payload
application. As AppImage is following the principle one app = one file, one
desktop file is enough to describe the entire AppImage. There MUST NOT be
more than one desktop file in the root directory. The name of the file
doesn’t matter, as long as it carries the .desktop extension. Can be a
symlink to subdirectories such as usr/share/applications/...

The name of this file could be used to determine the profile, just like
firejail currently already does with normal .desktop files.

But do note that an AppImage may have a .desktop file named in any way (and
this is invisible to the user), so a malicious AppImage could pretend to be a
different program, such as one which has a firejail profile with broad
permissions.

Now, the issue is in how to properly and reliably extract the contents of an
AppImage without running it. According to the documentation, it is a work
in progress:

There is currently no way to use the former method without calling the target
AppImage. This might not always be appropriate, e.g., if the AppImage is not
trustworthy.

The AppImage team is working on implementing a mount option in
appimagetool. Please see the related GitHub issue for progress on
this.

According to the author in the issue above, it's already possible with
AppImageKit:

So, here is how to extract (unpack) AppImages without having to run them:

  • For type-2 AppImages, you can extract them by
wget -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/runtime-x86_64"
chmod +x runtime-x86_64
TARGET_APPIMAGE=pat/to/AppImage ./runtime --appimage-extract ./runtime-x86_64
  • For type-1 AppImages, you can extract them by renaming them .iso and then
    using a tool like Iso7z that can handle zisofs to extract them, or
    loop-mounting them

This answer should also address the original question, "Provide way to
mount/extract AppImages without having user call them", hence closing.

The problem with this approach is that it requires downloading and running
binaries outside of the distro repos, which I'd rather not do.

And AFAICT AppImageKit is not packaged on Arch/Artix, not even in the AUR,
which is a bummer. And I couldn't find it on Debian either.

So these are the alternatives that I thought of:

  1. Get AppImageKit packaged in distros
  2. Copy and paste the extraction code
  3. Rewrite the extraction code from scratch

@kmk3
Copy link
Collaborator

kmk3 commented Jun 12, 2021

So, I just found this:

From README.md:

unappimage

A lightweight AppImage extractor, forked from squashfs-tools's unsquashfs.

From README:

Tools:

  • mksquashfs to create squashfs images
  • unsquashfs to unpack squashfs images

The project at least exists in the AUR:

If this would be considered good enough for now, firejail could try detecting
if the unsquashfs command exists and use it if it does.

@rusty-snake
Copy link
Collaborator

The name of this file could be used to determine the profile, just like
firejail currently already does with normal .desktop files.

Actually this does not really work because of names like org.gnome.Maps.desktop or mozilla-firefox.desktop. (#2624)
Can we parse the Exec= line in it or is it just something like bin/app?

Now, the issue is in how to properly and reliably extract the contents of an
AppImage without running it.

AFAIK that is what we already do.

@kmk3
Copy link
Collaborator

kmk3 commented Jun 12, 2021

@rusty-snake commented 13 hours ago:

The name of this file could be used to determine the profile, just like
firejail currently already does with normal .desktop files.

Actually this does not really work because of names like
org.gnome.Maps.desktop or mozilla-firefox.desktop. (#2624)

In that case I'd consider adding profiles that redirect to the
normal/non-AppImage ones. Example:

  • org.gnome.Maps.desktop.profile -> gnome-maps.profile

The amount of extra redirect profiles could get rather unwieldly, but I suppose
that we could put them in a separate etc/appimage dir to mitigate that.

Can we parse the Exec= line in it or is it just something like bin/app?

I also thought about parsing Exec=, though considering that it's a command
line, I'd expect it to be a source of corner cases. Ideally, it would be done
using just the C equivalent of something like this:

cut -f 2 -d = | cut -f 1 -d ' ' | xargs -E '' -n 1 basename

Example:

$ printf 'Exec=some/path/foobar -abc\n' | cut -f 2 -d = | cut -f 1 -d ' ' |
  xargs -E '' -n 1 basename
foobar

But what if it's run using sh -c? I have seen (or at least tried to do) this
before on normal .desktop files, as Exec does not support shell syntax, such
as environment variables; it just executes the arguments as is. Example:

# fails
Exec=/usr/bin/foo "${HOME}"
# should work (or something similar)
Exec=sh -c '/usr/bin/foo "${HOME}"'

I'm not sure how common that is in AppImages compared to normal .desktop files,
but still, considering that a shell can be used, anything is possible...

Additionally, I think that the org.foo program name is meant to be something
rather stable. As in, I'd expect it bo be changed once or twice at most, if at
all. And if it does change, we would just have to copy and paste a redirect
profile (kind of like dbus-(user|system).* may have different filters
referring to the same thing). Whereas if the Exec line changes from one
version to the next (e.g.: from Exec=foo to Exec=sh -c 'a=b foo'), how
would it be handled?

Now, the issue is in how to properly and reliably extract the contents of
an AppImage without running it.

AFAIK that is what we already do.

Nice; in that case ignore those suggestions.

@kmk3
Copy link
Collaborator

kmk3 commented Jun 12, 2021

So, here is how to extract (unpack) AppImages without having to run them:

  • For type-2 AppImages, you can extract them by
wget -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/runtime-x86_64"
chmod +x runtime-x86_64
TARGET_APPIMAGE=pat/to/AppImage ./runtime --appimage-extract ./runtime-x86_64
  • For type-1 AppImages, you can extract them by renaming them .iso and
    then using a tool like Iso7z that can handle zisofs to extract them, or
    loop-mounting them

This answer should also address the original question, "Provide way to
mount/extract AppImages without having user call them", hence closing.

The problem with this approach is that it requires downloading and running
binaries outside of the distro repos, which I'd rather not do.

And AFAICT AppImageKit is not packaged on Arch/Artix, not even in the AUR,
which is a bummer. And I couldn't find it on Debian either.

I just noticed this mentioned on the AppImageKit CONTRIBUTING.md:

Our software comes in AppImage format. Everything else is
unsupported by us

To be clear, I consider that it's one thing to download and run the AppImage of
a GUI program (e.g.: Firefox) under firejail with a built-in whitelisting
profile, and that it's a rather different beast to download and run a tool
which is general-purpose (and thus might potentially need broad permissions)
and which currently has no firejail profile.

@netblue30
Copy link
Owner

OK, I went for @reinerh idea, checking the name of the archive (using strcasestr) against the list of programs in /usr/lib/firejail/firecfg.config. Try it out, if nothing else comes up we release it in one or two weeks.

e770ab6

@rusty-snake
Copy link
Collaborator

The name of 16 AIs randomly picked from AppImageHub:

Auryo-2.5.4.AppImage
melodie-2.0.0-alpha.2-x86_64.AppImage
swaglyrics-x86_64.AppImage
CasterSoundboard-1a84315-x86_64.AppImage
GSequencer-3.8.12-x86_64.AppImage
gifcurry-6.0.1.0-x86_64.AppImage
MediaElch_linux_2.8.12_2021-05-10_06-46_git-master-08ebf8c.AppImage
admin-tools-0-Build34.11.glibc2.15-x86_64.AppImage
BrainVerse-0.0.8-alpha-x86_64.AppImage
Dana-x86_64.AppImage
Qucs-S-0.0.22_x86_64.AppImage
accessimap-lecteur-der-0.0.34-i386.AppImage
apk-editor-studio_linux_1.4.0.AppImage
airspaces-electron-2.6.0-x86_64.AppImage
Altitude-Metrix-Wallet-linux-x64.AppImage
dust3d-1.0.0-rc.6.AppImage

I think the most users won't rename their AIs. They just download and move to e.g. ~/.appimages (and create a wrapper-script, symlink, .desktop, ...)

@netblue30
Copy link
Owner

All these will end up using default.profile.

@rusty-snake
Copy link
Collaborator

Do we want to improve the heuristic or close here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature request
Projects
None yet
Development

No branches or pull requests

4 participants