And on with the “final” component of the package signing saga… I have previously posted about signing packages and databases and managing the PGP keyring, which was all preparatory work for pacman to be able to verify the signatures.

In the end, most people will not notice pacman verifying signatures unless something goes wrong (at least once it is configured). You will see the same “checking package integrity” line, but instead of verifying the packages md5sum, the PGP signature will be checked if available. But implementing this required substantial reworking of the libalpm backend, with the adding of signature verification abilities through the use of the gpgme library, adding flexible configuration options to control repo and package signature verification, changes to how and when repo databases get loaded (so that we can error out early if the repo signature is bad), and the list goes on… The majority of this was done by Dan McGee, who is the lead pacman developer. In fact, looking at the git shortlog for this development cycle:

$ git shortlog -n -s --no-merges maint..

296 Dan McGee

128 Dave Reisner

124 Allan McRae

...

(followed by 18 other contributors with 11 or less commits each). So Dan takes the clear lead with about 50% of all commits in this developmental cycle, while the battle for second place remains intensely competed for!

So what have we ended up with? My opinion is ever so slightly biased, but I think we have ended up with the most complete and flexible package signing implementation yet. Most other package managers signature checking is simply a call to gpgv , which trusts any signature in your keyring. With the more complicated solution using gpgme , pacman has the complete concept of the web of trust, allowing for very precise keyring management. We not only sign packages, but sign databases too. Importantly, we can add expiry times to those signatures, which together prevents a malicious mirror holding back individual package updates or deliberately not providing any updates at all. As an aside, we also now protect against the “endless data attack” where an attacker sends an endless data stream instead of the requested file. Together that covers the most well reported avenues of attack on package managers (I hesitate to say “all” despite not knowing of any others because someone will prove me wrong!).

Onward to the actual use of signature checking in pacman . The main adjustment needed to be made is the addition of the SigLevel directive to pacman.conf . This can be specified at a global level and also on a per-repo basis. The SigLevel directive takes three main values: Required , which forces signature checking to be performed; Optional (default), which will check signatures if present but unsigned packages and databases will be accepted; and Never , which sets no signature checking to be preformed. More fine grained control can be added by prefixing these options with Database and Package and combining multiple options. For example, I have a local repo that has a signed database but not all packages have signatures. So I use SigLevel = Optional for my global default and add SigLevel = DatabaseRequired to enforce the database to be validly signed for that repo. Alternatively, I could use SigLevel = DatabaseRequired PackageOptional to explicitly achieve the same result. You can also specify the level of trust needed in a signing key using the TrustedOnly (default) and TrustAll options. The former will only accept a key if it is fully trusted by your PGP keyring, while the latter only requires the key to be present in the keyring (much like using gpgv ).

As I wrote earlier, there is very little change from a users perspective once configured. About the only thing that is really noticeable is that pacman will attempt to download a signature for each database it downloads when the database SigLevel is set to Required or Optional . For example:

$ pacman -Syu

:: Synchronizing package databases...

allanbrokeit 1464.0B 540.5K/s 00:00:00 [######################] 100%

allanbrokeit.sig 287.0B 7.0M/s 00:00:00 [######################] 100%

...