diff options
| author | J08nY | 2017-08-18 17:30:11 +0200 |
|---|---|---|
| committer | J08nY | 2017-08-18 17:30:11 +0200 |
| commit | 54ad58f448f23cd26bbfad6abcfe5e4ca9b686ee (patch) | |
| tree | 192613f595dcca4f28b2c7e53a427b8a0a63b758 | |
| parent | 680ae1be88d22f2eb5d6f16a58acda4e5927ed72 (diff) | |
| download | mailman-pgp-54ad58f448f23cd26bbfad6abcfe5e4ca9b686ee.tar.gz mailman-pgp-54ad58f448f23cd26bbfad6abcfe5e4ca9b686ee.tar.zst mailman-pgp-54ad58f448f23cd26bbfad6abcfe5e4ca9b686ee.zip | |
| -rw-r--r-- | src/mailman_pgp/rest/lists.py | 22 | ||||
| -rw-r--r-- | src/mailman_pgp/rest/tests/test_lists.py | 24 | ||||
| -rw-r--r-- | src/mailman_pgp/utils/pgp.py | 11 |
3 files changed, 53 insertions, 4 deletions
diff --git a/src/mailman_pgp/rest/lists.py b/src/mailman_pgp/rest/lists.py index 708635f..9cd7a4b 100644 --- a/src/mailman_pgp/rest/lists.py +++ b/src/mailman_pgp/rest/lists.py @@ -33,7 +33,7 @@ from zope.component import getUtility from mailman_pgp.config import config from mailman_pgp.database import transaction from mailman_pgp.model.list import PGPMailingList -from mailman_pgp.utils.pgp import key_from_blob +from mailman_pgp.utils.pgp import key_from_blob, key_merge from mailman_pgp.utils.rest import enumflag_validator, workflow_validator from mailman_pgp.workflows.key_change import (KeyChangeModWorkflow, KeyChangeWorkflow) @@ -213,3 +213,23 @@ class AListPubkey: resource = dict(public_key=str(pubkey), key_fingerprint=str(pubkey.fingerprint)) okay(response, etag(resource)) + + def on_put(self, request, response): + """/lists/<list_id>/pubkey""" + # merge pubkey with the current one. Assume all new sigs are valid. + try: + validator = Validator(public_key=GetterSetter(key_from_blob)) + values = validator(request) + except (ValueError, PGPError) as error: + bad_request(response, str(error)) + return + + key = values.pop('public_key') + try: + key_merge(self._mlist.key, key) + self._mlist.fs_key.save() + except ValueError as e: + bad_request(response, str(e)) + return + + accepted(response) diff --git a/src/mailman_pgp/rest/tests/test_lists.py b/src/mailman_pgp/rest/tests/test_lists.py index cae3138..c97c392 100644 --- a/src/mailman_pgp/rest/tests/test_lists.py +++ b/src/mailman_pgp/rest/tests/test_lists.py @@ -16,6 +16,7 @@ # this program. If not, see <http://www.gnu.org/licenses/>. """""" +from copy import copy from unittest import TestCase from urllib.error import HTTPError @@ -311,3 +312,26 @@ class TestListKey(TestCase): call_api('http://localhost:9001/3.1/plugins/pgp/lists/' 'test.example.com/pubkey') self.assertEqual(cm.exception.code, 404) + + def test_set_list_pubkey(self): + signer_key = load_key('rsa_1024.priv.asc') + signed = copy(self.list_key.pubkey) + uid = next(iter(signed.userids)) + sig = signer_key.certify(uid) + uid |= sig + + json, response = call_api( + 'http://localhost:9001/3.1/plugins/pgp/lists/' + 'test.example.com/pubkey', + data=dict(public_key=str(signed)), + method='PUT') + + self.assertEqual(response.status_code, 202) + + json, response = call_api( + 'http://localhost:9001/3.1/plugins/pgp/lists/' + 'test.example.com/pubkey') + + key, _ = PGPKey.from_blob(json['public_key']) + uid = next(iter(key.userids)) + self.assertIn(sig, list(uid.signatures)) diff --git a/src/mailman_pgp/utils/pgp.py b/src/mailman_pgp/utils/pgp.py index 05721b4..eec7b67 100644 --- a/src/mailman_pgp/utils/pgp.py +++ b/src/mailman_pgp/utils/pgp.py @@ -182,13 +182,15 @@ def key_usable(key, flags_required): @public -def key_merge(privkey, new_key, signer_key): +def key_merge(privkey, new_key, signer_key=None): """ :param privkey: :type privkey: pgpy.PGPKey :param new_key: :type new_key: pgpy.PGPKey + :param signer_key: + :type signer_key: pgpy.PGPKey """ if privkey.pubkey.key_material != new_key.key_material: raise ValueError('You sent a wrong key.') @@ -207,10 +209,13 @@ def key_merge(privkey, new_key, signer_key): for sig in uid_other.signatures: if sig in uid.signatures: continue + if signer_key is None: + uid_sigs.setdefault(uid, []).append(sig) + continue if sig.signer != signer_key.fingerprint.keyid: continue - # sig is a new signature, not currenctly on uid, ans seems to - # be made by the pgp_address.key + # sig is a new signature, not currently on uid, and seems to + # be made by the signer_key try: verification = signer_key.verify(uid, sig) if bool(verification): |
