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)
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."""
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import syslog
|
||||||
import Milter
|
import Milter
|
||||||
import dkim
|
import dkim
|
||||||
from dkim.dnsplug import get_txt
|
from dkim.dnsplug import get_txt
|
||||||
@@ -37,38 +38,11 @@ from Milter.config import MilterConfigParser
|
|||||||
from Milter.utils import iniplist,parse_addr,parseaddr
|
from Milter.utils import iniplist,parse_addr,parseaddr
|
||||||
import dkimpy_milter.config as config
|
import dkimpy_milter.config as config
|
||||||
from dkimpy_milter.util import drop_privileges
|
from dkimpy_milter.util import drop_privileges
|
||||||
|
from dkimpy_milter.util import setExceptHook
|
||||||
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
|
|
||||||
|
|
||||||
FWS = re.compile(r'\r?\n[ \t]+')
|
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):
|
class dkimMilter(Milter.Base):
|
||||||
"Milter to check and sign DKIM. Each connection gets its own instance."
|
"Milter to check and sign DKIM. Each connection gets its own instance."
|
||||||
@@ -272,8 +246,9 @@ def main():
|
|||||||
print('usage: dkimpy-milter [<configfilename>]')
|
print('usage: dkimpy-milter [<configfilename>]')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
configFile = sys.argv[1]
|
configFile = sys.argv[1]
|
||||||
|
print('configfile', configFile)
|
||||||
milterconfig = config._processConfigFile(filename = configFile)
|
milterconfig = config._processConfigFile(filename = configFile)
|
||||||
|
print('Socket', milterconfig.get('Socket'))
|
||||||
drop_privileges(milterconfig)
|
drop_privileges(milterconfig)
|
||||||
Milter.factory = dkimMilter(milterconfig)
|
Milter.factory = dkimMilter(milterconfig)
|
||||||
Milter.set_flags(Milter.CHGHDRS + Milter.ADDHDRS)
|
Milter.set_flags(Milter.CHGHDRS + Milter.ADDHDRS)
|
||||||
|
|||||||
+23
-42
@@ -27,17 +27,17 @@
|
|||||||
import syslog
|
import syslog
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import string
|
|
||||||
import re
|
import re
|
||||||
import urllib
|
import urllib
|
||||||
import stat
|
import stat
|
||||||
|
import dkim
|
||||||
|
|
||||||
|
|
||||||
# default values
|
# default values
|
||||||
defaultConfigData = {
|
defaultConfigData = {
|
||||||
'Syslog' : 'yes',
|
'Syslog' : 'yes',
|
||||||
'SyslogFacility' : 'mail',
|
'SyslogFacility' : 'mail',
|
||||||
'UMask' : '007',
|
'UMask' : 007,
|
||||||
'Mode' : 'sv',
|
'Mode' : 'sv',
|
||||||
'Socket' : 'local:/var/run/dkimpy-milter/dkimpy-milter.sock',
|
'Socket' : 'local:/var/run/dkimpy-milter/dkimpy-milter.sock',
|
||||||
'PidFile' : '/var/run/dkimpy-milter/dkimpy-milter.pid',
|
'PidFile' : '/var/run/dkimpy-milter/dkimpy-milter.pid',
|
||||||
@@ -51,7 +51,6 @@ class ConfigException(Exception):
|
|||||||
'''Exception raised when there's a configuration file error.'''
|
'''Exception raised when there's a configuration file error.'''
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
def _processConfigFile(filename = None, configdata = None, useSyslog = 1,
|
def _processConfigFile(filename = None, configdata = None, useSyslog = 1,
|
||||||
useStderr = 0):
|
useStderr = 0):
|
||||||
@@ -62,8 +61,9 @@ def _processConfigFile(filename = None, configdata = None, useSyslog = 1,
|
|||||||
if configdata == None: configdata = config.defaultConfigData
|
if configdata == None: configdata = config.defaultConfigData
|
||||||
if filename != None:
|
if filename != None:
|
||||||
try:
|
try:
|
||||||
readConfigFile(filename, configdata)
|
_readConfigFile(filename, configdata)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
raise
|
||||||
if useSyslog:
|
if useSyslog:
|
||||||
syslog.syslog(e.args[0])
|
syslog.syslog(e.args[0])
|
||||||
if useStderr:
|
if useStderr:
|
||||||
@@ -71,46 +71,22 @@ def _processConfigFile(filename = None, configdata = None, useSyslog = 1,
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return(configdata)
|
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():
|
def _find_boolean(item):
|
||||||
sys.excepthook = ExceptHook(useSyslog = 1, useStderr = 1)
|
if type(item) == int:
|
||||||
|
item = str(item)
|
||||||
####################
|
if item[0] in ["T", "t", "Y", "y", "1"]:
|
||||||
def find_boolean(item):
|
item = True
|
||||||
if type(item) == int:
|
elif item[0] in ["F", "f", "N", "n", "0"]:
|
||||||
item = str(item)
|
item = False
|
||||||
if item[0] in ["T", "t", "Y", "y", "1"]:
|
else:
|
||||||
item = True
|
raise dkim.ParameterError()
|
||||||
elif item[0] in ["F", "f", "N", "n", "0"]:
|
return item
|
||||||
item = False
|
|
||||||
else:
|
|
||||||
raise dkim.ParameterError()
|
|
||||||
return item
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
commentRx = re.compile(r'^(.*)#.*$')
|
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
|
'''Reads a configuration file from the specified path, merging it
|
||||||
with the configuration data specified in configData. Returns a
|
with the configuration data specified in configData. Returns a
|
||||||
dictionary of name/value pairs based on configData and the values
|
dictionary of name/value pairs based on configData and the values
|
||||||
@@ -124,7 +100,7 @@ def readConfigFile(path, configData = None, configGlobal = {}):
|
|||||||
'Syslog' : 'bool',
|
'Syslog' : 'bool',
|
||||||
'SyslogFacility' : 'str',
|
'SyslogFacility' : 'str',
|
||||||
'SyslogSuccess' : 'bool',
|
'SyslogSuccess' : 'bool',
|
||||||
'UMask' : 'str',
|
'UMask' : 'int',
|
||||||
'Mode' : 'str',
|
'Mode' : 'str',
|
||||||
'Socket' : 'str',
|
'Socket' : 'str',
|
||||||
'PidFile' : 'str',
|
'PidFile' : 'str',
|
||||||
@@ -175,9 +151,14 @@ def readConfigFile(path, configData = None, configGlobal = {}):
|
|||||||
|
|
||||||
if debugLevel >= 5: syslog.syslog('readConfigFile: Found entry "%s=%s"'
|
if debugLevel >= 5: syslog.syslog('readConfigFile: Found entry "%s=%s"'
|
||||||
% ( name, value ))
|
% ( name, value ))
|
||||||
if value == bool:
|
if conversion == 'bool':
|
||||||
configData[name] = find_boolean(name)
|
configData[name] = _find_boolean(value)
|
||||||
|
elif conversion == 'str':
|
||||||
|
configData[name] = str(value)
|
||||||
|
elif conversion == 'int':
|
||||||
|
configData[name] = int(value)
|
||||||
else:
|
else:
|
||||||
|
syslog.syslog(str('name: ' + name + ' value: ' + value + ' conversion: ' + conversion))
|
||||||
configData[name] = conversion(value)
|
configData[name] = conversion(value)
|
||||||
fp.close()
|
fp.close()
|
||||||
|
|
||||||
|
|||||||
@@ -50,3 +50,27 @@ def drop_privileges(milterconfig):
|
|||||||
|
|
||||||
# Set umask
|
# Set umask
|
||||||
old_umask = os.umask(milterconfig.get('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)
|
||||||
|
|||||||
Reference in New Issue
Block a user