From c523afe8e56367ef93314e4f5e19ae77e7c1af5b Mon Sep 17 00:00:00 2001 From: Scott Kitterman Date: Tue, 13 Feb 2018 23:16:44 -0500 Subject: [PATCH] Continue moving towards a working system: - Move exception hook from config into util - Make config data conversion work for all used types - Make syslog work (still need to make it only work if specified) --- dkimpy_milter/__init__.py | 37 ++++------------------ dkimpy_milter/config.py | 65 ++++++++++++++------------------------- dkimpy_milter/util.py | 24 +++++++++++++++ 3 files changed, 53 insertions(+), 73 deletions(-) diff --git a/dkimpy_milter/__init__.py b/dkimpy_milter/__init__.py index 32407e0..4bf5033 100644 --- a/dkimpy_milter/__init__.py +++ b/dkimpy_milter/__init__.py @@ -22,6 +22,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.""" import sys +import syslog import Milter import dkim from dkim.dnsplug import get_txt @@ -37,38 +38,11 @@ from Milter.config import MilterConfigParser from Milter.utils import iniplist,parse_addr,parseaddr import dkimpy_milter.config as config from dkimpy_milter.util import drop_privileges - -def read_config(list): - "Return new config object." - for fn in list: - if os.access(fn,os.R_OK): - logging.config.fileConfig(fn) - break - cp = MilterConfigParser() - cp.read(list) - if cp.has_option('milter','datadir'): - os.chdir(cp.get('milter','datadir')) - conf = Config() - conf.log = logging.getLogger('dkim-milter') - conf.log.info('logging started') - conf.socketname = cp.getdefault('milter','socketname', '/tmp/dkimmiltersock') - conf.miltername = cp.getdefault('milter','name','pydkimfilter') - conf.internal_connect = cp.getlist('milter','internal_connect') - # DKIM section - if cp.has_option('dkim','privkey'): - conf.keyfile = cp.getdefault('dkim','privkey') - conf.selector = cp.getdefault('dkim','selector','default') - conf.domain = cp.getdefault('dkim','domain') - conf.reject = cp.getdefault('dkim','reject') - if conf.keyfile and conf.domain: - try: - with open(conf.keyfile,'r') as kf: - conf.key = kf.read() - except: - conf.log.error('Unable to read: %s',conf.keyfile) - return conf +from dkimpy_milter.util import setExceptHook FWS = re.compile(r'\r?\n[ \t]+') +syslog.openlog(os.path.basename(sys.argv[0]), syslog.LOG_PID, syslog.LOG_MAIL) +setExceptHook() class dkimMilter(Milter.Base): "Milter to check and sign DKIM. Each connection gets its own instance." @@ -272,8 +246,9 @@ def main(): print('usage: dkimpy-milter []') sys.exit(1) configFile = sys.argv[1] + print('configfile', configFile) milterconfig = config._processConfigFile(filename = configFile) - + print('Socket', milterconfig.get('Socket')) drop_privileges(milterconfig) Milter.factory = dkimMilter(milterconfig) Milter.set_flags(Milter.CHGHDRS + Milter.ADDHDRS) diff --git a/dkimpy_milter/config.py b/dkimpy_milter/config.py index 4851e62..23ed129 100644 --- a/dkimpy_milter/config.py +++ b/dkimpy_milter/config.py @@ -27,17 +27,17 @@ import syslog import os import sys -import string import re import urllib import stat +import dkim # default values defaultConfigData = { 'Syslog' : 'yes', 'SyslogFacility' : 'mail', - 'UMask' : '007', + 'UMask' : 007, 'Mode' : 'sv', 'Socket' : 'local:/var/run/dkimpy-milter/dkimpy-milter.sock', 'PidFile' : '/var/run/dkimpy-milter/dkimpy-milter.pid', @@ -51,7 +51,6 @@ class ConfigException(Exception): '''Exception raised when there's a configuration file error.''' pass - #################################################################### def _processConfigFile(filename = None, configdata = None, useSyslog = 1, useStderr = 0): @@ -62,8 +61,9 @@ def _processConfigFile(filename = None, configdata = None, useSyslog = 1, if configdata == None: configdata = config.defaultConfigData if filename != None: try: - readConfigFile(filename, configdata) + _readConfigFile(filename, configdata) except Exception, e: + raise if useSyslog: syslog.syslog(e.args[0]) if useStderr: @@ -71,46 +71,22 @@ def _processConfigFile(filename = None, configdata = None, useSyslog = 1, sys.exit(1) return(configdata) - -################# -# FIXME - still uses string, refactor -class ExceptHook: - def __init__(self, useSyslog = 1, useStderr = 0): - self.useSyslog = useSyslog - self.useStderr = useStderr - - def __call__(self, etype, evalue, etb): - import traceback - tb = traceback.format_exception(*(etype, evalue, etb)) - tb = map(string.rstrip, tb) - tb = string.join(tb, '\n') - for line in string.split(tb, '\n'): - if self.useSyslog: - syslog.syslog(line) - if self.useStderr: - sys.stderr.write(line + '\n') - - #################### -def setExceptHook(): - sys.excepthook = ExceptHook(useSyslog = 1, useStderr = 1) - -#################### -def find_boolean(item): - if type(item) == int: - item = str(item) - if item[0] in ["T", "t", "Y", "y", "1"]: - item = True - elif item[0] in ["F", "f", "N", "n", "0"]: - item = False - else: - raise dkim.ParameterError() - return item +def _find_boolean(item): + if type(item) == int: + item = str(item) + if item[0] in ["T", "t", "Y", "y", "1"]: + item = True + elif item[0] in ["F", "f", "N", "n", "0"]: + item = False + else: + raise dkim.ParameterError() + return item ############################################################### commentRx = re.compile(r'^(.*)#.*$') -def readConfigFile(path, configData = None, configGlobal = {}): +def _readConfigFile(path, configData = None, configGlobal = {}): '''Reads a configuration file from the specified path, merging it with the configuration data specified in configData. Returns a dictionary of name/value pairs based on configData and the values @@ -124,7 +100,7 @@ def readConfigFile(path, configData = None, configGlobal = {}): 'Syslog' : 'bool', 'SyslogFacility' : 'str', 'SyslogSuccess' : 'bool', - 'UMask' : 'str', + 'UMask' : 'int', 'Mode' : 'str', 'Socket' : 'str', 'PidFile' : 'str', @@ -175,9 +151,14 @@ def readConfigFile(path, configData = None, configGlobal = {}): if debugLevel >= 5: syslog.syslog('readConfigFile: Found entry "%s=%s"' % ( name, value )) - if value == bool: - configData[name] = find_boolean(name) + if conversion == 'bool': + configData[name] = _find_boolean(value) + elif conversion == 'str': + configData[name] = str(value) + elif conversion == 'int': + configData[name] = int(value) else: + syslog.syslog(str('name: ' + name + ' value: ' + value + ' conversion: ' + conversion)) configData[name] = conversion(value) fp.close() diff --git a/dkimpy_milter/util.py b/dkimpy_milter/util.py index 6f6eaa6..5741145 100644 --- a/dkimpy_milter/util.py +++ b/dkimpy_milter/util.py @@ -50,3 +50,27 @@ def drop_privileges(milterconfig): # Set umask old_umask = os.umask(milterconfig.get('UMask')) + +################# +# FIXME - still uses string, refactor +class ExceptHook: + def __init__(self, useSyslog = 1, useStderr = 0): + self.useSyslog = useSyslog + self.useStderr = useStderr + + def __call__(self, etype, evalue, etb): + import traceback + import string + tb = traceback.format_exception(*(etype, evalue, etb)) + tb = map(string.rstrip, tb) + tb = string.join(tb, '\n') + for line in string.split(tb, '\n'): + if self.useSyslog: + import syslog + syslog.syslog(line) + + +#################### +def setExceptHook(): + import sys + sys.excepthook = ExceptHook(useSyslog = 1, useStderr = 1)