diff options
| -rw-r--r-- | src/mailman_pgp/model/list.py | 32 | ||||
| -rw-r--r-- | src/mailman_pgp/pgp/keygen.py | 57 |
2 files changed, 40 insertions, 49 deletions
diff --git a/src/mailman_pgp/model/list.py b/src/mailman_pgp/model/list.py index e53d61b..764dc1b 100644 --- a/src/mailman_pgp/model/list.py +++ b/src/mailman_pgp/model/list.py @@ -1,16 +1,17 @@ """""" -from multiprocessing import SimpleQueue from os.path import exists, isfile, join -from mailman.config import config as mailman_config, config +from mailman.config import config as mailman_config from mailman.database.types import Enum, SAUnicode from mailman.interfaces.action import Action from mailman.model.mailinglist import MailingList from pgpy import PGPKey from public import public from sqlalchemy import Boolean, Column, Integer +from sqlalchemy.orm import reconstructor +from mailman_pgp.config import config from mailman_pgp.model.base import Base from mailman_pgp.pgp.keygen import ListKeyGenerator @@ -29,19 +30,21 @@ class EncryptedMailingList(Base): def __init__(self, mlist): super().__init__() self.list_id = mlist.list_id + self._init() self._mlist = mlist + self._generate(mlist) + + @reconstructor + def _init(self): + self._mlist = None self._key = None - self._key_queue = None self._key_generator = None - self._generate(mlist) def _generate(self, mlist): - self._key_queue = SimpleQueue() self._key_generator = ListKeyGenerator(config.pgp.keypair_config, mlist.display_name, mlist.posting_address, mlist.request_address, - self._key_queue, self.key_path) self._key_generator.start() @@ -49,23 +52,19 @@ class EncryptedMailingList(Base): def mlist(self): if self._mlist is not None: return self._mlist - return mailman_config.db.query(MailingList).filter_by( + return mailman_config.db.store.query(MailingList).filter_by( _list_id=self.list_id).first() @property def key(self): if self._key is None: - # First try the queue - if self._key_queue is not None and not self._key_queue.empty(): - self._key = self._key_queue.get() - # Then check the file - elif exists(self.key_path) and isfile(self.key_path): + # Check the file + if exists(self.key_path) and isfile(self.key_path): self._key = PGPKey.from_file(self.key_path) else: # Check if key generator is running or what? Restart it if not. - # If we race it shutting down and saving the key file + queue - # it will simply check the key_file exists and put it into a - # queue for us. + # If we race it shutting down and saving the key file + # it will simply check the key_file exists and exit. if self._key_generator is None or \ not self._key_generator.is_alive(): self._generate(self.mlist) @@ -74,5 +73,4 @@ class EncryptedMailingList(Base): @property def key_path(self): return join(config.pgp.keydir_config['list_keydir'], - self.list_id, - '.asc') + self.list_id + '.asc') diff --git a/src/mailman_pgp/pgp/keygen.py b/src/mailman_pgp/pgp/keygen.py index e1fa6b0..5df56d4 100644 --- a/src/mailman_pgp/pgp/keygen.py +++ b/src/mailman_pgp/pgp/keygen.py @@ -14,46 +14,46 @@ class ListKeyGenerator(mp.Process): """""" def __init__(self, keypair_config, display_name, posting_address, - request_address, queue, key_path): + request_address, key_path): super().__init__( target=self.generate, args=( keypair_config, display_name, posting_address, request_address, - queue, key_path), + key_path), daemon=True) def generate(self, keypair_config, display_name, posting_address, - request_address, queue, key_path): + request_address, key_path): """ - + Generates the list keypair and saves it to key_path, if it does not + exist. :param keypair_config: :param display_name: :param posting_address: :param request_address: - :param queue: :param key_path: - :return: """ - if exists(key_path) and isfile(key_path): - queue.put(PGPKey.from_file(key_path)) - return - key = self._create(keypair_config, display_name, posting_address, - request_address) - self._save(key, queue, key_path) + with Lock(key_path + '.lock'): + if exists(key_path) and isfile(key_path): + return + key = self._create(keypair_config, display_name, posting_address, + request_address) + self._save(key, key_path) def _create(self, config, display_name, posting_address, request_address): """ - + Generates the list `PGPKey` keypair, with posting and request UIDs. + Uses a Sign+Certify main key and Encrypt subkey. :param config: :param display_name: :param posting_address: :param request_address: - :return: + :return: `PGPKey` """ # Generate the Sign + Certify primary key. key_type = config['key_type'] - key_size = config['key_size'] - key = PGPKey.new(key_type, key_size) + key_length = config['key_length'] + key = PGPKey.new(key_type, key_length) key_params = dict(usage={KeyFlags.Sign, KeyFlags.Certify}, hashes=[HashAlgorithm.SHA256, HashAlgorithm.SHA384, @@ -67,36 +67,29 @@ class ListKeyGenerator(mp.Process): CompressionAlgorithm.ZIP, CompressionAlgorithm.Uncompressed], primary=True) - + # Generate the posting + request uids. main_uid = PGPUID.new(display_name, email=posting_address) request_uid = PGPUID.new(display_name, email=request_address) - + # Generate the Encrypt subkey. subkey_type = config['subkey_type'] - subkey_size = config['subkey_size'] - subkey = PGPKey.new(subkey_type, subkey_size) - + subkey_length = config['subkey_length'] + subkey = PGPKey.new(subkey_type, subkey_length) subkey_params = dict( usage={KeyFlags.EncryptCommunications, KeyFlags.EncryptStorage}, primary=False ) - + # Put it all together. key.add_uid(main_uid, **key_params) key.add_uid(request_uid, **key_params) key.add_subkey(subkey, **subkey_params) return key - def _save(self, key, queue, key_path): + def _save(self, key, key_path): """ - + Save the generated key. :param key: - :param queue: :param key_path: - :return: """ - queue.put(key) - - lock = Lock(key_path) - with lock: - with open(key_path, 'w') as key_file: - key_file.write(str(key)) + with open(key_path, 'w') as key_file: + key_file.write(str(key)) |
