Ziirish's Home :: Blog

Ziirish's Pub

 
 

Cela fait quelques années que j'utilise mutt en tant que client mail. Et depuis tout ce temps, je n'ai pas à m'en plaindre.

C'est un petit client en mode texte, léger, rapide, simple et efficace. Ça me permet également de rédiger mes mails avec vim , l'un des éditeurs de textes les plus puissants que j'ai rencontré. Et surtout, mutt gère le chiffrement et la signature des messages via S/MIME et GnuPG.

Seulement, un bug a traîné quelques années, et sa résolution il y a peu ne me satisfaisait guère.

Le but

Étant abonné à quelques listes de diffusions, il m'arrive régulièrement de recevoir des messages signés via PGP, mais impossible de vérifier automatiquement ces signatures.

Le bug dont je vous ai parlé plus haut était censé régler ce problème, mais visiblement, la solution de facilité a été choisie, puisque le correctif a consisté à supprimer de la documentation cette fonctionnalité.

Solution

Forcément, je n'allais pas en rester là !

On commence par jeter un coup d'oeil rapide à ma configuration.

~/.muttrc

# [bla bla bla]

## GnuPG

source ~/.mutt/gpg.rc

~/.mutt/gpg.rc

# Note that we explicitly set the comment armor header since GnuPG, when used
# in some localiaztion environments, generates 8bit data in that header, thereby
# breaking PGP/MIME.

# decode application/pgp
set pgp_decode_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"

# verify a pgp/mime signature
#set pgp_verify_command="gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify %s %f"
set pgp_verify_command="~/.mutt/gpggetkey %s %f"

# decrypt a pgp/mime attachment
set pgp_decrypt_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"

# create a pgp/mime signed attachment
# set pgp_sign_command="gpg-2comp --comment '' --no-verbose --batch --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f"
set pgp_sign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f"

# create a application/pgp signed (old-style) message
# set pgp_clearsign_command="gpg-2comp --comment '' --no-verbose --batch --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f"
set pgp_clearsign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f"

# create a pgp/mime encrypted attachment
# set pgp_encrypt_only_command="pgpewrap gpg-2comp -v --batch --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"
set pgp_encrypt_only_command="/usr/lib/mutt/pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"

# create a pgp/mime encrypted and signed attachment
# set pgp_encrypt_sign_command="pgpewrap gpg-2comp %?p?--passphrase-fd 0? -v --batch --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"
set pgp_encrypt_sign_command="/usr/lib/mutt/pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"

# import a key into the public key ring
set pgp_import_command="gpg --no-verbose --import %f"

# export a key from the public key ring
set pgp_export_command="gpg --no-verbose --export --armor %r"

# verify a key
set pgp_verify_key_command="gpg --verbose --batch --fingerprint --check-sigs %r"

# read in the public key ring
set pgp_list_pubring_command="gpg --no-verbose --batch --quiet --with-colons --list-keys %r" 

# read in the secret key ring
set pgp_list_secring_command="gpg --no-verbose --batch --quiet --with-colons --list-secret-keys %r" 

# fetch keys
# set pgp_getkeys_command="pkspxycwrap %r"
# This will work when #172960 will be fixed upstream
# set pgp_getkeys_command="gpg --no-verbose --keyserver pgp.mit.edu --recv-keys %r"

# pattern for good signature - may need to be adapted to locale!

# set pgp_good_sign="^gpgv?: Good signature from "

# OK, here's a version which uses gnupg's message catalog:
# set pgp_good_sign="`gettext -d gnupg -s 'Good signature from "' | tr -d '"'`"

# This version uses --status-fd messages
set pgp_good_sign="^\\[GNUPG:\\] GOODSIG"

L'astuce se trouve sur la commande pgp_verify_command, ici j'utilise un handler ~/.mutt/gpggetkey présenté ci-dessous.

#!/bin/bash

out=$(mktemp)
err=$(mktemp)

gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify $@ 2>$err 1>$out

if grep "NO_PUBKEY" $err &>/dev/null; then
    key=$(grep --color=none "RSA key ID" $err | perl -pe 's/^.+RSA key ID (.+)$/$1/')

    gpg --no-verbose --keyserver pgp.mit.edu --recv-keys $key &>/dev/null

    gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify $@
else
    cat $out
    cat $err
fi

rm $out $err &>/dev/null

Voilà, c'est tout !