def test_verifies(self): # A message verifies after being signed. sig_lines = dkim.arc_sign(self.message, b"test", b"example.com", self.key, b"test.domain: none", dkim.CV_None) (cv, res, reason) = dkim.arc_verify(b''.join(sig_lines) + self.message, dnsfunc=self.dnsfunc) self.assertEquals(cv, dkim.CV_Pass)
def main(): if sys.version_info[0] >= 3: # Make sys.stdin a binary stream. sys.stdin = sys.stdin.detach() message = sys.stdin.read() cv, results, comment = dkim.arc_verify(message) print(cv.decode('utf8'), end='')
def test_fails_h_in_as(self): # ARC 4.1.3, h= not allowed in AS self.maxDiff = None sig_lines = [ b'ARC-Seal: i=1; cv=none; a=rsa-sha256; d=example.com; s=test; t=12345;\r\n h=message-id : date : from : to : subject : from;\r\n b=mIurIuLl0/wAxWhA4DBS1wsUE15IBnmJ7o3sH15hIuesdD4smz1cCLXVhRtxQE\r\n rVtVLv4OgNCgdFsB5zbSOUao2bSSYP6y0BGyCWvr+hU4tai5axIc1Kfwbtv/0Mqg\r\n waiGJPreOAAeZOJ4vPfdaAbSXlN5MI4PHW89U82FSIBKI=\r\n', b'ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;\r\n d=example.com; s=test; t=12345; h=message-id :\r\n date : from : to : subject : from;\r\n bh=wE7NXSkgnx9PGiavN4OZhJztvkqPDlemV3OGuEnLwNo=;\r\n b=a0f6qc3k9eECTSR155A0TQS+LjqPFWfI/brQBA83EUz00SNxj\r\n 1wmWykvs1hhBVeM0r1kEQc6CKbzRYaBNSiFj4q8JBpRIujLz1qL\r\n yGmPuAI6ddu/Z/1hQxgpVcp/odmI1UMV2R+d+yQ7tUp3EQxF/GY\r\n Nt22rV4rNmDmANZVqJ90=\r\n', b'ARC-Authentication-Results: i=1; lists.example.org; arc=none;\r\n spf=pass [email protected];\r\n dkim=pass (1024-bit key) [email protected];\r\n dmarc=pass\r\n' ] (cv, res, reason) = dkim.arc_verify(b''.join(sig_lines) + self.message, dnsfunc=self.dnsfunc) self.assertEqual(cv, dkim.CV_Fail)
def is_whitelisted_internal(body, whitelist=[]): """This is a special method that is used by the mail parsing script to figure out of any of the callbacks must be triggered or not. This hook will not be called for any other feature. """ # Let's make sure no spoofing is happening. if not (dkim_verify(body) or arc_verify(body)): print "No DKIM" return False parsed = message_from_string(body) from_address = parsed["From"] _, address = parseaddr(from_address) return address in whitelist
def main(): if sys.version_info[0] >= 3: # Make sys.stdin a binary stream. sys.stdin = sys.stdin.detach() message = sys.stdin.read() verbose = '-v' in sys.argv if verbose: logging.basicConfig(level=10) a = dkim.ARC(message) cv, results, comment = a.verify() else: cv, results, comment = dkim.arc_verify(message) print("arc verification: cv=%s %s" % (cv, comment)) if verbose: print(repr(results))
def test_signs_and_verifies(self): # A message verifies after being signed self.maxDiff = None sig_lines = dkim.arc_sign(self.message, b"test", b"example.com", self.key, b"lists.example.org", timestamp="12345") expected_sig = [ b'ARC-Seal: i=1; cv=none; a=rsa-sha256; d=example.com; s=test; t=12345;\r\n b=MBw2+L1/4PuYWJlt1tZlDtbOvyfbyH2t2N6DinFV/BIaB2LqbDKTYjXXk9HuuK1/qEkTd\r\n TxCYScIrtVO7pFbGiSawMuLatVzHNCqTURa1zBTXr2mKW1hgdmrtMMUcMVCYxr1AJpu6IYX\r\n VMIoOAn7tIDdO0VLokK6FnIXTWEAplQ=\r\n', b'ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;\r\n d=example.com; s=test; t=12345; h=message-id : date : from : to :\r\n subject : from; bh=wE7NXSkgnx9PGiavN4OZhJztvkqPDlemV3OGuEnLwNo=;\r\n b=a0f6qc3k9eECTSR155A0TQS+LjqPFWfI/brQBA83EUz00SNxj1wmWykvs1hhBVeM0r1kE\r\n Qc6CKbzRYaBNSiFj4q8JBpRIujLz1qLyGmPuAI6ddu/Z/1hQxgpVcp/odmI1UMV2R+d+yQ7\r\n tUp3EQxF/GYNt22rV4rNmDmANZVqJ90=\r\n', b'ARC-Authentication-Results: i=1; lists.example.org; arc=none;\r\n spf=pass [email protected];\r\n dkim=pass (1024-bit key) [email protected];\r\n dmarc=pass\r\n' ] self.assertEqual(expected_sig, sig_lines) (cv, res, reason) = dkim.arc_verify(b''.join(sig_lines) + self.message, dnsfunc=self.dnsfunc) self.assertEqual(cv, dkim.CV_Pass)
import dkim if len(sys.argv) != 4: print("Usage: arcverifytest.py messagefile dnsport verbose", file=sys.stderr) sys.exit(1) def arctestdns(name): try: q = DNSRecord.question(name.decode("utf-8"), "TXT") a = q.send("localhost", int(sys.argv[2])) r = DNSRecord.parse(a) if not r.get_a().rdata: return None return "".join([x.decode('utf-8') for x in r.get_a().rdata.data]) except: return None if (sys.argv[3].lower() == 'true'): logging.basicConfig(level=10) with open(sys.argv[1], 'rb') as mf: cv, results, comment = dkim.arc_verify(mf.read(), dnsfunc=arctestdns) if cv == None: cv = b'' sys.stdout.write(cv.decode("utf-8"))
def _email_header_validation_using_dkimarc_function( self, event, *args, **kwargs): """Function: Analyzes the DKIM and ARC headers for an RFC822 formatted email.""" try: # Get the function parameters: email_header_validation_target_email = kwargs.get( "email_header_validation_target_email") # text incident_id = kwargs.get('incident_id') # number attachment_id = kwargs.get('attachment_id') # number artifact_id = kwargs.get('artifact_id') # number if email_header_validation_target_email is None and incident_id is None: raise FunctionError( 'Either an RFC822 email must be provided or an incident id and attachment_id ' 'or artifact_id must be provided') log = logging.getLogger(__name__) log.info("email_header_validation_target_email: %s", email_header_validation_target_email) yield StatusMessage("Analyzing email headers") # Initialize DKIM object from string or attachment and check for DKIM header if email_header_validation_target_email: target_email = email_header_validation_target_email else: client = self.rest_client() target_email = get_content(client, incident_id, attachment_id, artifact_id) dkim_email = dkim.DKIM(target_email) dkim_header_exists = b"dkim-signature" in [ header[0].lower() for header in dkim_email.headers ] # Do header analysis dkim_results = dkim.dkim_verify(target_email) arc_results = dkim.arc_verify(target_email) if arc_results == 'success': arc_results = 'Validation successful' # Form DKIM results statement if dkim_header_exists: if dkim_results: dkim_message = 'Validation successful' else: dkim_message = 'Most recent DKIM-Message-Signature did not validate' else: dkim_message = 'Message is not DKIM signed' results = { "dkim_verify": dkim_results, "arc_verify": arc_results[0] == 'pass', "dkim_message": dkim_message, "arc_message": arc_results[2] } # Produce a FunctionResult with the results yield FunctionResult(results) except Exception: yield FunctionError()
reason=spf_result[1]) results_list += [spf_res] # Write Received-SPF header (must be added ABOVE Received: lines for this server) sys.stdout.write( 'Received-SPF: {0} ({1}) receiver={2}; client-ip={3}; helo={4}; envelope-from={5};' .format(spf_result[0], spf_result[1], AUTHSERV_HOSTNAME, up_srv_ip, up_srv_helo, sender_address).encode("utf-8") + linesep) ### ARC SIGNATURE #import logging #logging.basicConfig(level=10) try: cv = dkim.CV_None.decode("ascii") if re.search(b'arc-seal', message, re.IGNORECASE): arc_vrfy = dkim.arc_verify(message) cv = arc_vrfy[0].decode("ascii") arc_res = authres.arc.ARCAuthenticationResult(result=cv) results_list += [arc_res] except Exception as e: sys.stdout.write("X-MTA-Error: qmail-arc failed ARC verifying ({}).". format(e).encode("utf-8") + linesep) #raise pass try: ### PREP AUTH RESULT auth_res = authres.AuthenticationResultsHeader(authserv_id=AUTHSERV_ID, results=results_list)