Refactor for verifying multiple signatures

This commit is contained in:
Scott Kitterman
2018-02-15 00:34:16 -05:00
parent 92923fdbc4
commit 08d52edd2c
+39 -37
View File
@@ -88,11 +88,11 @@ class dkimMilter(Milter.Base):
if len(t) == 2: t[1] = t[1].lower() if len(t) == 2: t[1] = t[1].lower()
self.canon_from = '@'.join(t) self.canon_from = '@'.join(t)
self.user = self.getsymval('{auth_authen}') self.user = self.getsymval('{auth_authen}')
self.has_dkim = False self.has_dkim = 0
self.author = None self.author = None
self.arheaders = [] self.arheaders = []
self.arresults = [] self.arresults = []
if self.user: '''if self.user:
# Very simple SMTP AUTH policy by default: # Very simple SMTP AUTH policy by default:
# any successful authentication is considered INTERNAL # any successful authentication is considered INTERNAL
self.internal_connection = True self.internal_connection = True
@@ -106,15 +106,15 @@ class dkimMilter(Milter.Base):
self.arresults.append( self.arresults.append(
authres.SMTPAUTHAuthenticationResult(result = 'pass', authres.SMTPAUTHAuthenticationResult(result = 'pass',
result_comment = auth_type+' sslbits='+ssl_bits, smtp_auth = self.user) result_comment = auth_type+' sslbits='+ssl_bits, smtp_auth = self.user)
) )'''
return Milter.CONTINUE return Milter.CONTINUE
@Milter.noreply @Milter.noreply
def header(self,name,val): def header(self,name,val):
lname = name.lower() lname = name.lower()
if not self.has_dkim and lname == 'dkim-signature': if lname == 'dkim-signature':
self.log("%s: %s" % (name,val)) self.log("%s: %s" % (name,val))
self.has_dkim = True self.has_dkim += 1
if lname == 'from': if lname == 'from':
fname,self.author = parseaddr(val) fname,self.author = parseaddr(val)
self.log("%s: %s" % (name,val)) self.log("%s: %s" % (name,val))
@@ -156,15 +156,7 @@ class dkimMilter(Milter.Base):
result = None result = None
if self.has_dkim and (conf.get('Mode') == 'v' or conf.get('Mode') == 'sv'): if self.has_dkim and (conf.get('Mode') == 'v' or conf.get('Mode') == 'sv'):
txt = self.fp.read() txt = self.fp.read()
if self.check_dkim(txt): self.check_dkim(txt)
result = 'pass'
else:
result = 'fail'
self.arresults.append(
authres.DKIMAuthenticationResult(result=result,
header_i = self.header_i, header_d = self.header_d,
result_comment = self.dkim_comment)
)
else: else:
result = 'none' result = 'none'
if self.arresults: if self.arresults:
@@ -192,29 +184,39 @@ class dkimMilter(Milter.Base):
res = False res = False
conf = self.conf conf = self.conf
d = dkim.DKIM(txt,logger=conf.log) d = dkim.DKIM(txt,logger=conf.log)
try: for y in range(self.has_dkim): # Verify _ALL_ the signatures
res = d.verify() try:
if res: res = d.verify(idx=y)
self.dkim_comment = 'Good %d bit signature.' % d.keysize if res:
else: self.dkim_comment = 'Good %d bit signature.' % d.keysize
self.dkim_comment = 'Bad %d bit signature.' % d.keysize else:
except dkim.DKIMException as x: self.dkim_comment = 'Bad %d bit signature.' % d.keysize
self.dkim_comment = str(x) except dkim.DKIMException as x:
#self.log('DKIM: %s'%x) self.dkim_comment = str(x)
except Exception as x: #self.log('DKIM: %s'%x)
self.dkim_comment = str(x) except Exception as x:
conf.log.error("check_dkim: %s",x,exc_info=True) self.dkim_comment = str(x)
self.header_i = d.signature_fields.get(b'i') conf.log.error("check_dkim: %s",x,exc_info=True)
self.header_d = d.signature_fields.get(b'd') self.header_i = d.signature_fields.get(b'i')
if res: self.header_d = d.signature_fields.get(b'd')
#self.log('DKIM: Pass (%s)'%d.domain) if res:
self.dkim_domain = d.domain #self.log('DKIM: Pass (%s)'%d.domain)
else: self.dkim_domain = d.domain
fd,fname = tempfile.mkstemp(".dkim") else:
with os.fdopen(fd,"w+b") as fp: fd,fname = tempfile.mkstemp(".dkim")
fp.write(txt) with os.fdopen(fd,"w+b") as fp:
self.log('DKIM: Fail (saved as %s)'%fname) fp.write(txt)
return res self.log('DKIM: Fail (saved as %s)'%fname)
if res:
result = 'pass'
else:
result = 'fail'
self.arresults.append(
authres.DKIMAuthenticationResult(result=result,
header_i = self.header_i, header_d = self.header_d,
result_comment = self.dkim_comment)
)
return
def main(): def main():
configFile = '/etc/dkimpy-milter.conf' configFile = '/etc/dkimpy-milter.conf'