From 2ac26c09ce2cbad1230d8c34918026c48f717340 Mon Sep 17 00:00:00 2001 From: "Piotr F. Mieszkowski" Date: Sat, 22 Oct 2022 11:19:47 +0200 Subject: [PATCH] Simplify code, improve log entries, add comments --- gpg-mailgate.py | 11 ++++++----- lacre/config.py | 11 ++++++++--- lacre/core.py | 22 +++++++--------------- lacre/daemon.py | 4 +++- lacre/keyring.py | 6 ++---- lacre/mailop.py | 8 ++++---- 6 files changed, 30 insertions(+), 32 deletions(-) diff --git a/gpg-mailgate.py b/gpg-mailgate.py index 57e1036..00c6b44 100755 --- a/gpg-mailgate.py +++ b/gpg-mailgate.py @@ -26,28 +26,29 @@ import logging import lacre import lacre.config as conf -start = time.time() +start = time.process_time() conf.load_config() lacre.init_logging(conf.get_item('logging', 'config')) # This has to be executed *after* logging initialisation. import lacre.core as core -LOG = logging.getLogger(__name__) +LOG = logging.getLogger('gpg-mailgate.py') missing_params = conf.validate_config() if missing_params: LOG.error(f"Aborting delivery! Following mandatory config parameters are missing: {missing_params!r}") sys.exit(lacre.EX_CONFIG) -# Read e-mail from stdin +# Read e-mail from stdin, parse it raw = sys.stdin.read() raw_message = email.message_from_string(raw) from_addr = raw_message['From'] +# Read recipients from the command-line to_addrs = sys.argv[1:] # Let's start core.deliver_message(raw_message, from_addr, to_addrs) -(elapsed_s, process_t) = core.exec_time_info(start) +process_t = (time.process_time() - start) * 1000 -LOG.info("Elapsed-time: {elapsed:.2f}s; Process-time: {process:.4f}s".format(elapsed=elapsed_s, process=process_t)) +LOG.info("Message delivered in {process:.2f} ms".format(process=process_t)) diff --git a/lacre/config.py b/lacre/config.py index d1d7821..707a1c5 100644 --- a/lacre/config.py +++ b/lacre/config.py @@ -1,6 +1,7 @@ -"""Lacre configuration +"""Lacre configuration. -Routines defined here are responsible for processing configuration. +Routines defined here are responsible for processing and validating +configuration. """ from configparser import RawConfigParser @@ -18,7 +19,8 @@ CONFIG_PATH_ENV = "GPG_MAILGATE_CONFIG" MANDATORY_CONFIG_ITEMS = [("relay", "host"), ("relay", "port"), ("daemon", "host"), - ("daemon", "port")] + ("daemon", "port"), + ("gpg", "keyhome")] # Global dict to keep configuration parameters. It's hidden behind several # utility functions to make it easy to replace it with ConfigParser object in @@ -38,6 +40,9 @@ def load_config() -> dict: parser = _read_config(configFile) + # XXX: Global variable. It is a left-over from old GPG-Mailgate code. We + # should drop it and probably use ConfigParser instance where configuration + # parameters are needed. global cfg cfg = _copy_to_dict(parser) return cfg diff --git a/lacre/core.py b/lacre/core.py index f92a691..d8b3707 100644 --- a/lacre/core.py +++ b/lacre/core.py @@ -1,9 +1,3 @@ -"""Lacre's actual mail-delivery module. - -IMPORTANT: This module has to be loaded _after_ initialisation of the logging -module. -""" - # # gpg-mailgate # @@ -23,6 +17,12 @@ module. # along with gpg-mailgate source code. If not, see . # +"""Lacre's actual mail-delivery module. + +IMPORTANT: This module has to be loaded _after_ initialisation of the logging +module. +""" + from email.mime.multipart import MIMEMultipart import copy import email @@ -32,7 +32,6 @@ import GnuPG import os import smtplib import sys -import time import asyncio # imports for S/MIME @@ -383,7 +382,7 @@ def _smime_encrypt(raw_message, recipients): unsmime_to = list() for addr in recipients: - cert_and_email = _get_cert_for_email(addr[0], cert_path) + cert_and_email = _get_cert_for_email(addr, cert_path) if not (cert_and_email is None): (to_cert, normal_email) = cert_and_email @@ -556,10 +555,3 @@ def deliver_message(raw_message: email.message.Message, from_address, to_addrs): # Send out mail to recipients which are left LOG.debug("Sending the rest as text/plain") send_msg(raw_message.as_string(), recipients_left) - - -def exec_time_info(start_timestamp): - """Calculate time since the given timestamp.""" - elapsed_s = time.time() - start_timestamp - process_t = time.process_time() - return (elapsed_s, process_t) diff --git a/lacre/daemon.py b/lacre/daemon.py index e3fd850..c1e8e4e 100644 --- a/lacre/daemon.py +++ b/lacre/daemon.py @@ -22,7 +22,7 @@ RESULT_NOT_IMPLEMENTED = '500 Not implemented yet' # the last Lacre module, i.e. lacre.mailgate. conf.load_config() lacre.init_logging(conf.get_item("logging", "config")) -LOG = logging.getLogger(__name__) +LOG = logging.getLogger('lacre.daemon') import lacre.core as gate import lacre.keyring as kcache @@ -103,6 +103,8 @@ def _main(): asyncio.run(_sleep()) except KeyboardInterrupt: LOG.info("Finishing...") + except: + LOG.exception('Unexpected exception caught, your system may be unstable') finally: LOG.info('Shutting down keyring watcher and the daemon...') reloader.stop() diff --git a/lacre/keyring.py b/lacre/keyring.py index 34f1d70..6387e9b 100644 --- a/lacre/keyring.py +++ b/lacre/keyring.py @@ -17,10 +17,7 @@ LOG = logging.getLogger(__name__) def _sanitize(keys): - for fingerprint in keys: - keys[fingerprint] = text.sanitize_case_sense(keys[fingerprint]) - - return keys + return {fingerprint: text.sanitize_case_sense(keys[fingerprint]) for fingerprint in keys} class KeyCacheMisconfiguration(Exception): @@ -118,6 +115,7 @@ class KeyRing: def _read_mod_time(self): # (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) + # 0 1 2 3 4 5 6 7 8 9 MTIME = 8 st = stat(self._path) return st[MTIME] diff --git a/lacre/mailop.py b/lacre/mailop.py index ec8d870..db0f8b2 100644 --- a/lacre/mailop.py +++ b/lacre/mailop.py @@ -73,8 +73,8 @@ class InlineOpenPGPEncrypt(OpenPGPEncrypt): """Encrypt with PGP Inline.""" LOG.debug('Sending PGP/Inline...') return core._gpg_encrypt_and_return(msg, - self._keys, self._recipients, - core._encrypt_all_payloads_inline) + self._keys, self._recipients, + core._encrypt_all_payloads_inline) class MimeOpenPGPEncrypt(OpenPGPEncrypt): @@ -88,8 +88,8 @@ class MimeOpenPGPEncrypt(OpenPGPEncrypt): """Encrypt with PGP MIME.""" LOG.debug('Sending PGP/MIME...') return core._gpg_encrypt_and_return(msg, - self._keys, self._recipients, - core._encrypt_all_payloads_mime) + self._keys, self._recipients, + core._encrypt_all_payloads_mime) class SMimeEncrypt(MailOperation):