Piotr F. Mieszkowski
4c844384e3
- Forward messages without encryption. - Include a simple test setup in the Makefile. - Add a test to send a test message to the daemon.
84 lines
2.3 KiB
Python
84 lines
2.3 KiB
Python
"""Lacre Daemon, the Advanced Mail Filter message dispatcher."""
|
|
|
|
import logging
|
|
import lacre
|
|
import lacre.config as conf
|
|
import sys
|
|
from aiosmtpd.controller import Controller
|
|
import asyncio
|
|
|
|
# Mail status constants.
|
|
#
|
|
# These are the only values that our mail handler is allowed to return.
|
|
RESULT_OK = '250 OK'
|
|
RESULT_ERROR = '500 Could not process your message'
|
|
RESULT_NOT_IMPLEMENTED = '500 Not implemented yet'
|
|
|
|
# Load configuration and init logging, in this order. Only then can we load
|
|
# the last Lacre module, i.e. lacre.mailgate.
|
|
conf.load_config()
|
|
lacre.init_logging(conf.get_item("logging", "config"))
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
import lacre.mailgate as gate
|
|
|
|
|
|
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
|
|
|
|
for recipient, operation in gate.delivery_plan(envelope.rcpt_tos):
|
|
LOG.debug(f"Sending mail to {recipient} via {operation}")
|
|
new_message = operation.perform(envelope.content)
|
|
gate.send_msg(new_message, [recipient], envelope.mail_from)
|
|
|
|
return RESULT_NOT_IMPLEMENTED
|
|
|
|
|
|
def _init_controller():
|
|
proxy = MailEncryptionProxy()
|
|
host, port = conf.daemon_params()
|
|
LOG.info(f"Initialising a mail Controller at {host}:{port}")
|
|
return Controller(proxy, hostname=host, port=port)
|
|
|
|
|
|
def _validate_config():
|
|
missing = conf.validate_config()
|
|
if missing:
|
|
params = ", ".join([f"[{tup[0]}]{tup[1]}" for tup in missing])
|
|
LOG.error(f"Following mandatory parameters are missing: {params}")
|
|
sys.exit(lacre.EX_CONFIG)
|
|
|
|
|
|
async def _sleep():
|
|
while True:
|
|
await asyncio.sleep(5)
|
|
|
|
|
|
def _main():
|
|
_validate_config()
|
|
|
|
controller = _init_controller()
|
|
|
|
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())
|
|
except KeyboardInterrupt:
|
|
LOG.info("Finishing...")
|
|
|
|
controller.stop()
|
|
|
|
LOG.info("Done")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
_main()
|