forked from Disroot/gpg-lacre
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:
parent
d7e4947afd
commit
f5cff3292a
|
@ -3,7 +3,6 @@
|
||||||
import logging
|
import logging
|
||||||
import lacre
|
import lacre
|
||||||
import lacre.config as conf
|
import lacre.config as conf
|
||||||
import lacre.keycache as kcache
|
|
||||||
import sys
|
import sys
|
||||||
from aiosmtpd.controller import Controller
|
from aiosmtpd.controller import Controller
|
||||||
from aiosmtpd.smtp import Envelope
|
from aiosmtpd.smtp import Envelope
|
||||||
|
@ -24,6 +23,7 @@ lacre.init_logging(conf.get_item("logging", "config"))
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
import lacre.mailgate as gate
|
import lacre.mailgate as gate
|
||||||
|
import lacre.keycache as kcache
|
||||||
|
|
||||||
|
|
||||||
class MailEncryptionProxy:
|
class MailEncryptionProxy:
|
||||||
|
@ -48,11 +48,11 @@ class MailEncryptionProxy:
|
||||||
return RESULT_NOT_IMPLEMENTED
|
return RESULT_NOT_IMPLEMENTED
|
||||||
|
|
||||||
|
|
||||||
def _init_controller(keys: kcache.KeyCache):
|
def _init_controller(keys: kcache.KeyCache, tout: float = 2.5):
|
||||||
proxy = MailEncryptionProxy(keys)
|
proxy = MailEncryptionProxy(keys)
|
||||||
host, port = conf.daemon_params()
|
host, port = conf.daemon_params()
|
||||||
LOG.info(f"Initialising a mail Controller at {host}:{port}")
|
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():
|
def _validate_config():
|
||||||
|
@ -67,27 +67,26 @@ def _full_param_name(tup):
|
||||||
return f"[{tup[0]}]{tup[1]}"
|
return f"[{tup[0]}]{tup[1]}"
|
||||||
|
|
||||||
|
|
||||||
async def _sleep():
|
async def _sleep(minutes, heartbeat_func):
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(5)
|
await asyncio.sleep(minutes * 60)
|
||||||
|
heartbeat_func()
|
||||||
|
|
||||||
|
|
||||||
def _main():
|
def _main():
|
||||||
_validate_config()
|
_validate_config()
|
||||||
|
|
||||||
|
refresh_min = float(conf.get_item('gpg', 'cache_refresh_minutes', 2))
|
||||||
|
|
||||||
keys = kcache.KeyCache(conf.get_item('gpg', 'keyhome'))
|
keys = kcache.KeyCache(conf.get_item('gpg', 'keyhome'))
|
||||||
keys.load()
|
keys.load()
|
||||||
controller = _init_controller(keys)
|
controller = _init_controller(keys)
|
||||||
|
|
||||||
LOG.info("Starting the daemon...")
|
LOG.info("Starting the daemon...")
|
||||||
# starts the controller in a new thread
|
|
||||||
controller.start()
|
controller.start()
|
||||||
|
|
||||||
# _this_ thread now continues operation, so it may be used to control key
|
|
||||||
# and certificate cache
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
asyncio.run(_sleep())
|
asyncio.run(_sleep(refresh_min, keys.load))
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
LOG.info("Finishing...")
|
LOG.info("Finishing...")
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,10 @@ import GnuPG
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class KeyCacheMisconfiguration(Exception):
|
||||||
|
"""Exception used to signal that KeyCache is misconfigured."""
|
||||||
|
|
||||||
|
|
||||||
class KeyCache:
|
class KeyCache:
|
||||||
"""A store for OpenPGP keys.
|
"""A store for OpenPGP keys.
|
||||||
|
|
||||||
|
@ -44,11 +48,15 @@ class KeyCache:
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
"""Load keyring, replacing any previous contents of the cache."""
|
"""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))
|
self.replace_keyring(self._load_keyring_from(self._keyring_dir))
|
||||||
|
|
||||||
reload = load
|
reload = load
|
||||||
|
|
||||||
def load_keyring(self, keyhome: str):
|
def load_keyring_from(self, keyhome: str):
|
||||||
"""Add all identities from keyring stored in KEYHOME."""
|
"""Add all identities from keyring stored in KEYHOME."""
|
||||||
self.extend_keyring(self._load_keyring_from(keyhome))
|
self.extend_keyring(self._load_keyring_from(keyhome))
|
||||||
|
|
||||||
|
@ -60,7 +68,7 @@ class KeyCache:
|
||||||
for fingerprint in keys:
|
for fingerprint in keys:
|
||||||
keys[fingerprint] = text.sanitize_case_sense(keys[fingerprint])
|
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
|
self._keys = keys
|
||||||
|
|
||||||
def extend_keyring(self, keys: dict):
|
def extend_keyring(self, keys: dict):
|
||||||
|
@ -68,5 +76,5 @@ class KeyCache:
|
||||||
for fingerprint in keys:
|
for fingerprint in keys:
|
||||||
keys[fingerprint] = text.sanitize_case_sense(keys[fingerprint])
|
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)
|
self._keys.update(keys)
|
||||||
|
|
|
@ -132,7 +132,7 @@ def _customise_headers(msg_copy):
|
||||||
def _load_keys():
|
def _load_keys():
|
||||||
"""Return a map from a key's fingerprint to email address."""
|
"""Return a map from a key's fingerprint to email address."""
|
||||||
keys = kcache.KeyCache()
|
keys = kcache.KeyCache()
|
||||||
keys.load_keyring(conf.get_item('gpg', 'keyhome'))
|
keys.load_keyring_from(conf.get_item('gpg', 'keyhome'))
|
||||||
return keys
|
return keys
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue