Thunderbird snap and external GnuPG (for smart cards)

Hello,

I’ve looked into setting up Thunderbird with external GnuPG, so as to be able to use a smart card for key operations (e.g. a YubiKey). I think the expectation is that this should work (almost) out-of-the-box, but the reality is a bit different. I’m documenting my findings here, especially since Ubuntu 24.04 (noble) is only going to distribute Thunderbird exclusively as a snap. In short, it works, but there are changes necessary. The issues here were previously raised in a couple of topics [1, 2] and an LP bug report [3], but no solution was addressed.

I am using Ubuntu 23.10 (mantic) on amd64, snapd version 2.60.4+23.10.1 and thunderbird snap version 115.9.0-1 (revision 460).

First of all, I believe the expectation is that the only requirement, once mail.openpgp.allow_external_gnupg is enabled, is to connect the Thunderbird gpg-keys plug to the system slot, as such:

$ snap connect thunderbird:gpg-keys :gpg-keys

Unfortunately, this doesn’t suffice. There are three issues remaining. It’s important to know that, when external GnuPG is configured, Thunderbird uses the GPGme library for some operations, which has a backend that invokes gpg.

  1. Thunderbird is executed with HOME set to /home/user/snap/thunderbird/common, but GNUPGHOME set to /home/user/.gnupg. This means a non-default homedir configuration is assumed, hence the agent sockets are not looked up in /run/user/XXXX/gnupg, but rather in a hashed sub-directory, which can be computed using something like:

    $ HOME=/bla gpgconf --dry-run --homedir ~/.gnupg --list-dirs | grep ^socketdir:

  2. For some operations, GPGme is used and invokes /usr/bin/gpg which, in the snap confinement, doesn’t exist. $SNAP/usr/bin/gpg should be invoked instead (i.e. /snap/thunderbird/REVISION/usr/bin/gpg). PATH is set appropriately to include $SNAP/usr/bin. This was the most annoying (for me) to debug, since even when enabling full debugging with GPGME_DEBUG, there is no indication that invoking /usr/bin/gpg failed and the only logging provided is that the executed command did not produce any output.

  3. The AppArmor profile does not allow connecting to the agent sockets in /run/user/XXX/gnupg.

I’ve overcome these three issues and got smart card operations to work by doing the following two things:

  1. I created a wrapper script that is invoked by GPGme (using the mail.openpgp.alternative_gpg_path setting) that simply contains:

    #!/bin/sh
    HOME="$SNAP_REAL_HOME" $SNAP/usr/bin/gpg "$@"
    

    This overcomes the first two issues, but is of course rather ugly.

  2. I created an overriding AppArmor profile to allow connecting to the GPG agent sockets. This was the easiest to debug (the system log will clearly show the violations), but unfortunately the snap-provided profile does not include a local file for tweaks, so unfortunately this was a bit of a hack (even more so than the previous step). Therefore, I’m not including instructions about this here, as for anyone who understands AppArmor and the implications of doing that it should be trivial; if you’re not comfortable with AppArmor, following my instructions could put you at risk, so I would advise against it.

That’s it. I hope the information I provided will allow the Thunderbird snap to be packaged in a way that allows this to work (almost) out-of-the-box, especially since the use of smart cards could increase in the future, with all the supply-chain attacks going on around.

I’m happy to help with any testing and further information.

[1] Thunderbird snap and smart card

[2] Link not included because I am a new user, but its t/thunderbird-snap-gpg-keys/13930

[3] Bug #2009825 “snap thunderbird cannot sign messages with externa...” : Bugs : thunderbird package : Ubuntu