Add cache validity configuration parameter

Also, log basic information in KeyCache and provide load() and reload()
operations to make daemon's code cleaner.
This commit is contained in:
Piotr F. Mieszkowski 2022-10-05 22:11:26 +02:00
parent f52177bcb0
commit 75a03de24b
4 changed files with 39 additions and 9 deletions

View File

@ -51,6 +51,14 @@ dec_regex = None
# i.e. have mode 700.
keyhome = /var/gpgmailgate/.gnupg
# Number of minutes between key cache refreshes.
#
# Lacre daemon keeps a cache of known keys to reduce number of OS processes
# needed to perform a single email. Keyring is going to be modified during
# daemon's lifetime, so with this simple mechanism we ensure that new keys
# will eventually be recognised and loaded.
cache_refresh_minutes = 5
[smime]
# the directory for the S/MIME certificate files
cert_path = /var/gpgmailgate/smime

View File

@ -75,8 +75,8 @@ async def _sleep():
def _main():
_validate_config()
keys = kcache.KeyCache()
keys.load_keyring(conf.get_item('gpg', 'keyhome'))
keys = kcache.KeyCache(conf.get_item('gpg', 'keyhome'))
keys.load()
controller = _init_controller(keys)
LOG.info("Starting the daemon...")

View File

@ -1,9 +1,12 @@
"""A cache of OpenPGP keys known to Lacre."""
import lacre.text as text
import logging
import GnuPG
LOG = logging.getLogger(__name__)
class KeyCache:
"""A store for OpenPGP keys.
@ -13,15 +16,21 @@ class KeyCache:
[default].
"""
def __init__(self):
"""Initialise an empty cache."""
def __init__(self, keyring_dir: str = None):
"""Initialise an empty cache.
With keyring_dir given, set location of the directory from which keys should be loaded.
"""
self._keys = dict()
self._keyring_dir = keyring_dir
def __getitem__(self, email):
return self._keys[email]
def __getitem__(self, fingerpring):
"""Look up email assigned to the given fingerprint."""
return self._keys[fingerpring]
def __setitem__(self, email, fingerprint):
self._keys[email] = fingerprint
def __setitem__(self, fingerprint, email):
"""Assign an email to a fingerpring, overwriting it if it was already present."""
self._keys[fingerprint] = email
def __contains__(self, fingerprint):
"""Check if the given fingerprint is assigned to an email."""
@ -30,17 +39,28 @@ class KeyCache:
return fingerprint in self._keys
def has_email(self, email):
"""Check if cache contains a key assigned to the given email."""
return email in self._keys.values()
def load(self):
"""Load keyring, replacing any previous contents of the cache."""
self.replace_keyring(self._load_keyring_from(self._keyring_dir))
reload = load
def load_keyring(self, keyhome: str):
"""Add all identities from keyring stored in KEYHOME."""
self.extend_keyring(GnuPG.public_keys(keyhome))
self.extend_keyring(self._load_keyring_from(keyhome))
def _load_keyring_from(self, keyring_dir):
return GnuPG.public_keys(keyring_dir)
def replace_keyring(self, keys: dict):
"""Overwrite previously stored key cache with KEYS."""
for fingerprint in keys:
keys[fingerprint] = text.sanitize_case_sense(keys[fingerprint])
LOG.info(f'Loaded {len(keys)} keys')
self._keys = keys
def extend_keyring(self, keys: dict):
@ -48,4 +68,5 @@ class KeyCache:
for fingerprint in keys:
keys[fingerprint] = text.sanitize_case_sense(keys[fingerprint])
LOG.info(f'Loaded {len(keys)} keys')
self._keys.update(keys)

View File

@ -6,6 +6,7 @@ date_format = ISO
[gpg]
keyhome = test/keyhome
cache_refresh_minutes = 1
[smime]
cert_path = test/certs