Browse Source

Daemon improvements

* Use a configuration file for server-specific configuration.
* Only reply to mails originating from allowed_peers (if configured)
* Respond to SIGHUP to reload configuration. Changing the listen address or port requires a restart of the daemon
master
Johann Schmitz 6 years ago
parent
commit
f230820f04
Signed by: ercpe GPG Key ID: A084064277C501ED
  1. 6
      doc/vacationd.cfg
  2. 31
      src/greatvacation/daemon/config.py
  3. 23
      src/greatvacation/daemon/main.py
  4. 12
      src/greatvacation/daemon/vacationd.py

6
doc/vacationd.cfg

@ -0,0 +1,6 @@
# Example configuration file for vacationd
[server]
listen_address = 127.0.0.1
port = 1025
allowed_peers = 127.0.0.1

31
src/greatvacation/daemon/config.py

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
from ConfigParser import ConfigParser
import logging
class Config(object):
def __init__(self, config_file):
self.config_file = config_file
self.parser = None
self.read_config()
def read_config(self):
logging.info("(re-)loading configuration")
self.parser = ConfigParser()
read_files = self.parser.read(self.config_file)
if not (len(read_files) == 1 and read_files[0] == self.config_file):
raise Exception("Configuration file not read: %s" % self.config_file)
@property
def listen_address(self):
return self.parser.get('server', 'listen_address')
@property
def port(self):
return self.parser.get('server', 'port')
@property
def allowed_peers(self):
peers = self.parser.get('server', 'allowed_peers') if self.parser.has_option('server', 'allowed_peers') else ''
return [x.strip() for x in peers.split(',')]

23
src/greatvacation/daemon/main.py

@ -1,17 +1,30 @@
# -*- coding: utf-8 -*-
import argparse
import asyncore
import logging
import os
import signal
from greatvacation.daemon.config import Config
if __name__ == "__main__":
settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', None)
if not settings_module:
raise Exception("FIXME")
raise Exception("DJANGO_SETTINGS_MODULE not found in env.")
from greatvacation.daemon.vacationd import VacationSMTPServer
import django
django.setup()
# getattr(settings, 'EMAIL_HOST')
# import logging
server = VacationSMTPServer(('127.0.0.1', 1025), None)
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--config', help="Configuration file to use", required=True)
args = parser.parse_args()
config = Config(args.config)
signal.signal(signal.SIGHUP, lambda signum, frame: config.read_config())
from greatvacation.daemon.vacationd import VacationSMTPServer
server = VacationSMTPServer(config)
asyncore.loop()

12
src/greatvacation/daemon/vacationd.py

@ -13,12 +13,24 @@ from greatvacation.models import AutoReply, ReplyRule, UserReplyRule, SentReply
from email.mime.text import MIMEText
class VacationSMTPServer(smtpd.SMTPServer):
def __init__(self, config):
self.config = config
local_endpoint = config.listen_address, int(config.port)
logging.info("Starting server on %s:%s" % local_endpoint)
smtpd.SMTPServer.__init__(self, local_endpoint, None)
def process_message(self, peer, mailfrom, rcpttos, data):
logging.info('Receiving message from: %s:%s' % peer)
logging.info('Message addressed from: %s' % mailfrom)
logging.info('Message addressed to : %s' % rcpttos)
logging.info('Message length : %s' % len(data))
peer_addr, peer_port = peer
if self.config.allowed_peers and peer_addr not in self.config.allowed_peers:
logging.error("IGNORING mail from peer %s" % peer_addr)
return
mail = email.message_from_string(data)
mail_date = self.get_mail_date(mail)