Hi all!
Another blog post is up. Copy follows for discussion. https://neuromancer.sk/article/8
PGP handling progress
This week things moved along with the mailman-pgp plugin. As I finally had a good PGP library to work with as well as some basic plugin API patches outstanding to Mailman Core.
So with that I implemented large parts of the mailman_pgp.pgp
package,
including tests, as well as a basic signature checking rule. Also, as
the package now contains tests, I added a gitlab CI config and started
running it.
repo @ neuromancer.sk repo @ gitlab
Wrappers
Created two classes, which wrap an email.message.Message
instance (or
mailman.email.message.Message
) and expose a common public PGP handling
API on said instance. One understands PGP/MIME (as per RFC1847 and
RFC3156) and the other somewhat understands inline PGP. They both give
methods to check presence of a PGP signed/encrypted message or PGP keys,
to verify signatures of a message, to decrypt it or collect the attached
keys. There are currently almost complete tests for handling signatures
and partial for encryption.
MIMEWrapper
This one was rather easy to implement, as RFC3156 and RFC1847 are both very precise but also rather simple standards (well compared that to 90+ page RFC4880 [OpenPGP]).
InlineWrapper
As there is really no "Inline PGP standard" this wrapper improvises with how it looks for signatures/messages/keys. In it's current form it only accepts a non-multipart message and looks for ASCII-armored blobs in it.
Signature rule
The concrete way of integrating the PGP plugin into Mailman Core has changed over time. The original version of my proposal planned on working in the Mailman Core tree and as that changed to a plugin, new requirements of integration popped up, us stuff couldn't just be changed for this one plugin to work.
Because of the nature of encryption the PGP plugin needs to get it's
hands on the messages before the rest of Mailmans rules. This could be
done with a rule in a custom chain, however as I understand rules, they
are, well, rules, they shouldn't change the message they are processing
in any way. In my understanding of this architecture, if Mailman was
written in a language with a const
identifier, the message would have
it in the chain links process
method. It would work as a rule, just
wouldn't feel nice and fit in with the architecture.
That's why I first wanted to implement all handling of incoming messages
in a custom incoming runner. This runners class is then set as the
runner for the in
queue and the default runner is moved to another
queue, perhaps in_default
. The custom incoming runner does it's thing
before passing messages back to the default incoming runners queue.
However only encryption has this issue of needing to change the message,
as rules and the rest need it in cleartext. So I decided to split off
signature handling to a custom rule, and only handle encryption in the
incoming runner.
I would like to get rid of the not-so-nice redirection of the default incoming runner altogether but I see no other way to decrypt the incoming message to a PGP enabled list before other rules get it.
The signature rule processes messages using the wrappers described above according to a per-list signature handling configuration:
Option | Default -------------------- | ------- unsigned_msg_action | bounce inline_pgp_action | None (pass-through) expired_sig_action | bounce revoked_sig_action | bounce malformed_sig_action | bounce duplicate_sig_action | bounce strip_original_sig | False sign_outgoing | False
I think the options are quite self-explanatory. They are checked in
order and taken if the message matches the option and the set action is
not None
. So with the default configuration of the PGP enabled mailing
list, an unsigned message will be bounced, inline PGP is allowed,
signatures by expired keys are bounced (expired at time of checking),
signatures by revoked keys are bounced, signatures that don't verify are
bounced (maybe a better name for them than malformed?) and finally
signatures that the Mailman PGP plugin already processed are bounced as
well. This is to prevent replay attacks and is something I think people
would expect Mailman to do, although I am not sure if the plugin should
do it.
This signature rule is almost complete, with some edge-cases remaining and the checking of duplicate signatures also remaining.
Cheers,
Jan
/\ # PGP: 362056ADA8F2F4E421565EF87F4A448FE68F329D /__\ # https://neuromancer.sk /\ /\ # Eastern Seaboard Phishing Authority /__\/__\ #