Reload key cache periodically

Use [default]cache_refresh_minutes configuration parameter to define periods
between cache reloads.  After this number of minutes cache will be reloaded.
This commit is contained in:
Piotr F. Mieszkowski 2022-10-11 21:50:51 +02:00 committed by Gitea
parent d7e4947afd
commit f5cff3292a
3 changed files with 21 additions and 14 deletions

View File

@ -3,7 +3,6 @@
import logging
import lacre
import lacre.config as conf
import lacre.keycache as kcache
import sys
from aiosmtpd.controller import Controller
from aiosmtpd.smtp import Envelope
@ -24,6 +23,7 @@ lacre.init_logging(conf.get_item("logging", "config"))
LOG = logging.getLogger(__name__)
import lacre.mailgate as gate
import lacre.keycache as kcache
class MailEncryptionProxy:
@ -48,11 +48,11 @@ class MailEncryptionProxy:
return RESULT_NOT_IMPLEMENTED
def _init_controller(keys: kcache.KeyCache):
def _init_controller(keys: kcache.KeyCache, tout: float = 2.5):
proxy = MailEncryptionProxy(keys)
host, port = conf.daemon_params()
LOG.info(f"Initialising a mail Controller at {host}:{port}")
return Controller(proxy, hostname=host, port=port)
return Controller(proxy, hostname=host, port=port, ready_timeout=tout)
def _validate_config():
@ -67,27 +67,26 @@ def _full_param_name(tup):
return f"[{tup[0]}]{tup[1]}"
async def _sleep():
async def _sleep(minutes, heartbeat_func):
while True:
await asyncio.sleep(5)
await asyncio.sleep(minutes * 60)
heartbeat_func()
def _main():
_validate_config()
refresh_min = float(conf.get_item('gpg', 'cache_refresh_minutes', 2))
keys = kcache.KeyCache(conf.get_item('gpg', 'keyhome'))
keys.load()
controller = _init_controller(keys)
LOG.info("Starting the daemon...")
# starts the controller in a new thread
controller.start()
# _this_ thread now continues operation, so it may be used to control key
# and certificate cache
try:
asyncio.run(_sleep())
asyncio.run(_sleep(refresh_min, keys.load))
except KeyboardInterrupt:
LOG.info("Finishing...")

View File

@ -8,6 +8,10 @@ import GnuPG
LOG = logging.getLogger(__name__)
class KeyCacheMisconfiguration(Exception):
"""Exception used to signal that KeyCache is misconfigured."""
class KeyCache:
"""A store for OpenPGP keys.
@ -44,11 +48,15 @@ class KeyCache:
def load(self):
"""Load keyring, replacing any previous contents of the cache."""
LOG.debug('Reloading keys...')
if self._keyring_dir is None:
LOG.error('Keyringn directory not set!')
raise KeyCacheMisconfiguration("Keyring directory not configured")
self.replace_keyring(self._load_keyring_from(self._keyring_dir))
reload = load
def load_keyring(self, keyhome: str):
def load_keyring_from(self, keyhome: str):
"""Add all identities from keyring stored in KEYHOME."""
self.extend_keyring(self._load_keyring_from(keyhome))
@ -60,7 +68,7 @@ class KeyCache:
for fingerprint in keys:
keys[fingerprint] = text.sanitize_case_sense(keys[fingerprint])
LOG.info(f'Loaded {len(keys)} keys')
LOG.info(f'Storing {len(keys)} keys')
self._keys = keys
def extend_keyring(self, keys: dict):
@ -68,5 +76,5 @@ class KeyCache:
for fingerprint in keys:
keys[fingerprint] = text.sanitize_case_sense(keys[fingerprint])
LOG.info(f'Loaded {len(keys)} keys')
LOG.info(f'Adding {len(keys)} keys')
self._keys.update(keys)

View File

@ -132,7 +132,7 @@ def _customise_headers(msg_copy):
def _load_keys():
"""Return a map from a key's fingerprint to email address."""
keys = kcache.KeyCache()
keys.load_keyring(conf.get_item('gpg', 'keyhome'))
keys.load_keyring_from(conf.get_item('gpg', 'keyhome'))
return keys