diff --git a/dkim/__init__.py b/dkim/__init__.py index 05df719..b2d946c 100644 --- a/dkim/__init__.py +++ b/dkim/__init__.py @@ -118,11 +118,11 @@ def hash_headers(hasher, canonicalize_headers, headers, include_headers, # once in the signature header cheaders = canonicalize_headers.canonicalize_headers( [(sigheaders[0][0], _remove(sigheaders[0][1], sig[b'b']))]) - sign_headers += [(x[0], x[1].rstrip()) for x in cheaders] - for x in sign_headers: - hasher.update(x[0]) + sign_headers += [(x, y.rstrip()) for x,y in cheaders] + for x,y in sign_headers: + hasher.update(x) hasher.update(b":") - hasher.update(x[1]) + hasher.update(y) def validate_signature_fields(sig): """Validate DKIM-Signature fields. @@ -259,10 +259,10 @@ class DKIM(object): headers = canon_policy.canonicalize_headers(self.headers) if include_headers is None: - include_headers = [x[0].lower() for x in headers] + include_headers = [x.lower() for x,y in headers] else: include_headers = [x.lower() for x in include_headers] - sign_headers = [x for x in headers if x[0].lower() in include_headers] + sign_headers = [(x,y) for x,y in headers if x.lower() in include_headers] body = canon_policy.canonicalize_body(self.body) @@ -281,10 +281,12 @@ class DKIM(object): (b'q', b"dns/txt"), (b's', selector), (b't', str(int(time.time())).encode('ascii')), - (b'h', b" : ".join(x[0] for x in sign_headers)), + (b'h', b" : ".join(x for x,y in sign_headers)), (b'bh', bodyhash), (b'b', b""), ] if x] + # record what verify should extract + self.include_headers = tuple([x.lower() for x,y in sign_headers]) sig_value = fold(b"; ".join(b"=".join(x) for x in sigfields)) dkim_header = canon_policy.canonicalize_headers([ @@ -316,7 +318,7 @@ class DKIM(object): def verify(self,dnsfunc=get_txt): - sigheaders = [x for x in self.headers if x[0].lower() == b"dkim-signature"] + sigheaders = [(x,y) for x,y in self.headers if x.lower() == b"dkim-signature"] if len(sigheaders) < 1: return False @@ -376,6 +378,7 @@ class DKIM(object): raise KeyFormatError("could not parse public key (%s): %s" % (pub[b'p'],e)) include_headers = [x.lower() for x in re.split(br"\s*:\s*", sig[b'h'])] + self.include_headers = tuple(include_headers) # address bug#644046 by including any additional From header # fields when verifying. Since there should be only one From header, # this shouldn't break any legitimate messages. This could be diff --git a/dkim/tests/data/message.mbox b/dkim/tests/data/message.mbox deleted file mode 100644 index 945c235..0000000 --- a/dkim/tests/data/message.mbox +++ /dev/null @@ -1,113 +0,0 @@ -Return-Path: -Delivered-To: kitterma-kitterman:com-scott@kitterman.com -X-Envelope-To: scott@kitterman.com -Received: (qmail 84128 invoked by uid 3013); 7 Mar 2011 19:23:23 -0000 -Delivered-To: kitterma-kitterman:com-bcc@kitterman.com -Received: (qmail 84124 invoked from network); 7 Mar 2011 19:23:23 -0000 -Received: from mailwash7.pair.com (66.39.2.7) - by raung.pair.com with SMTP; 7 Mar 2011 19:23:23 -0000 -Received: from localhost (localhost [127.0.0.1]) - by mailwash7.pair.com (Postfix) with SMTP id 55353BC0C - for ; Mon, 7 Mar 2011 14:23:23 -0500 (EST) -X-Virus-Check-By: mailwash7.pair.com -X-Spam-Check-By: mailwash7.pair.com -X-Spam-Status: No, hits=-102.4 required=3.5 tests=BAYES_00,DKIM_SIGNED,DKIM_VERIFIED,SPF_HELO_PASS,USER_IN_WHITELIST autolearn=ham version=3.002005 -X-Spam-Flag: NO -X-Spam-Level: -X-Spam-Filtered: e5ffa8d1346811c78a1c1beaefd60800 -Received: from mailout00.controlledmail.com (mailout00.controlledmail.com [72.81.252.19]) - by mailwash7.pair.com (Postfix) with ESMTP id 0CCA9BC14 - for ; Mon, 7 Mar 2011 14:23:19 -0500 (EST) -Received: from mailout00.controlledmail.com (localhost [127.0.0.1]) - by mailout00.controlledmail.com (Postfix) with ESMTP id 6D9F438C28F; - Mon, 7 Mar 2011 14:23:18 -0500 (EST) -DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=kitterman.com; - s=2007-00; t=1299525798; - bh=n0HUwGCP28PkesXBPH82Kboy8LhNFWU9zUISIpAez7M=; - h=From:To:Subject:Date:Cc:MIME-Version:Content-Type: - Content-Transfer-Encoding:Message-Id; - b=K/UUOt8lCtgjp3kSTogqBm9lY1Yax/NwZ+bKm39/WKzo5KYe3L/6RoIA/0oiDX4kO - Qut49HCV6ZUe6dY9V5qWBwLanRs1sCnObaOGMpFfs8tU4TWpDSVXaNZAqn15XVW0WH - EzOzUfVuatpa1kF4voIgSbmZHR1vN3WpRtcTBe/I= -From: Scott Kitterman -To: Kerrick Staley , - Nick Coghlan -Subject: Comments on PEP 394 draft -Date: Mon, 7 Mar 2011 14:22:57 -0500 -User-Agent: KMail/1.13.5 (Linux/2.6.35-27-generic; KDE/4.5.1; i686; ; ) -Cc: barry@python.org -MIME-Version: 1.0 -Content-Type: multipart/signed; - boundary="nextPart1746914.gtVYRJxS1r"; - protocol="application/pgp-signature"; - micalg=pgp-sha1 -Content-Transfer-Encoding: 7bit -Message-Id: <201103071423.13147.scott@kitterman.com> -X-AV-Checked: ClamAV using ClamSMTP -X-UID: 63126 -X-Length: 4427 -Status: R -X-Status: N -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - ---nextPart1746914.gtVYRJxS1r -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: quoted-printable - -I'm one of the maintainers of the packages that provide /usr/bin/python,=20 -python3, and potentially python2 in Debian and Ubuntu. I've read both your= -=20 -draft ( http://www.python.org/dev/peps/pep-0394/ ) and the thread on ptyhon- -dev. I'm writing you directly since I'm not subscribed to python-dev and=20 -that's what Barry suggested. - -I think that the PEP generally makes sense. The only comment I have is tha= -t=20 -the recommendation regarding pointing /usr/bin/python at /usr/bin/python3 i= -s=20 -far too aggressive. It will break lots of local scripts and python softwar= -e=20 -(updating distribution package repositories isn't nearly sufficient=20 -preparation for the change). I know some distributions have or will do thi= -s,=20 -but I think it is not appropriate for an upstream recommendation. If you=20 -would change: - -"For the time being, it is recommended that python should refer to python2,= -=20 -except on distributions which include only python3 in their base install, o= -r=20 -those that wish to push strongly for migration of user scripts to Python 3." - -to - -"For the time being, it is recommended that python should refer to python2." - -then it would be something Debian would likely (I'm not the only maintainer= -)=20 -support. Given that the previous position was that /usr/bin/python would=20 -always refer to python2, just establishing that it should change as some po= -int=20 -is a step forward. I don't think pushing harder than that will be worth th= -e=20 -added controversy associated with being more aggressive. - -Scott K - ---nextPart1746914.gtVYRJxS1r -Content-Type: application/pgp-signature; name=signature.asc -Content-Description: This is a digitally signed message part. - ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.10 (GNU/Linux) - -iEYEABECAAYFAk11MJQACgkQHajaM93NaGpohwCfZNhmnoyq51jlCJ/nJ1dpbLWc -llUAn0y8pceuESDSfNLHW0DADEygs4aU -=S7uo ------END PGP SIGNATURE----- - ---nextPart1746914.gtVYRJxS1r-- - diff --git a/dkim/tests/data/test_extra.message b/dkim/tests/data/test_extra.message new file mode 100644 index 0000000..a514ea3 --- /dev/null +++ b/dkim/tests/data/test_extra.message @@ -0,0 +1,9 @@ +Received: from zulu +Received: from localhost +Message-ID: +Date: Mon, 01 Jan 2011 01:02:03 +0400 +From: Test User +To: somebody@example.com +Subject: Testing + +This is a test message. diff --git a/dkim/tests/test_dkim.py b/dkim/tests/test_dkim.py index f676e18..be32872 100644 --- a/dkim/tests/test_dkim.py +++ b/dkim/tests/test_dkim.py @@ -133,13 +133,18 @@ b/mPfjC0QJTocVBq6Za/PlzfV+Py92VaCak19F4WrbVTK5Gg5tW220MCAwEAAQ==""" def test_extra_headers(self): # # extra headers above From caused failure - message = read_test_data("message.mbox") + message = read_test_data("test_extra.message") for header_algo in (b"simple", b"relaxed"): for body_algo in (b"simple", b"relaxed"): - sig = dkim.sign( - message, b"test", b"example.com", self.key, + d = dkim.DKIM(message) + sig = d.sign(b"test", b"example.com", self.key, canonicalize=(header_algo, body_algo)) - res = dkim.verify(sig + message, dnsfunc=self.dnsfunc) + dv = dkim.DKIM(sig + message) + res = dv.verify(dnsfunc=self.dnsfunc) + self.assertEquals(d.include_headers,dv.include_headers) + s = dkim.select_headers(d.headers,d.include_headers) + sv = dkim.select_headers(dv.headers,dv.include_headers) + self.assertEquals(s,sv) self.assertTrue(res) def test_multiple_from_fails(self):