aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman_pgp/commands/tests/test_key.py20
-rw-r--r--src/mailman_pgp/model/address.py4
-rw-r--r--src/mailman_pgp/model/sighash.py42
-rw-r--r--src/mailman_pgp/rules/signature.py26
-rw-r--r--src/mailman_pgp/rules/tests/test_signature.py15
5 files changed, 84 insertions, 23 deletions
diff --git a/src/mailman_pgp/commands/tests/test_key.py b/src/mailman_pgp/commands/tests/test_key.py
index a9343b3..83bf49e 100644
--- a/src/mailman_pgp/commands/tests/test_key.py
+++ b/src/mailman_pgp/commands/tests/test_key.py
@@ -37,8 +37,8 @@ from mailman_pgp.pgp.mime import MIMEWrapper
from mailman_pgp.pgp.tests.base import load_key
from mailman_pgp.pgp.wrapper import PGPWrapper
from mailman_pgp.testing.layers import PGPConfigLayer
-from mailman_pgp.workflows.pubkey import CONFIRM_REQUEST
from mailman_pgp.workflows.key_change import CHANGE_CONFIRM_REQUEST
+from mailman_pgp.workflows.pubkey import CONFIRM_REQUEST
from mailman_pgp.workflows.subscription import OpenSubscriptionPolicy
@@ -143,7 +143,8 @@ class TestPreSubscription(unittest.TestCase):
self.assertFalse(pgp_address.key_confirmed)
items = get_queue_messages('virgin', expected_count=2)
- if items[0].msg['Subject'] == 'The results of your email commands':
+ if items[0].msg[
+ 'Subject'] == 'The results of your email commands': # pragma: no cover
results = items[0].msg
confirm_request = items[1].msg
else:
@@ -186,7 +187,8 @@ class TestPreSubscription(unittest.TestCase):
self.assertFalse(pgp_address.key_confirmed)
items = get_queue_messages('virgin', expected_count=2)
- if items[0].msg['Subject'] == 'The results of your email commands':
+ if items[0].msg[
+ 'Subject'] == 'The results of your email commands': # pragma: no cover
results = items[0].msg
confirm_request = items[1].msg
else:
@@ -574,7 +576,8 @@ class TestAfterSubscription(unittest.TestCase):
make_testable_runner(CommandRunner, 'command').run()
items = get_queue_messages('virgin', expected_count=2)
- if items[0].msg['Subject'] == 'The results of your email commands':
+ if items[0].msg[
+ 'Subject'] == 'The results of your email commands': # pragma: no cover
results = items[0].msg
confirm_request = items[1].msg
else:
@@ -610,7 +613,8 @@ class TestAfterSubscription(unittest.TestCase):
make_testable_runner(CommandRunner, 'command').run()
items = get_queue_messages('virgin', expected_count=2)
- if items[0].msg['Subject'] == 'The results of your email commands':
+ if items[0].msg[
+ 'Subject'] == 'The results of your email commands': # pragma: no cover
results = items[0].msg
confirm_request = items[1].msg
else:
@@ -644,7 +648,8 @@ class TestAfterSubscription(unittest.TestCase):
make_testable_runner(CommandRunner, 'command').run()
items = get_queue_messages('virgin', expected_count=2)
- if items[0].msg['Subject'] == 'The results of your email commands':
+ if items[0].msg[
+ 'Subject'] == 'The results of your email commands': # pragma: no cover
confirm_request = items[1].msg
else:
confirm_request = items[0].msg
@@ -760,7 +765,8 @@ class TestGeneral(unittest.TestCase):
listid='test.example.com')
make_testable_runner(CommandRunner, 'command').run()
items = get_queue_messages('virgin', expected_count=2)
- if items[0].msg['Subject'] == 'The results of your email commands':
+ if items[0].msg[
+ 'Subject'] == 'The results of your email commands': # pragma: no cover
pubkey_message = items[1].msg
else:
pubkey_message = items[0].msg
diff --git a/src/mailman_pgp/model/address.py b/src/mailman_pgp/model/address.py
index 25a87dc..9444f5a 100644
--- a/src/mailman_pgp/model/address.py
+++ b/src/mailman_pgp/model/address.py
@@ -22,7 +22,7 @@ from os.path import exists, isfile, join
from mailman.database.types import SAUnicode
from mailman.interfaces.usermanager import IUserManager
from pgpy import PGPKey
-from sqlalchemy import Boolean, Column, Integer
+from sqlalchemy import Boolean, Column, Integer, String
from sqlalchemy.orm import reconstructor
from zope.component import getUtility
@@ -37,7 +37,7 @@ class PGPAddress(Base):
id = Column(Integer, primary_key=True)
email = Column(SAUnicode, index=True, unique=True)
- key_fingerprint = Column(SAUnicode)
+ key_fingerprint = Column(String(50))
key_confirmed = Column(Boolean, default=False)
def __init__(self, address):
diff --git a/src/mailman_pgp/model/sighash.py b/src/mailman_pgp/model/sighash.py
new file mode 100644
index 0000000..0c61e38
--- /dev/null
+++ b/src/mailman_pgp/model/sighash.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2017 Jan Jancar
+#
+# This file is a part of the Mailman PGP plugin.
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program. If not, see <http://www.gnu.org/licenses/>.
+
+""""""
+from sqlalchemy import LargeBinary, Column, String, DateTime
+
+from mailman_pgp.model.base import Base
+
+
+class PGPSigHash(Base):
+ """"""
+
+ __tablename__ = "sighash"
+
+ hash = Column(LargeBinary, primary_key=True)
+ fingerprint = Column(String(50), index=True)
+ time = Column(DateTime)
+
+ @staticmethod
+ def find(hash=None, fingerprint=None):
+ kws = {}
+ if hash is not None:
+ kws['hash'] = hash
+ if fingerprint is not None:
+ kws['fingerprint'] = fingerprint
+ if len(kws) == 0:
+ return None
+ return PGPSigHash.query().filter_by(**kws).all()
diff --git a/src/mailman_pgp/rules/signature.py b/src/mailman_pgp/rules/signature.py
index c40de32..c8ef62d 100644
--- a/src/mailman_pgp/rules/signature.py
+++ b/src/mailman_pgp/rules/signature.py
@@ -17,6 +17,7 @@
"""Signature checking rule for the pgp-posting-chain."""
import logging
+from email.utils import parseaddr
from mailman.core.i18n import _
from mailman.interfaces.action import Action
@@ -29,6 +30,7 @@ from zope.interface import implementer
from mailman_pgp.database import query
from mailman_pgp.model.address import PGPAddress
from mailman_pgp.model.list import PGPMailingList
+from mailman_pgp.model.sighash import PGPSigHash
from mailman_pgp.pgp.wrapper import PGPWrapper
log = logging.getLogger('mailman.plugin.pgp')
@@ -57,7 +59,13 @@ class Signature:
# Find the `PGPMailingList` this is for.
pgp_list = PGPMailingList.for_list(mlist)
if pgp_list is None:
- raise ValueError('PGP enabled mailing list not found.')
+ return False
+
+ # Find sender
+ display_name, email = parseaddr(msg['from'])
+ # Address could be None or the empty string.
+ if not email:
+ email = msg.sender
# Wrap the message to work with it.
wrapped = PGPWrapper(msg)
@@ -66,7 +74,7 @@ class Signature:
if not wrapped.is_signed():
action = pgp_list.unsigned_msg_action
if action != Action.defer:
- record_action(msg, msgdata, action, msg.sender,
+ record_action(msg, msgdata, action, email,
'The message is unsigned.')
return True
@@ -74,28 +82,30 @@ class Signature:
if wrapped.inline.is_signed():
action = pgp_list.inline_pgp_action
if action != Action.defer:
- record_action(msg, msgdata, action, msg.sender,
+ record_action(msg, msgdata, action, email,
'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)
+ address = user_manager.get_address(email)
pgp_address = PGPAddress.for_address(address)
if pgp_address is None:
- raise ValueError('PGP enabled address not found.')
+ # Just let it continue.
+ return False
# See if we have a key.
key = pgp_address.key
if key is None:
- raise ValueError('No key?')
+ record_action(msg, msgdata, Action.reject, email,
+ 'No key set for address {}.'.format(email))
+ return True
# Take the `invalid_sig_action` if the verification failed.
if not wrapped.verifies(key):
action = pgp_list.invalid_sig_action
if action != Action.defer:
- record_action(msg, msgdata, action, msg.sender,
+ record_action(msg, msgdata, action, email,
'Signature did not verify.')
return True
diff --git a/src/mailman_pgp/rules/tests/test_signature.py b/src/mailman_pgp/rules/tests/test_signature.py
index 56baf08..f5c5dc3 100644
--- a/src/mailman_pgp/rules/tests/test_signature.py
+++ b/src/mailman_pgp/rules/tests/test_signature.py
@@ -75,8 +75,8 @@ To: ordinary@example.com
""")
- with self.assertRaises(ValueError):
- self.rule.check(ordinary_list, msg, {})
+ matches = self.rule.check(ordinary_list, msg, {})
+ self.assertFalse(matches)
def test_no_address(self):
with transaction():
@@ -86,16 +86,19 @@ From: anne@example.com
To: test@example.com
""")
- with self.assertRaises(ValueError):
- self.rule.check(self.mlist, msg, {})
+ matches = self.rule.check(self.mlist, msg, {})
+ self.assertFalse(matches)
def test_no_key(self):
with transaction():
self.pgp_sender.key = None
msgdata = {}
- with self.assertRaises(ValueError):
- self.rule.check(self.mlist, self.msg_mime_signed, msgdata)
+ matches = self.rule.check(self.mlist, self.msg_mime_signed, msgdata)
+ self.assertTrue(matches)
+ self.assertAction(msgdata, Action.reject, [
+ 'No key set for address {}.'.format(
+ self.pgp_sender.address.original_email)])
def assertAction(self, msgdata, action, reasons):
self.assertEqual(msgdata['moderation_action'], action.name)