Compare commits

..

13 Commits

Author SHA1 Message Date
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
4 changed files with 53 additions and 16 deletions
+13
View File
@@ -1,3 +1,16 @@
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 1.1.0 2019-04-12
- Add SubDomains option to enable signing for sub-domains (LP: #1811535) - Add SubDomains option to enable signing for sub-domains (LP: #1811535)
- Port to python3 (LP: #1815502) - Port to python3 (LP: #1815502)
+2 -2
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 For users of Debian Stable (Debian 9, Codename Squeeze), all dependencies are
available in either the main or backports repositories: 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 [sudo] apt install -t stretch-backports python3-authres python3-dkim
The preferred method of installation is from PyPi using pip (if distribution 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 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 have not been previously installed. Because pymilter and PyNaCl are compiled
Python extensions, the system will need appropriate development packages and 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. packages and then pip install dkimpy_milter.
The milter will work with either py3dns (DNS) or dnspython (dns), preferring The milter will work with either py3dns (DNS) or dnspython (dns), preferring
+37 -13
View File
@@ -55,6 +55,7 @@ class dkimMilter(Milter.Base):
self.privatersa = privateRSA self.privatersa = privateRSA
self.privateed25519 = privateEd25519 self.privateed25519 = privateEd25519
self.fp = None self.fp = None
self.fdomain = ''
@Milter.noreply @Milter.noreply
def connect(self, hostname, unused, hostaddr): def connect(self, hostname, unused, hostaddr):
@@ -136,14 +137,18 @@ class dkimMilter(Milter.Base):
try: try:
self.fdomain = self.author.split('@')[1].lower() self.fdomain = self.author.split('@')[1].lower()
except IndexError as er: 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 if (milterconfig.get('Syslog') and
milterconfig.get('debugLevel') >= 1): milterconfig.get('debugLevel') >= 1):
syslog.syslog("{0}: {1}".format(name, val)) syslog.syslog("{0}: {1}".format(name, val))
elif lname == 'authentication-results': elif lname == 'authentication-results':
self.arheaders.append(val) self.arheaders.append(val)
if self.fp: if self.fp:
self.fp.write(b"%s: %s\n" % (codecs.encode(name, 'ascii'), codecs.encode(val, 'ascii'))) 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 return Milter.CONTINUE
@Milter.noreply @Milter.noreply
@@ -177,8 +182,9 @@ class dkimMilter(Milter.Base):
except: except:
# Don't error out on unparseable AR header fiels # Don't error out on unparseable AR header fiels
pass pass
# Check or sign DKIM # Check and/or sign DKIM
self.fp.seek(0) self.fp.seek(0)
txt = self.fp.read()
if milterconfig.get('Domain'): if milterconfig.get('Domain'):
domain = milterconfig.get('Domain') domain = milterconfig.get('Domain')
else: else:
@@ -187,12 +193,10 @@ class dkimMilter(Milter.Base):
self.fdomain = _get_parent_domain(self.fdomain, domain) self.fdomain = _get_parent_domain(self.fdomain, domain)
if ((self.fdomain in domain) and not milterconfig.get('Mode') == 'v' if ((self.fdomain in domain) and not milterconfig.get('Mode') == 'v'
and not self.external_connection): and not self.external_connection):
txt = self.fp.read()
self.sign_dkim(txt) self.sign_dkim(txt)
if ((self.has_dkim) and (not self.internal_connection) and if ((self.has_dkim) and (not self.internal_connection) and
(milterconfig.get('Mode') == 'v' or (milterconfig.get('Mode') == 'v' or
milterconfig.get('Mode') == 'sv')): milterconfig.get('Mode') == 'sv')):
txt = self.fp.read()
self.check_dkim(txt) self.check_dkim(txt)
if self.arresults: if self.arresults:
h = authres.AuthenticationResultsHeader(authserv_id= h = authres.AuthenticationResultsHeader(authserv_id=
@@ -261,6 +265,7 @@ class dkimMilter(Milter.Base):
def check_dkim(self, txt): def check_dkim(self, txt):
res = False res = False
self.header_a = None
for y in range(self.has_dkim): # Verify _ALL_ the signatures for y in range(self.has_dkim): # Verify _ALL_ the signatures
d = dkim.DKIM(txt) d = dkim.DKIM(txt)
try: try:
@@ -289,9 +294,21 @@ class dkimMilter(Milter.Base):
self.dkim_comment = str(x) self.dkim_comment = str(x)
if milterconfig.get('Syslog'): if milterconfig.get('Syslog'):
syslog.syslog("check_dkim: {0}".format(x)) syslog.syslog("check_dkim: {0}".format(x))
self.header_i = codecs.decode(d.signature_fields.get(b'i'), 'ascii') try:
self.header_d = codecs.decode(d.signature_fields.get(b'd'), 'ascii') # i= is optional and dkimpy is fine if it's not provided
self.header_a = codecs.decode(d.signature_fields.get(b'a'), 'ascii') 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 res:
if (milterconfig.get('Syslog') and if (milterconfig.get('Syslog') and
(milterconfig.get('SyslogSuccess') or (milterconfig.get('SyslogSuccess') or
@@ -311,20 +328,27 @@ class dkimMilter(Milter.Base):
syslog.syslog('DKIM: Fail (saved as {0})' syslog.syslog('DKIM: Fail (saved as {0})'
.format(fname)) .format(fname))
else: 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: if res:
result = 'pass' result = 'pass'
else: else:
result = 'fail' result = 'fail'
res = False res = False
self.arresults.append( if self.header_d:
authres.DKIMAuthenticationResult(result=result, self.arresults.append(
authres.DKIMAuthenticationResult(result=result,
header_i=self.header_i, header_i=self.header_i,
header_d=self.header_d, header_d=self.header_d,
header_a=self.header_a, header_a=self.header_a,
result_comment= result_comment=
self.dkim_comment) self.dkim_comment)
) )
self.header_a = None
return return
# get parent domain to be signed for if fdomain is a subdomain # get parent domain to be signed for if fdomain is a subdomain
@@ -380,10 +404,10 @@ def main():
own_socketfile(milterconfig, socketname) own_socketfile(milterconfig, socketname)
drop_privileges(milterconfig) drop_privileges(milterconfig)
sys.stdout.flush() sys.stdout.flush()
Milter.runmilter(miltername, socketname, 240)
if milterconfig.get('Syslog'): 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'))) .format(pid, milterconfig.get('UserID')))
Milter.runmilter(miltername, socketname, 240)
if __name__ == "__main__": if __name__ == "__main__":
main() main()
+1 -1
View File
@@ -30,7 +30,7 @@ except ImportError: # If PyDNS is not installed, prefer dnspython
setup( setup(
name='dkimpy-milter', name='dkimpy-milter',
version='1.1.0', version='1.1.2',
author='Scott Kitterman', author='Scott Kitterman',
author_email='scott@kitterman.com', author_email='scott@kitterman.com',
url='https://launchpad.net/dkimpy-milter', url='https://launchpad.net/dkimpy-milter',