Create skeleton of the Lacre daemon
Also: - Expose a function to read mail relay configuration. - Replace tabs with 4 spaces in lacre.config.
This commit is contained in:
parent
8f191cae72
commit
3f2760ba2d
102
lacre/config.py
102
lacre/config.py
|
@ -16,72 +16,86 @@ CONFIG_PATH_ENV = "GPG_MAILGATE_CONFIG"
|
|||
# List of mandatory configuration parameters. Each item on this list should be
|
||||
# a pair: a section name and a parameter name.
|
||||
MANDATORY_CONFIG_ITEMS = [("relay", "host"),
|
||||
("relay", "port")]
|
||||
("relay", "port")]
|
||||
|
||||
# Global dict to keep configuration parameters. It's hidden behind several
|
||||
# utility functions to make it easy to replace it with ConfigParser object in
|
||||
# the future.
|
||||
cfg = dict()
|
||||
|
||||
|
||||
def load_config() -> dict:
|
||||
"""Parses configuration file.
|
||||
"""Parse configuration file.
|
||||
|
||||
If environment variable identified by CONFIG_PATH_ENV
|
||||
variable is set, its value is taken as a configuration file
|
||||
path. Otherwise, the default is taken
|
||||
('/etc/gpg-mailgate.conf').
|
||||
"""
|
||||
configFile = os.getenv(CONFIG_PATH_ENV, '/etc/gpg-mailgate.conf')
|
||||
If environment variable identified by CONFIG_PATH_ENV
|
||||
variable is set, its value is taken as a configuration file
|
||||
path. Otherwise, the default is taken
|
||||
('/etc/gpg-mailgate.conf').
|
||||
"""
|
||||
configFile = os.getenv(CONFIG_PATH_ENV, '/etc/gpg-mailgate.conf')
|
||||
|
||||
parser = read_config(configFile)
|
||||
parser = _read_config(configFile)
|
||||
|
||||
global cfg
|
||||
cfg = copy_to_dict(parser)
|
||||
return cfg
|
||||
global cfg
|
||||
cfg = _copy_to_dict(parser)
|
||||
return cfg
|
||||
|
||||
def read_config(fileName) -> RawConfigParser:
|
||||
cp = RawConfigParser()
|
||||
cp.read(fileName)
|
||||
|
||||
return cp
|
||||
def _read_config(fileName) -> RawConfigParser:
|
||||
cp = RawConfigParser()
|
||||
cp.read(fileName)
|
||||
|
||||
def copy_to_dict(confParser) -> dict:
|
||||
config = dict()
|
||||
return cp
|
||||
|
||||
for sect in confParser.sections():
|
||||
config[sect] = dict()
|
||||
for (name, value) in confParser.items(sect):
|
||||
config[sect][name] = value
|
||||
|
||||
return config
|
||||
def _copy_to_dict(confParser) -> dict:
|
||||
config = dict()
|
||||
|
||||
for sect in confParser.sections():
|
||||
config[sect] = dict()
|
||||
for (name, value) in confParser.items(sect):
|
||||
config[sect][name] = value
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def get_item(section, key, empty_value=None):
|
||||
global cfg
|
||||
if config_item_set(section, key):
|
||||
return cfg[section][key]
|
||||
else:
|
||||
return empty_value
|
||||
|
||||
def get_item(section, key, empty_value = None):
|
||||
global cfg
|
||||
if config_item_set(section, key):
|
||||
return cfg[section][key]
|
||||
else:
|
||||
return empty_value
|
||||
|
||||
def has_section(section) -> bool:
|
||||
global cfg
|
||||
return section in cfg
|
||||
return section in cfg
|
||||
|
||||
|
||||
def config_item_set(section, key) -> bool:
|
||||
global cfg
|
||||
return section in cfg and (key in cfg[section]) and not (cfg[section][key] is None)
|
||||
return section in cfg and (key in cfg[section]) and not (cfg[section][key] is None)
|
||||
|
||||
|
||||
def config_item_equals(section, key, value) -> bool:
|
||||
global cfg
|
||||
return section in cfg and key in cfg[section] and cfg[section][key] == value
|
||||
return section in cfg and key in cfg[section] and cfg[section][key] == value
|
||||
|
||||
|
||||
def validate_config():
|
||||
"""Checks whether the configuration is complete.
|
||||
"""Check if configuration is complete.
|
||||
|
||||
Returns a list of missing parameters, so an empty list means
|
||||
configuration is complete.
|
||||
"""
|
||||
missing = []
|
||||
for (section, param) in MANDATORY_CONFIG_ITEMS:
|
||||
if not config_item_set(section, param):
|
||||
missing.append((section, param))
|
||||
return missing
|
||||
Returns a list of missing parameters, so an empty list means
|
||||
configuration is complete.
|
||||
"""
|
||||
missing = []
|
||||
for (section, param) in MANDATORY_CONFIG_ITEMS:
|
||||
if not config_item_set(section, param):
|
||||
missing.append((section, param))
|
||||
return missing
|
||||
|
||||
|
||||
#
|
||||
# High level access to configuration.
|
||||
#
|
||||
|
||||
def relay_params():
|
||||
"""Return a (HOST, PORT) tuple identifying the mail relay."""
|
||||
return (cfg["relay"]["host"], int(cfg["relay"]["port"]))
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
"""Lacre Daemon, the Advanced Mail Filter message dispatcher."""
|
||||
|
||||
from aiosmtpd.controller import Controller
|
||||
|
||||
import lacre.config as conf
|
||||
# import lacre.mailgate as gate
|
||||
|
||||
|
||||
RESULT_OK = '250 OK'
|
||||
RESULT_ERROR = '500 Could not process your message'
|
||||
RESULT_NOT_IMPLEMENTED = '500 Not implemented yet'
|
||||
|
||||
|
||||
class MailEncryptionProxy:
|
||||
"""A mail handler dispatching to appropriate mail operation."""
|
||||
|
||||
async def handle_DATA(self, server, session, envelope):
|
||||
"""Accept a message and either encrypt it or forward as-is."""
|
||||
# for now, just return an error because we're not ready to handle mail
|
||||
return RESULT_NOT_IMPLEMENTED
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
proxy = MailEncryptionProxy()
|
||||
host, port = conf.relay_params()
|
||||
controller = Controller(proxy, hostname=host, port=port)
|
||||
|
||||
# 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
|
||||
|
||||
controller.stop()
|
|
@ -378,7 +378,7 @@ def send_msg( message, recipients ):
|
|||
recipients = [_f for _f in recipients if _f]
|
||||
if recipients:
|
||||
LOG.info(f"Sending email to: {recipients!r}")
|
||||
relay = (conf.get_item('relay', 'host'), int(conf.get_item('relay', 'port')))
|
||||
relay = conf.relay_params()
|
||||
smtp = smtplib.SMTP(relay[0], relay[1])
|
||||
if conf.config_item_equals('relay', 'starttls', 'yes'):
|
||||
smtp.starttls()
|
||||
|
|
Loading…
Reference in New Issue