lacre.daemon: When keys can't be loaded, fail gracefully
- Introduce '[daemon]bounce_on_keys_missing' option to let the admin decide if they want Lacre to deliver cleartext message when identity database is unreachable or throws exceptions. It defaults to 'no'. - In IdentityRepository, use option mentioned above to decide what to do when an exception is caught.
This commit is contained in:
parent
628de8a28d
commit
8cc1136a90
|
@ -68,6 +68,11 @@ max_data_bytes = 33554432
|
|||
# This should never be PII, but information like encoding, content types, etc.
|
||||
log_headers = no
|
||||
|
||||
# Sometimes we might fail to load keys and need to choose between delivering
|
||||
# in cleartext or not delivering. The default is to deliver cleartext, but
|
||||
# administrators can make this decision on their own.
|
||||
bounce_on_keys_missing = no
|
||||
|
||||
[relay]
|
||||
# the relay settings to use for Postfix
|
||||
# gpg-mailgate will submit email to this relay after it is done processing
|
||||
|
|
|
@ -37,9 +37,7 @@ class MailEncryptionProxy:
|
|||
with time_logger('Message delivery', LOG):
|
||||
try:
|
||||
keys = self._keyring.freeze_identities()
|
||||
LOG.debug('Parsing message: %s', self._beginning(envelope))
|
||||
message = email.message_from_bytes(envelope.original_content, policy=SMTPUTF8)
|
||||
LOG.debug('Parsed into %s: %s', type(message), repr(message))
|
||||
|
||||
if message.defects:
|
||||
LOG.warning("Issues found: %d; %s", len(message.defects), repr(message.defects))
|
||||
|
|
|
@ -13,6 +13,7 @@ LOG = logging.getLogger(__name__)
|
|||
# Internal state
|
||||
_engine = None
|
||||
|
||||
|
||||
def connect(url):
|
||||
global _engine
|
||||
|
||||
|
@ -78,13 +79,21 @@ class IdentityRepository(KeyRing):
|
|||
self._conn.execute(delq)
|
||||
|
||||
def freeze_identities(self) -> KeyCache:
|
||||
"""Return a static, async-safe copy of the identity map."""
|
||||
"""Return a static, async-safe copy of the identity map.
|
||||
|
||||
Depending on the value of [daemon]bounce_on_keys_missing value,
|
||||
if we get a database exception, this method will either return
|
||||
empty collection or let the exception be propagated.
|
||||
"""
|
||||
self._ensure_connected()
|
||||
try:
|
||||
return self._load_identities()
|
||||
except OperationalError:
|
||||
LOG.exception('Cannot retrieve identities')
|
||||
return None
|
||||
if conf.flag_enabled('daemon', 'bounce_on_keys_missing'):
|
||||
raise
|
||||
else:
|
||||
LOG.exception('Failed to load keys, returning empty collection')
|
||||
return KeyCache({})
|
||||
|
||||
def _load_identities(self) -> KeyCache:
|
||||
all_identities = select(self._identities.c.fingerprint, self._identities.c.email)
|
||||
|
|
Loading…
Reference in New Issue