aboutsummaryrefslogtreecommitdiff
path: root/src/mailman_pgp/rules
diff options
context:
space:
mode:
authorJ08nY2017-06-22 17:25:44 +0200
committerJ08nY2017-06-22 17:25:44 +0200
commit429234b8db28ed6aadf21a3ccfce7eaf7065be71 (patch)
tree719f9abc1b9804d062676458bf3ca51463b3f1bc /src/mailman_pgp/rules
parent54aa6d86be743b6a0f640cd68b25938d02e3dfd7 (diff)
downloadmailman-pgp-429234b8db28ed6aadf21a3ccfce7eaf7065be71.tar.gz
mailman-pgp-429234b8db28ed6aadf21a3ccfce7eaf7065be71.tar.zst
mailman-pgp-429234b8db28ed6aadf21a3ccfce7eaf7065be71.zip
Diffstat (limited to 'src/mailman_pgp/rules')
-rw-r--r--src/mailman_pgp/rules/signature.py75
1 files changed, 60 insertions, 15 deletions
diff --git a/src/mailman_pgp/rules/signature.py b/src/mailman_pgp/rules/signature.py
index 5a89ab1..0ffd76b 100644
--- a/src/mailman_pgp/rules/signature.py
+++ b/src/mailman_pgp/rules/signature.py
@@ -30,45 +30,90 @@ from mailman_pgp.model.list import PGPMailingList
from mailman_pgp.pgp.wrapper import PGPWrapper
+def _record_action(msgdata, action, sender, reason):
+ msgdata['moderation_action'] = action
+ msgdata['moderation_sender'] = sender
+ msgdata.setdefault('moderation_reasons', []).append(reason)
+
+
@public
@implementer(IRule)
class Signature:
- """"""
+ """The signature checking rule."""
name = 'signature'
-
description = _(
- """
- """)
-
+ """A rule which enforces PGP enabled list signature configuration.""")
record = True
- def _record_action(self, msgdata, action, sender, reason):
- msgdata['moderation_action'] = action
- msgdata['moderation_sender'] = sender
- msgdata.setdefault('moderation_reasons', []).append(reason)
-
def check(self, mlist, msg, msgdata):
"""See `IRule`."""
+ # Find the `PGPMailingList` this is for.
enc_list = query(PGPMailingList).filter_by(
list_id=mlist.list_id).first()
if enc_list is None:
raise ValueError('PGP enabled mailing list not found.')
+ # Wrap the message to work with it.
wrapped = PGPWrapper(msg)
+ # Take unsigned_msg_action if unsigned.
if not wrapped.is_signed():
action = enc_list.unsigned_msg_action
if action is not None:
- self._record_action(msgdata, action, msg.sender,
- 'The message is unsigned.')
+ _record_action(msgdata, action, msg.sender,
+ 'The message is unsigned.')
return True
+ # Take `inline_pgp_action` if inline signed.
if wrapped.is_inline_signed():
action = enc_list.inline_pgp_action
if action is not None:
- self._record_action(msgdata, action, msg.sender,
- 'Inline PGP is not allowed.')
+ _record_action(msgdata, action, msg.sender,
+ 'Inline PGP is not allowed.')
+ return True
+
+ # Lookup the address by sender, and its corresponding `PGPAddress`.
+ user_manager = getUtility(IUserManager)
+ sender = msg.sender
+ address = user_manager.get_address(sender)
+ enc_address = PGPAddress.query().filter_by(
+ email=address.email).first()
+ if enc_address is None:
+ raise ValueError('PGP enabled address not found.')
+
+ # See if we have a key.
+ key = enc_address.key
+ if key is None:
+ # TODO: how to handle this?
+ raise ValueError('No key?')
+
+ # Verify, this gives us stuff we need to check.
+ verification = wrapped.verify(key)
+
+ # Take the `invalid_sig_action` if the verification failed.
+ if not verification:
+ action = enc_list.invalid_sig_action
+ if action is not None:
+ _record_action(msgdata, action, msg.sender,
+ 'Signature did not verify.')
+ return True
+
+ # TODO: handle more signatures here?
+ sig_obj = next(verification.good_signatures)
+ sig_key = sig_obj.by
+ sig_sig = sig_obj.signature
+
+ # Take the `expired_sig_action` if either he signature or the key
+ # is expired.
+ if sig_sig.is_expired or sig_key.is_expired:
+ action = enc_list.expired_sig_action
+ if action is not None:
+ _record_action(msgdata, action, msg.sender,
+ 'Signature or key expired.')
return True
- # TODO finish this \ No newline at end of file
+ # XXX: we need to track key revocation separately to use it here
+ # TODO: check key revocation here
+
+ return False