Compare commits

...

16 Commits

Author SHA1 Message Date
Scott Kitterman 59296be0cf Bump version to 1.1.3 2019-10-06 00:14:54 -04:00
Scott Kitterman 4e1fa3c8ff Update README now that sysv init is tested 2019-10-06 00:14:27 -04:00
Scott Kitterman 99899062bb Fix sysv init so it works (LP: #1839487) 2019-10-05 21:48:44 -04:00
Scott Kitterman 6a1705926f Update version/release date for 1.1.2 2019-09-23 13:36:56 -04:00
Scott Kitterman e6f8db9f94 More reslience fixes 2019-09-23 11:36:10 -04:00
Scott Kitterman e63867d517 Merge branch 'stable1.1' of git+ssh://git.launchpad.net/dkimpy-milter into stable1.1 2019-09-23 11:27:33 -04:00
Scott Kitterman 209ad11661 Catch more ascii encoding errors to improve resilience against bad data
(LP: #1844189)
2019-09-23 11:26:10 -04:00
Scott Kitterman 795a914845 Catch more ascii encoding errors to improve resilience against bad data
(LP: #1844189)
2019-09-23 11:04:02 -04:00
Scott Kitterman be92e5c5b1 Catch more ascii encoding errors to improve resilience against bad data
(LP: #1844189)
2019-09-23 10:48:04 -04:00
Scott Kitterman 6910ff1f9a Fix variable initialization so mailformed mails missing body From do not
cause a traceback (LP: #1844161)
2019-09-16 20:08:34 -04:00
Scott Kitterman 7953e54ffb CHANGES and setup.py updates for 1.1.1 release prep 2019-09-06 00:52:18 -04:00
Scott Kitterman bc98f9180f Fix startup logging so it provides information at a useful time 2019-09-06 00:41:42 -04:00
Scott Kitterman a144791f2a Minor README corrections 2019-09-06 00:37:46 -04:00
Scott Kitterman 55e1a6b54e Fixup missing i= processing 2019-09-06 00:27:52 -04:00
Scott Kitterman 7c3ff1905a - Fix verify processing so missing (optional) i= tag doesn't cause the milter
to fail
2019-09-06 00:22:00 -04:00
Scott Kitterman 7ec97a6001 - Fix message extraction so that signing in the same pass through the milter
as verifying works correctly
2019-09-05 23:55:34 -04:00
5 changed files with 66 additions and 25 deletions
+16
View File
@@ -1,3 +1,19 @@
1.1.3 2019-10-06
- Fix sysv init so it works (LP: #1839487)
1.1.2 2019-09-23
- Fix variable initialization so mailformed mails missing body From do not
cause a traceback (LP: #1844161)
- Catch more ascii encoding errors to improve resilience against bad data
(LP: #1844189)
1.1.1 2019-09-06
- Fix startup logging so it provides information at a useful time
- Fix verify processing so missing (optional) i= tag doesn't cause the milter
to fail (LP: #1842250)
- Fix message extraction so that signing in the same pass through the milter
as verifying works correctly
1.1.0 2019-04-12
- Add SubDomains option to enable signing for sub-domains (LP: #1811535)
- Port to python3 (LP: #1815502)
+4 -5
View File
@@ -22,7 +22,7 @@ python3 setup.py install --single-version-externally-managed --record=/dev/null
For users of Debian Stable (Debian 9, Codename Squeeze), all dependencies are
available in either the main or backports repositories:
[sudo] apt install python3-milter python3-nacl python3-ipaddress python3-dnspython
[sudo] apt install python3-milter python3-nacl python3-dnspython
[sudo] apt install -t stretch-backports python3-authres python3-dkim
The preferred method of installation is from PyPi using pip (if distribution
@@ -33,7 +33,7 @@ packages are not available):
Using pip will cause required packages to be installed via easy_install if they
have not been previously installed. Because pymilter and PyNaCl are compiled
Python extensions, the system will need appropriate development packages and
an C compiler. Alternately, install these dependencies from dsitribution/OS
an C compiler. Alternately, install these dependencies from distribution/OS
packages and then pip install dkimpy_milter.
The milter will work with either py3dns (DNS) or dnspython (dns), preferring
@@ -84,9 +84,8 @@ MTA INTEGRATION
Both a systemd unit file and a sysv init file are provided. Both make
assumptions about defaults being used, e.g. if a non-standard pidfile name is
used, they will need to be updated. The sysv init file is Debian specific and
untested, since the developers are not using sysv init. Feedback/patches
welcome.
used, they will need to be updated. The sysv init file uses start-stop-deamon
from Debian. It is not portable to systems without that available.
The dkimpy-milter drops priviledges after setup to the user/group specified in
UserID. During initial setup, this system user needs to be manually created.
+31 -7
View File
@@ -55,6 +55,7 @@ class dkimMilter(Milter.Base):
self.privatersa = privateRSA
self.privateed25519 = privateEd25519
self.fp = None
self.fdomain = ''
@Milter.noreply
def connect(self, hostname, unused, hostaddr):
@@ -136,14 +137,18 @@ class dkimMilter(Milter.Base):
try:
self.fdomain = self.author.split('@')[1].lower()
except IndexError as er:
self.fdomain = '' # self.author was not a proper email address
pass # self.author was not a proper email address
if (milterconfig.get('Syslog') and
milterconfig.get('debugLevel') >= 1):
syslog.syslog("{0}: {1}".format(name, val))
elif lname == 'authentication-results':
self.arheaders.append(val)
if self.fp:
try:
self.fp.write(b"%s: %s\n" % (codecs.encode(name, 'ascii'), codecs.encode(val, 'ascii')))
except:
# Don't choke on header fields with non-ascii garbage in them.
pass
return Milter.CONTINUE
@Milter.noreply
@@ -177,8 +182,9 @@ class dkimMilter(Milter.Base):
except:
# Don't error out on unparseable AR header fiels
pass
# Check or sign DKIM
# Check and/or sign DKIM
self.fp.seek(0)
txt = self.fp.read()
if milterconfig.get('Domain'):
domain = milterconfig.get('Domain')
else:
@@ -187,12 +193,10 @@ class dkimMilter(Milter.Base):
self.fdomain = _get_parent_domain(self.fdomain, domain)
if ((self.fdomain in domain) and not milterconfig.get('Mode') == 'v'
and not self.external_connection):
txt = self.fp.read()
self.sign_dkim(txt)
if ((self.has_dkim) and (not self.internal_connection) and
(milterconfig.get('Mode') == 'v' or
milterconfig.get('Mode') == 'sv')):
txt = self.fp.read()
self.check_dkim(txt)
if self.arresults:
h = authres.AuthenticationResultsHeader(authserv_id=
@@ -261,6 +265,7 @@ class dkimMilter(Milter.Base):
def check_dkim(self, txt):
res = False
self.header_a = None
for y in range(self.has_dkim): # Verify _ALL_ the signatures
d = dkim.DKIM(txt)
try:
@@ -289,9 +294,21 @@ class dkimMilter(Milter.Base):
self.dkim_comment = str(x)
if milterconfig.get('Syslog'):
syslog.syslog("check_dkim: {0}".format(x))
try:
# i= is optional and dkimpy is fine if it's not provided
self.header_i = codecs.decode(d.signature_fields.get(b'i'), 'ascii')
except TypeError as x:
self.header_i = None
try:
self.header_d = codecs.decode(d.signature_fields.get(b'd'), 'ascii')
self.header_a = codecs.decode(d.signature_fields.get(b'a'), 'ascii')
except Exception as x:
self.dkim_comment = str(x)
if milterconfig.get('Syslog'):
syslog.syslog("check_dkim: {0}".format(x))
self.header_d = None
if not self.header_a:
self.header_a = 'rsa-sha256'
if res:
if (milterconfig.get('Syslog') and
(milterconfig.get('SyslogSuccess') or
@@ -311,12 +328,18 @@ class dkimMilter(Milter.Base):
syslog.syslog('DKIM: Fail (saved as {0})'
.format(fname))
else:
syslog.syslog('DKIM: Fail ({0})'.format(d.domain.lower()))
if milterconfig.get('Syslog'):
if d.domain:
syslog.syslog('DKIM: Fail ({0})'
.format(d.domain.lower()))
else:
syslog.syslog('DKIM: Fail, unextractable domain')
if res:
result = 'pass'
else:
result = 'fail'
res = False
if self.header_d:
self.arresults.append(
authres.DKIMAuthenticationResult(result=result,
header_i=self.header_i,
@@ -325,6 +348,7 @@ class dkimMilter(Milter.Base):
result_comment=
self.dkim_comment)
)
self.header_a = None
return
# get parent domain to be signed for if fdomain is a subdomain
@@ -380,10 +404,10 @@ def main():
own_socketfile(milterconfig, socketname)
drop_privileges(milterconfig)
sys.stdout.flush()
Milter.runmilter(miltername, socketname, 240)
if milterconfig.get('Syslog'):
syslog.syslog('dkimpy-milter started:{0} user:{1}'
syslog.syslog('dkimpy-milter starting:{0} user:{1}'
.format(pid, milterconfig.get('UserID')))
Milter.runmilter(miltername, socketname, 240)
if __name__ == "__main__":
main()
+1 -1
View File
@@ -30,7 +30,7 @@ except ImportError: # If PyDNS is not installed, prefer dnspython
setup(
name='dkimpy-milter',
version='1.1.0',
version='1.1.3',
author='Scott Kitterman',
author_email='scott@kitterman.com',
url='https://launchpad.net/dkimpy-milter',
+8 -6
View File
@@ -20,7 +20,7 @@
### END INIT INFO
prefix="/usr/local"
exec_prefix=${prefix}
sysconfdir="/etc/dkimpy-milter"
sysconfdir="/usr/local/etc"
bindir="${exec_prefix}/bin/"
RUNDIR="/run/dkimpy-milter"
DAEMON=${bindir}/dkimpy-milter
@@ -67,14 +67,14 @@ case "$1" in
fi
fi
fi
start-stop-daemon --start --quiet --pidfile $RUNDIR/$NAME.pid --startas \
$DAEMON $sysconfdir/$NAME.conf --name $NAME --test > /dev/null \
start-stop-daemon --start --background --quiet --pidfile \
$RUNDIR/$NAME.pid --exec $DAEMON $sysconfdir/$NAME.conf
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
if [ -f $RUNDIR/$NAME.pid ]; then
chown root:root $RUNDIR/$NAME.pid
start-stop-daemon --stop --pidfile $RUNDIR/$NAME.pid
rm $RUNDIR/$NAME.pid
#echo $SOCKET
@@ -87,6 +87,7 @@ case "$1" in
force-reload)
echo -n "Force reloading $DESC: "
if [ -f $RUNDIR/$NAME.pid ]; then
chown root:root $RUNDIR/$NAME.pid
start-stop-daemon --stop --pidfile $RUNDIR/$NAME.pid
rm $RUNDIR/$NAME.pid
#echo $SOCKET
@@ -95,7 +96,7 @@ case "$1" in
fi
fi
sleep 1
start-stop-daemon --start --chuid $USER --background --quiet --pidfile \
start-stop-daemon --start --background --quiet --pidfile \
$RUNDIR/$NAME.pid --exec $DAEMON $sysconfdir/$NAME.conf
echo "$NAME."
;;
@@ -103,6 +104,7 @@ case "$1" in
echo "Restarting $DESC: "
echo -n "Stopping $DESC: "
if [ -f $RUNDIR/$NAME.pid ]; then
chown root:root $RUNDIR/$NAME.pid
start-stop-daemon --stop --pidfile $RUNDIR/$NAME.pid
rm $RUNDIR/$NAME.pid
#echo $SOCKET
@@ -113,7 +115,7 @@ case "$1" in
echo "$NAME."
sleep 1
echo -n "Starting $DESC: "
start-stop-daemon --start --chuid $USER --background --quiet --pidfile \
start-stop-daemon --start --background --quiet --pidfile \
$RUNDIR/$NAME.pid --exec $DAEMON $sysconfdir/$NAME.conf
echo "$NAME."
;;