Control: tag -1 moreinfo Hi Nik,
mutt is capable of tagging messages matching a given pattern, and of
applying an action on all tagged messages, hence your second motivating
point is untrue IMHO.
That said, I believe your tool can be of interest, and possibly to mutt
users as well. I've got a wishlist, though:
* It would be great to be able to use a pre-authenticated tunnel to the
IMAP server. In my setup for instance, I use ‘/usr/lib/dovecot/imap’
as a tunnel and rely on unix permissions for authentication; the IMAP
server is not directly exposed to the network.
* It might be preferable to dump the certification signature (and
import them all at once using … | gpg --import), since the user can
then use the --import-options of her choice.
* I think the default selector, on the Subject: header, is too
restrictive and not flexible enough. Alternatives to caff such as
PIUS or monkeysign may have other subjects, and it would be great to
select messages that were manually crafted as well. However calls to
GnuPG are expensive, so ideally certification signatures should be
detected without false positive. It's probably hard to come up with
a list of all MIME Content-Type used to send signatures by email, but
after a quick look my own inbox here is what I found already:
1/ Encrypted message (multipart/encrypted) with attachment
(application/pgp-keys or text/plain).
2/ Clear or armored message (multipart/mixed) with encrypted,
non-armored, attachment (application/octet-stream).
3/ Clear or armored message (multipart/mixed) with encrypted,
armored, attachment (application/pgp-encrypted).
4/ Clear message (text/plain) with armored signature in the body
(text/plain).
5/ Signed message (multipart/signed) with armored signature in the
body (text/plain).
(This list is non exhaustive obviously, so please complete/correct
it.) I therefore propose the following algorithm to detect emails
containing certification signatures:
* If the message is not multipart, or if the MIME Content-Type is
text/plain or application/pgp-keys:
- If the first non-blank line matches /^-+BEGIN PGP PUBLIC KEY
BLOCK-+$/,
import the data and stop.
(Corresponds to an armored public key.)
* If the MIME Content-Type is application/octet-stream or
application/pgp-keys:
- Read the first 8 bytes; if it matches the beginning of an
OpenPGP header (see RFC 4880 sections 4.2 and 5.5), import
the data and stop.
(Corresponds to a non-armored public key.)
* If the message is not multipart, or if the MIME Content-Type is
text/plain or application/pgp-encrypted:
- If the first non-blank line matches /^-+BEGIN PGP MESSAGE-+$/,
try to decrypt, and upon success loop with the decrypted
content.
(Corresponds to armored encrypted message.)
* If the MIME Content-Type is application/octet-stream or
application/pgp-encrypted:
- Read the first byte; if it matches the beginning of an
OpenPGP header (see RFC 4880 sections 4.2, 5.1 and 5.3 ), try
to decrypt, and upon success loop with the decrypted content.
(Corresponds to non-armored encrypted message.)
* If the MIME Content-Type is multipart/signed, loop on each part
for which the Content-Type is not application/pgp-signature.
(Corresponds to a PGP/MIME signed message.)
* If the MIME Content-Type is multipart/mixed, loop on each part.
(Corresponds to a clear message.)
* If the MIME Content-Type is multipart/encrypted, try to decrypt
the message, and upon success loop on each part.
(Corresponds to a PGP/MIME (sign)encrypted message.)
* Otherwise, drop the message or MIME part and stop.
That's just a sketch, but I believe it does cover all the
situations described above. (And that's *more* than what mutt's ^K
binding is able to detect ;-) It's unclear how that would scale in
practice though, so it might be good to keep selectors based on
headers. (Or perhaps something more flexible, based on the IMAP SEARCH
command as defined in RFC 3501 section 6.4.4? :-)
Regarding the parsing of OpenPGP packets headers in non-armored byte
streams, let x be the first byte. It MUST match the mask 0x80 (i.e., the
most significant bit must be set).
* For public keys, if $x also matches the mask 0x40, then $x MUST be
0xc6. Otherwise, $x & 0xfc MUST be 0x98. If selecting based on the
first byte only leads to too many false positive, one might need to
parse the full header and read the first byte of the packet, which
MUST be 0x03 or 0x04. (see gpg --export $keyID | hexdump -n8 -ve
'8/1 "%02X""\n"'.)
* For asymmetrically encrypted data, if $x also matches the mask 0x40,
then $x MUST be 0xc1. Otherwise, $x & 0xfc MUST be 0x84. If
selecting based on the first byte only leads to too many false
positive, one might need to parse the full header and read the first
byte of the packet, which MUST be 0x03.
* For symmetrically encrypted data, if $x also matches the mask 0x40,
then $x MUST be 0xc3. Otherwise, $x & 0xfc MUST be 0x8c. If
selecting based on the first byte only leads to too many false
positive, one might need to parse the full header and read the first
byte of the packet, which MUST be 0x04.
I'd be happy to give a hand, but I'm afraid Python hacking isn't my
strong side :-P
Cheers,
--
Guilhem.
signature.asc
Description: Digital signature

