Merge lp:~maxb/launchpad/use-hashlib into lp:launchpad

Proposed by Max Bowsher
Status: Merged
Approved by: Graham Binns
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~maxb/launchpad/use-hashlib
Merge into: lp:launchpad
Diff against target: 902 lines (+110/-178)
27 files modified
lib/canonical/base.py (+3/-3)
lib/canonical/buildd/slave.py (+3/-3)
lib/canonical/launchpad/database/emailaddress.py (+3/-2)
lib/canonical/launchpad/database/temporaryblobstorage.py (+4/-3)
lib/canonical/launchpad/helpers.py (+4/-3)
lib/canonical/launchpad/mailman/monkeypatches/lphandler.py (+3/-2)
lib/canonical/launchpad/scripts/logger.py (+4/-2)
lib/canonical/launchpad/webapp/authentication.py (+3/-3)
lib/canonical/launchpad/webapp/login.py (+5/-4)
lib/canonical/launchpad/webapp/tests/test_encryptor.py (+10/-5)
lib/canonical/librarian/client.py (+7/-6)
lib/canonical/librarian/ftests/test_storage.py (+5/-4)
lib/canonical/librarian/storage.py (+3/-4)
lib/canonical/librarian/tests/test_storage.py (+0/-1)
lib/canonical/librarian/utils.py (+3/-3)
lib/lp/archivepublisher/library.py (+4/-2)
lib/lp/archivepublisher/publishing.py (+8/-34)
lib/lp/archivepublisher/tests/test_librarianwrapper.py (+2/-2)
lib/lp/archivepublisher/tests/test_pool.py (+4/-4)
lib/lp/archivepublisher/tests/test_publisher.py (+2/-66)
lib/lp/archiveuploader/nascentuploadfile.py (+3/-4)
lib/lp/services/mail/sendmail.py (+7/-4)
lib/lp/soyuz/doc/soyuz-upload.txt.disabled (+2/-2)
lib/lp/soyuz/scripts/ftpmaster.py (+2/-2)
lib/lp/soyuz/scripts/gina/library.py (+5/-2)
lib/lp/soyuz/scripts/queue.py (+3/-3)
lib/lp/soyuz/scripts/tests/test_queue.py (+8/-5)
To merge this branch: bzr merge lp:~maxb/launchpad/use-hashlib
Reviewer Review Type Date Requested Status
Graham Binns (community) code Approve
Review via email: mp+18894@code.launchpad.net

Commit message

Switch from using sha and md5 to hashlib. Also use hashlib.sha256 instead of the python-apt implementation.

To post a comment you must log in.
Revision history for this message
Max Bowsher (maxb) wrote :

Python 2.5 introduced the hashlib module as the new home of hash functions.

Python 2.6 deprecated the old md5 and sha modules.

To help in clearing the way for a future migration to Python 2.6, here is a branch substituting the use of hashlib for md5 and sha. It also replaces the usage of python-apt's sha256 function (formerly necessary since Python 2.4 offered no sha256 implementation) with hashlib.sha256, allowing a removal of compatibility code.

These changes were originally authored by Barry during the Python 2.5/2.6 sprint, and left on a branch including Python-2.6-only changes at the end of the sprint. I've disentangled them for landing on mainline.

Revision history for this message
Graham Binns (gmb) wrote :

Hi Max,

Great branch, and I'm happy for it to land.

review: Approve (code)
Revision history for this message
Max Bowsher (maxb) wrote :

This somehow ended up with this in ec2test, despite working fine in plain old make check locally:

Error in test testAptSHA256 (lp.archivepublisher.tests.test_publisher.TestPublisher)
Traceback (most recent call last):
  File "/usr/lib/python2.5/unittest.py", line 260, in run
    testMethod()
  File "/var/launchpad/test/lib/lp/archivepublisher/tests/test_publisher.py", line 804, in testAptSHA256
    text, file = _getSHA256("foobar")
  File "/var/launchpad/test/lib/lp/archivepublisher/tests/test_publisher.py", line 797, in _getSHA256
    file = hashlib.sha256(open(test_filepath)).hexdigest()
TypeError: sha256() argument 1 must be string or read-only buffer, not file

Back to "Work in progress" whilst I try to figure out why.

Revision history for this message
Max Bowsher (maxb) wrote :

" This test only runs on Ubuntu/hardy systems. "

Well, meh.

Revision history for this message
Max Bowsher (maxb) wrote :

It turns out the entire test is no longer relevant, because it tests for the presence of a bug in apt_pkg.sha256sum, which the first revision in this branch removes all uses of. Hence, the fix is to simply delete the test.

Incremental diff: just the deletion of the entire method lp.archivepublisher.tests.test_publisher.TestPublisher.testAptSHA256

This is ready for re-review and landing now.

Revision history for this message
Graham Binns (gmb) wrote :

Approved after re-review.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/base.py'
--- lib/canonical/base.py 2009-06-25 05:30:52 +0000
+++ lib/canonical/base.py 2010-02-10 00:32:23 +0000
@@ -33,8 +33,8 @@
33 This method is useful for shrinking sha1 and md5 hashes, but keeping33 This method is useful for shrinking sha1 and md5 hashes, but keeping
34 them in simple ASCII suitable for URL's etc.34 them in simple ASCII suitable for URL's etc.
3535
36 >>> import sha, md536 >>> import hashlib
37 >>> s = sha.new('foo').hexdigest()37 >>> s = hashlib.sha1('foo').hexdigest()
38 >>> s38 >>> s
39 '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'39 '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
40 >>> i = long(s, 16)40 >>> i = long(s, 16)
@@ -42,7 +42,7 @@
42 68123873083688143418383284816464454849230703155L42 68123873083688143418383284816464454849230703155L
43 >>> base(i, 62)43 >>> base(i, 62)
44 '1HyPQr2xj1nmnkQXBCJXUdQoy5l'44 '1HyPQr2xj1nmnkQXBCJXUdQoy5l'
45 >>> base(int(md5.new('foo').hexdigest(), 16), 62)45 >>> base(int(hashlib.md5('foo').hexdigest(), 16), 62)
46 '5fX649Stem9fET0lD46zVe'46 '5fX649Stem9fET0lD46zVe'
4747
48 A sha1 hash can be compressed to 27 characters or less48 A sha1 hash can be compressed to 27 characters or less
4949
=== modified file 'lib/canonical/buildd/slave.py'
--- lib/canonical/buildd/slave.py 2010-01-14 02:36:36 +0000
+++ lib/canonical/buildd/slave.py 2010-02-10 00:32:23 +0000
@@ -8,9 +8,9 @@
88
9__metaclass__ = type9__metaclass__ = type
1010
11import hashlib
11import os12import os
12import re13import re
13import sha
14import urllib214import urllib2
15import xmlrpclib15import xmlrpclib
1616
@@ -301,7 +301,7 @@
301 else:301 else:
302 of = open(self.cachePath(sha1sum), "w")302 of = open(self.cachePath(sha1sum), "w")
303 # Upped for great justice to 256k303 # Upped for great justice to 256k
304 check_sum = sha.sha()304 check_sum = hashlib.sha1()
305 for chunk in iter(lambda: f.read(256*1024), ''):305 for chunk in iter(lambda: f.read(256*1024), ''):
306 of.write(chunk)306 of.write(chunk)
307 check_sum.update(chunk)307 check_sum.update(chunk)
@@ -316,7 +316,7 @@
316316
317 def storeFile(self, content):317 def storeFile(self, content):
318 """Take the provided content and store it in the file cache."""318 """Take the provided content and store it in the file cache."""
319 sha1sum = sha.sha(content).hexdigest()319 sha1sum = hashlib.sha1(content).hexdigest()
320 present, info = self.ensurePresent(sha1sum)320 present, info = self.ensurePresent(sha1sum)
321 if present:321 if present:
322 return sha1sum322 return sha1sum
323323
=== modified file 'lib/canonical/launchpad/database/emailaddress.py'
--- lib/canonical/launchpad/database/emailaddress.py 2009-06-25 05:30:52 +0000
+++ lib/canonical/launchpad/database/emailaddress.py 2010-02-10 00:32:23 +0000
@@ -11,8 +11,9 @@
11 'UndeletableEmailAddress',11 'UndeletableEmailAddress',
12 ]12 ]
1313
14
15import hashlib
14import operator16import operator
15import sha
1617
17from zope.interface import implements18from zope.interface import implements
1819
@@ -80,7 +81,7 @@
80 @property81 @property
81 def rdf_sha1(self):82 def rdf_sha1(self):
82 """See `IEmailAddress`."""83 """See `IEmailAddress`."""
83 return sha.new('mailto:' + self.email).hexdigest().upper()84 return hashlib.sha1('mailto:' + self.email).hexdigest().upper()
8485
8586
86class EmailAddressSet:87class EmailAddressSet:
8788
=== modified file 'lib/canonical/launchpad/database/temporaryblobstorage.py'
--- lib/canonical/launchpad/database/temporaryblobstorage.py 2009-06-25 05:30:52 +0000
+++ lib/canonical/launchpad/database/temporaryblobstorage.py 2010-02-10 00:32:23 +0000
@@ -10,13 +10,14 @@
10 'TemporaryStorageManager',10 'TemporaryStorageManager',
11 ]11 ]
1212
13from cStringIO import StringIO13
14from datetime import timedelta, datetime
15import random14import random
16import sha
17import time15import time
18import thread16import thread
1917
18from cStringIO import StringIO
19from datetime import timedelta, datetime
20
20from pytz import utc21from pytz import utc
21from sqlobject import StringCol, ForeignKey22from sqlobject import StringCol, ForeignKey
22from zope.component import getUtility23from zope.component import getUtility
2324
=== modified file 'lib/canonical/launchpad/helpers.py'
--- lib/canonical/launchpad/helpers.py 2009-12-10 13:20:12 +0000
+++ lib/canonical/launchpad/helpers.py 2010-02-10 00:32:23 +0000
@@ -10,16 +10,17 @@
1010
11__metaclass__ = type11__metaclass__ = type
1212
13import subprocess13import hashlib
14import gettextpo14import gettextpo
15import os15import os
16import random16import random
17import re17import re
18import subprocess
18import tarfile19import tarfile
19import warnings20import warnings
21
20from StringIO import StringIO22from StringIO import StringIO
21from difflib import unified_diff23from difflib import unified_diff
22import sha
2324
24from zope.component import getUtility25from zope.component import getUtility
25from zope.security.interfaces import ForbiddenAttribute26from zope.security.interfaces import ForbiddenAttribute
@@ -462,7 +463,7 @@
462 """463 """
463 return '%s.msg' % (464 return '%s.msg' % (
464 canonical.base.base(465 canonical.base.base(
465 long(sha.new(message_id).hexdigest(), 16), 62))466 long(hashlib.sha1(message_id).hexdigest(), 16), 62))
466467
467468
468def intOrZero(value):469def intOrZero(value):
469470
=== modified file 'lib/canonical/launchpad/mailman/monkeypatches/lphandler.py'
--- lib/canonical/launchpad/mailman/monkeypatches/lphandler.py 2009-06-25 05:30:52 +0000
+++ lib/canonical/launchpad/mailman/monkeypatches/lphandler.py 2010-02-10 00:32:23 +0000
@@ -3,7 +3,8 @@
33
4"""A global pipeline handler for determining Launchpad membership."""4"""A global pipeline handler for determining Launchpad membership."""
55
6import sha6
7import hashlib
7import xmlrpclib8import xmlrpclib
89
9from Mailman import Errors10from Mailman import Errors
@@ -24,7 +25,7 @@
24 secret = msg['x-launchpad-hash']25 secret = msg['x-launchpad-hash']
25 message_id = msg['message-id']26 message_id = msg['message-id']
26 if secret and message_id:27 if secret and message_id:
27 hash = sha.new(mm_cfg.LAUNCHPAD_SHARED_SECRET)28 hash = hashlib.sha1(mm_cfg.LAUNCHPAD_SHARED_SECRET)
28 hash.update(message_id)29 hash.update(message_id)
29 if secret == hash.hexdigest():30 if secret == hash.hexdigest():
30 # Since this message is coming from Launchpad, pre-approve it.31 # Since this message is coming from Launchpad, pre-approve it.
3132
=== modified file 'lib/canonical/launchpad/scripts/logger.py'
--- lib/canonical/launchpad/scripts/logger.py 2009-10-16 18:07:01 +0000
+++ lib/canonical/launchpad/scripts/logger.py 2010-02-10 00:32:23 +0000
@@ -25,12 +25,14 @@
25 'DEBUG6', 'DEBUG7', 'DEBUG8', 'DEBUG9'25 'DEBUG6', 'DEBUG7', 'DEBUG8', 'DEBUG9'
26 ]26 ]
2727
28
29import hashlib
28import logging30import logging
29import re31import re
30import sha
31import sys32import sys
32import traceback33import traceback
33import time34import time
35
34from optparse import OptionParser36from optparse import OptionParser
35from cStringIO import StringIO37from cStringIO import StringIO
36from datetime import datetime, timedelta38from datetime import datetime, timedelta
@@ -168,7 +170,7 @@
168 expiry = datetime.now().replace(tzinfo=utc) + timedelta(days=90)170 expiry = datetime.now().replace(tzinfo=utc) + timedelta(days=90)
169 try:171 try:
170 filename = base(172 filename = base(
171 long(sha.new(traceback).hexdigest(),16), 62173 long(hashlib.sha1(traceback).hexdigest(),16), 62
172 ) + '.txt'174 ) + '.txt'
173 url = librarian.remoteAddFile(175 url = librarian.remoteAddFile(
174 filename, len(traceback), StringIO(traceback),176 filename, len(traceback), StringIO(traceback),
175177
=== modified file 'lib/canonical/launchpad/webapp/authentication.py'
--- lib/canonical/launchpad/webapp/authentication.py 2009-10-20 22:13:21 +0000
+++ lib/canonical/launchpad/webapp/authentication.py 2010-02-10 00:32:23 +0000
@@ -14,8 +14,8 @@
1414
1515
16import binascii16import binascii
17import hashlib
17import random18import random
18import sha
1919
20from contrib.oauth import OAuthRequest20from contrib.oauth import OAuthRequest
2121
@@ -178,7 +178,7 @@
178 plaintext = str(plaintext)178 plaintext = str(plaintext)
179 if salt is None:179 if salt is None:
180 salt = self.generate_salt()180 salt = self.generate_salt()
181 v = binascii.b2a_base64(sha.new(plaintext + salt).digest() + salt)181 v = binascii.b2a_base64(hashlib.sha1(plaintext + salt).digest() + salt)
182 return v[:-1]182 return v[:-1]
183183
184 def validate(self, plaintext, encrypted):184 def validate(self, plaintext, encrypted):
@@ -191,7 +191,7 @@
191 return False191 return False
192 salt = ref[20:]192 salt = ref[20:]
193 v = binascii.b2a_base64(193 v = binascii.b2a_base64(
194 sha.new(plaintext + salt).digest() + salt)[:-1]194 hashlib.sha1(plaintext + salt).digest() + salt)[:-1]
195 pw1 = (v or '').strip()195 pw1 = (v or '').strip()
196 pw2 = (encrypted or '').strip()196 pw2 = (encrypted or '').strip()
197 return pw1 == pw2197 return pw1 == pw2
198198
=== modified file 'lib/canonical/launchpad/webapp/login.py'
--- lib/canonical/launchpad/webapp/login.py 2010-01-14 13:25:34 +0000
+++ lib/canonical/launchpad/webapp/login.py 2010-02-10 00:32:23 +0000
@@ -6,10 +6,11 @@
6__metaclass__ = type6__metaclass__ = type
77
8import cgi8import cgi
9import hashlib
10import random
9import urllib11import urllib
12
10from datetime import datetime, timedelta13from datetime import datetime, timedelta
11import md5
12import random
1314
14from BeautifulSoup import UnicodeDammit15from BeautifulSoup import UnicodeDammit
1516
@@ -162,7 +163,7 @@
162 expected = self.request.form.get(self.captcha_hash)163 expected = self.request.form.get(self.captcha_hash)
163 submitted = self.request.form.get(self.captcha_submission)164 submitted = self.request.form.get(self.captcha_submission)
164 if expected is not None and submitted is not None:165 if expected is not None and submitted is not None:
165 return md5.new(submitted).hexdigest() == expected166 return hashlib.md5(submitted).hexdigest() == expected
166 return False167 return False
167168
168 @cachedproperty169 @cachedproperty
@@ -182,7 +183,7 @@
182183
183 The hash is the value we put in the form for later comparison.184 The hash is the value we put in the form for later comparison.
184 """185 """
185 return md5.new(str(self.captcha_answer)).hexdigest()186 return hashlib.md5(str(self.captcha_answer)).hexdigest()
186187
187 @property188 @property
188 def captcha_problem(self):189 def captcha_problem(self):
189190
=== modified file 'lib/canonical/launchpad/webapp/tests/test_encryptor.py'
--- lib/canonical/launchpad/webapp/tests/test_encryptor.py 2009-06-25 05:30:52 +0000
+++ lib/canonical/launchpad/webapp/tests/test_encryptor.py 2010-02-10 00:32:23 +0000
@@ -3,15 +3,19 @@
33
4__metaclass__ = type4__metaclass__ = type
55
6
7import binascii
8import hashlib
6import unittest9import unittest
7import sha10
8import binascii
9from zope.component import getUtility11from zope.component import getUtility
10from zope.app.testing import ztapi12from zope.app.testing import ztapi
11from zope.app.testing.placelesssetup import PlacelessSetup13from zope.app.testing.placelesssetup import PlacelessSetup
14
12from canonical.launchpad.webapp.authentication import SSHADigestEncryptor15from canonical.launchpad.webapp.authentication import SSHADigestEncryptor
13from canonical.launchpad.interfaces import IPasswordEncryptor16from canonical.launchpad.interfaces import IPasswordEncryptor
1417
18
15class TestSSHADigestEncryptor(PlacelessSetup, unittest.TestCase):19class TestSSHADigestEncryptor(PlacelessSetup, unittest.TestCase):
1620
17 def setUp(self):21 def setUp(self):
@@ -26,7 +30,7 @@
26 self.failIfEqual(encrypted1, encrypted2)30 self.failIfEqual(encrypted1, encrypted2)
27 salt = encrypted1[20:]31 salt = encrypted1[20:]
28 v = binascii.b2a_base64(32 v = binascii.b2a_base64(
29 sha.new('motorhead' + salt).digest() + salt33 hashlib.sha1('motorhead' + salt).digest() + salt
30 )[:-1]34 )[:-1]
31 return (v == encrypted1)35 return (v == encrypted1)
3236
@@ -41,8 +45,9 @@
41 encrypted2 = encryptor.encrypt(u'motorhead')45 encrypted2 = encryptor.encrypt(u'motorhead')
42 self.failIfEqual(encrypted1, encrypted2)46 self.failIfEqual(encrypted1, encrypted2)
43 salt = encrypted1[20:]47 salt = encrypted1[20:]
44 v = binascii.b2a_base64(sha.new('motorhead' + salt).digest() + salt)[:-1]48 v = binascii.b2a_base64(
45 return (v == encrypted1)49 hashlib.sha1('motorhead' + salt).digest() + salt)[:-1]
50 return v == encrypted1
4651
47 def test_unicode_validate(self):52 def test_unicode_validate(self):
48 encryptor = getUtility(IPasswordEncryptor)53 encryptor = getUtility(IPasswordEncryptor)
4954
=== modified file 'lib/canonical/librarian/client.py'
--- lib/canonical/librarian/client.py 2010-01-11 18:06:23 +0000
+++ lib/canonical/librarian/client.py 2010-02-10 00:32:23 +0000
@@ -10,16 +10,17 @@
10 'RestrictedLibrarianClient',10 'RestrictedLibrarianClient',
11 ]11 ]
1212
13import md513
14import hashlib
14import re15import re
15import sha
16import socket16import socket
17from socket import SOCK_STREAM, AF_INET
18from select import select
19import time17import time
20import threading18import threading
21import urllib19import urllib
22import urllib220import urllib2
21
22from select import select
23from socket import SOCK_STREAM, AF_INET
23from urlparse import urljoin24from urlparse import urljoin
2425
25from storm.store import Store26from storm.store import Store
@@ -130,8 +131,8 @@
130 self._sendLine('')131 self._sendLine('')
131132
132 # Prepare to the upload the file133 # Prepare to the upload the file
133 shaDigester = sha.sha()134 shaDigester = hashlib.sha1()
134 md5Digester = md5.md5()135 md5Digester = hashlib.md5()
135 bytesWritten = 0136 bytesWritten = 0
136137
137 # Read in and upload the file 64kb at a time, by using the two-arg138 # Read in and upload the file 64kb at a time, by using the two-arg
138139
=== modified file 'lib/canonical/librarian/ftests/test_storage.py'
--- lib/canonical/librarian/ftests/test_storage.py 2009-06-25 05:30:52 +0000
+++ lib/canonical/librarian/ftests/test_storage.py 2010-02-10 00:32:23 +0000
@@ -1,7 +1,7 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the1# Copyright 2009 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4import sha4import hashlib
5import shutil5import shutil
6import tempfile6import tempfile
7import unittest7import unittest
@@ -13,6 +13,7 @@
13from canonical.launchpad.database import LibraryFileContent, LibraryFileAlias13from canonical.launchpad.database import LibraryFileContent, LibraryFileAlias
14from canonical.testing import LaunchpadZopelessLayer14from canonical.testing import LaunchpadZopelessLayer
1515
16
16class LibrarianStorageDBTests(unittest.TestCase):17class LibrarianStorageDBTests(unittest.TestCase):
17 layer = LaunchpadZopelessLayer18 layer = LaunchpadZopelessLayer
1819
@@ -26,7 +27,7 @@
2627
27 def test_addFile(self):28 def test_addFile(self):
28 data = 'data ' * 5029 data = 'data ' * 50
29 digest = sha.sha(data).hexdigest()30 digest = hashlib.sha1(data).hexdigest()
30 newfile = self.storage.startAddFile('file1', len(data))31 newfile = self.storage.startAddFile('file1', len(data))
31 newfile.srcDigest = digest32 newfile.srcDigest = digest
32 newfile.append(data)33 newfile.append(data)
@@ -36,7 +37,7 @@
36 def test_addFiles_identical(self):37 def test_addFiles_identical(self):
37 # Start adding two files with identical data38 # Start adding two files with identical data
38 data = 'data ' * 500039 data = 'data ' * 5000
39 digest = sha.sha(data).hexdigest()40 digest = hashlib.sha1(data).hexdigest()
40 newfile1 = self.storage.startAddFile('file1', len(data))41 newfile1 = self.storage.startAddFile('file1', len(data))
41 newfile2 = self.storage.startAddFile('file2', len(data))42 newfile2 = self.storage.startAddFile('file2', len(data))
42 newfile1.append(data)43 newfile1.append(data)
@@ -63,7 +64,7 @@
63 def test_alias(self):64 def test_alias(self):
64 # Add a file (and so also add an alias)65 # Add a file (and so also add an alias)
65 data = 'data ' * 5066 data = 'data ' * 50
66 digest = sha.sha(data).hexdigest()67 digest = hashlib.sha1(data).hexdigest()
67 newfile = self.storage.startAddFile('file1', len(data))68 newfile = self.storage.startAddFile('file1', len(data))
68 newfile.mimetype = 'text/unknown'69 newfile.mimetype = 'text/unknown'
69 newfile.append(data)70 newfile.append(data)
7071
=== modified file 'lib/canonical/librarian/storage.py'
--- lib/canonical/librarian/storage.py 2009-07-17 00:26:05 +0000
+++ lib/canonical/librarian/storage.py 2010-02-10 00:32:23 +0000
@@ -4,9 +4,8 @@
4__metaclass__ = type4__metaclass__ = type
55
6import os6import os
7import md5
8import sha
9import errno7import errno
8import hashlib
10import shutil9import shutil
11import tempfile10import tempfile
1211
@@ -89,8 +88,8 @@
89 tmpfile, tmpfilepath = tempfile.mkstemp(dir=self.storage.incoming)88 tmpfile, tmpfilepath = tempfile.mkstemp(dir=self.storage.incoming)
90 self.tmpfile = os.fdopen(tmpfile, 'w')89 self.tmpfile = os.fdopen(tmpfile, 'w')
91 self.tmpfilepath = tmpfilepath90 self.tmpfilepath = tmpfilepath
92 self.shaDigester = sha.new()91 self.shaDigester = hashlib.sha1()
93 self.md5Digester = md5.new()92 self.md5Digester = hashlib.md5()
9493
95 def append(self, data):94 def append(self, data):
96 self.tmpfile.write(data)95 self.tmpfile.write(data)
9796
=== modified file 'lib/canonical/librarian/tests/test_storage.py'
--- lib/canonical/librarian/tests/test_storage.py 2009-07-19 04:41:14 +0000
+++ lib/canonical/librarian/tests/test_storage.py 2010-02-10 00:32:23 +0000
@@ -2,7 +2,6 @@
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4import os4import os
5import sha
6import shutil5import shutil
7import tempfile6import tempfile
8import unittest7import unittest
98
=== modified file 'lib/canonical/librarian/utils.py'
--- lib/canonical/librarian/utils.py 2009-06-25 05:30:52 +0000
+++ lib/canonical/librarian/utils.py 2010-02-10 00:32:23 +0000
@@ -2,7 +2,6 @@
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4__metaclass__ = type4__metaclass__ = type
5
6__all__ = [5__all__ = [
7 'copy_and_close',6 'copy_and_close',
8 'filechunks',7 'filechunks',
@@ -10,7 +9,8 @@
10 'sha1_from_path',9 'sha1_from_path',
11 ]10 ]
1211
13import sha12
13import hashlib
1414
15MEGABYTE = 1024*102415MEGABYTE = 1024*1024
1616
@@ -39,7 +39,7 @@
39def sha1_from_path(path):39def sha1_from_path(path):
40 """Return the hexdigest SHA1 for the contents of the path."""40 """Return the hexdigest SHA1 for the contents of the path."""
41 the_file = open(path)41 the_file = open(path)
42 the_hash = sha.new()42 the_hash = hashlib.sha1()
4343
44 for chunk in filechunks(the_file):44 for chunk in filechunks(the_file):
45 the_hash.update(chunk)45 the_hash.update(chunk)
4646
=== modified file 'lib/lp/archivepublisher/library.py'
--- lib/lp/archivepublisher/library.py 2009-06-24 23:28:16 +0000
+++ lib/lp/archivepublisher/library.py 2010-02-10 00:32:23 +0000
@@ -113,7 +113,9 @@
113 return os.link(path, archive)113 return os.link(path, archive)
114114
115if __name__ == '__main__':115if __name__ == '__main__':
116 import os, sys, sha116 import hashlib
117 import os
118 import sys
117119
118 lib = Librarian('localhost', 9090, 8000, "/tmp/cache")120 lib = Librarian('localhost', 9090, 8000, "/tmp/cache")
119121
@@ -124,7 +126,7 @@
124 lib.upload_port)126 lib.upload_port)
125 fileobj = open(name, 'rb')127 fileobj = open(name, 'rb')
126 size = os.stat(name).st_size128 size = os.stat(name).st_size
127 digest = sha.sha(open(name, 'rb').read()).hexdigest()129 digest = hashlib.sha1(open(name, 'rb').read()).hexdigest()
128130
129 fileid, filealias = lib.addFile(name, size, fileobj,131 fileid, filealias = lib.addFile(name, size, fileobj,
130 contentType='test/test',132 contentType='test/test',
131133
=== modified file 'lib/lp/archivepublisher/publishing.py'
--- lib/lp/archivepublisher/publishing.py 2009-12-14 17:32:06 +0000
+++ lib/lp/archivepublisher/publishing.py 2010-02-10 00:32:23 +0000
@@ -9,12 +9,11 @@
99
10__metaclass__ = type10__metaclass__ = type
1111
12import apt_pkg12import hashlib
13from datetime import datetime
14import logging13import logging
15from md5 import md5
16import os14import os
17from sha import sha15
16from datetime import datetime
1817
19from zope.component import getUtility18from zope.component import getUtility
2019
@@ -59,23 +58,6 @@
59Architecture: %s58Architecture: %s
60"""59"""
6160
62class sha256:
63 """Encapsulates apt_pkg.sha256sum as expected by publishing.
64
65 It implements '__init__' and 'hexdigest' methods from PEP-247, which are
66 the only ones required in soyuz-publishing-system.
67
68 It's a work around for broken Crypto.Hash.SHA256. See further information
69 in bug #131503.
70 """
71 def __init__(self, content):
72 self._sum = apt_pkg.sha256sum(content)
73
74 def hexdigest(self):
75 """Return the hexdigest produced by apt_pkg.sha256sum."""
76 return self._sum
77
78
79def reorder_components(components):61def reorder_components(components):
80 """Return a list of the components provided.62 """Return a list of the components provided.
8163
@@ -518,13 +500,13 @@
518 f.write("MD5Sum:\n")500 f.write("MD5Sum:\n")
519 all_files = sorted(list(all_files), key=os.path.dirname)501 all_files = sorted(list(all_files), key=os.path.dirname)
520 for file_name in all_files:502 for file_name in all_files:
521 self._writeSumLine(full_name, f, file_name, md5)503 self._writeSumLine(full_name, f, file_name, hashlib.md5)
522 f.write("SHA1:\n")504 f.write("SHA1:\n")
523 for file_name in all_files:505 for file_name in all_files:
524 self._writeSumLine(full_name, f, file_name, sha)506 self._writeSumLine(full_name, f, file_name, hashlib.sha1)
525 f.write("SHA256:\n")507 f.write("SHA256:\n")
526 for file_name in all_files:508 for file_name in all_files:
527 self._writeSumLine(full_name, f, file_name, sha256)509 self._writeSumLine(full_name, f, file_name, hashlib.sha256)
528510
529 f.close()511 f.close()
530512
@@ -607,16 +589,8 @@
607589
608 in_file = open(full_name, 'r')590 in_file = open(full_name, 'r')
609 try:591 try:
610 # XXX cprov 20080704 bug=243630,269014: Workaround for hardy's592 contents = in_file.read()
611 # python-apt. If it receives a file object as an argument instead593 length = len(contents)
612 # of the file contents as a string, it will generate the correct
613 # SHA256.
614 if sum_form == sha256:
615 contents = in_file
616 length = os.stat(full_name).st_size
617 else:
618 contents = in_file.read()
619 length = len(contents)
620 checksum = sum_form(contents).hexdigest()594 checksum = sum_form(contents).hexdigest()
621 finally:595 finally:
622 in_file.close()596 in_file.close()
623597
=== modified file 'lib/lp/archivepublisher/tests/test_librarianwrapper.py'
--- lib/lp/archivepublisher/tests/test_librarianwrapper.py 2009-06-24 23:28:16 +0000
+++ lib/lp/archivepublisher/tests/test_librarianwrapper.py 2010-02-10 00:32:23 +0000
@@ -5,9 +5,9 @@
55
6__metaclass__ = type6__metaclass__ = type
77
8import hashlib
8import os9import os
9import shutil10import shutil
10import sha
11import sys11import sys
12import unittest12import unittest
1313
@@ -47,7 +47,7 @@
4747
48 fileobj = open(path, 'rb')48 fileobj = open(path, 'rb')
49 size = os.stat(path).st_size49 size = os.stat(path).st_size
50 digest = sha.sha(open(path, 'rb').read()).hexdigest()50 digest = hashlib.sha1(open(path, 'rb').read()).hexdigest()
5151
52 ## Use Fake Librarian class52 ## Use Fake Librarian class
53 uploader = FakeUploadClient()53 uploader = FakeUploadClient()
5454
=== modified file 'lib/lp/archivepublisher/tests/test_pool.py'
--- lib/lp/archivepublisher/tests/test_pool.py 2009-06-24 23:28:16 +0000
+++ lib/lp/archivepublisher/tests/test_pool.py 2010-02-10 00:32:23 +0000
@@ -5,13 +5,13 @@
55
6__metaclass__ = type6__metaclass__ = type
77
88import hashlib
9import os9import os
10import sha
11import sys10import sys
12import shutil11import shutil
12import unittest
13
13from tempfile import mkdtemp14from tempfile import mkdtemp
14import unittest
1515
16from lp.archivepublisher.tests.util import FakeLogger16from lp.archivepublisher.tests.util import FakeLogger
17from lp.archivepublisher.diskpool import DiskPool, poolify17from lp.archivepublisher.diskpool import DiskPool, poolify
@@ -44,7 +44,7 @@
44 def addToPool(self, component):44 def addToPool(self, component):
45 return self.pool.addFile(45 return self.pool.addFile(
46 component, self.sourcename, self.filename,46 component, self.sourcename, self.filename,
47 sha.sha(self.contents).hexdigest(), MockFile(self.contents))47 hashlib.sha1(self.contents).hexdigest(), MockFile(self.contents))
4848
49 def removeFromPool(self, component):49 def removeFromPool(self, component):
50 return self.pool.removeFile(component, self.sourcename, self.filename)50 return self.pool.removeFile(component, self.sourcename, self.filename)
5151
=== modified file 'lib/lp/archivepublisher/tests/test_publisher.py'
--- lib/lp/archivepublisher/tests/test_publisher.py 2009-12-21 18:05:27 +0000
+++ lib/lp/archivepublisher/tests/test_publisher.py 2010-02-10 00:32:23 +0000
@@ -8,6 +8,7 @@
88
9import bz29import bz2
10import gzip10import gzip
11import hashlib
11import os12import os
12import shutil13import shutil
13import stat14import stat
@@ -20,8 +21,7 @@
2021
21from lp.archivepublisher.config import getPubConfig22from lp.archivepublisher.config import getPubConfig
22from lp.archivepublisher.diskpool import DiskPool23from lp.archivepublisher.diskpool import DiskPool
23from lp.archivepublisher.publishing import (24from lp.archivepublisher.publishing import Publisher, getPublisher
24 Publisher, getPublisher, sha256)
25from canonical.config import config25from canonical.config import config
26from canonical.database.constants import UTC_NOW26from canonical.database.constants import UTC_NOW
27from canonical.launchpad.ftests.keys_for_tests import gpgkeysdir27from canonical.launchpad.ftests.keys_for_tests import gpgkeysdir
@@ -745,70 +745,6 @@
745 self.assertReleaseFileRequested(745 self.assertReleaseFileRequested(
746 publisher, 'breezy-autotest', component, dist)746 publisher, 'breezy-autotest', component, dist)
747747
748 def testAptSHA256(self):
749 """Test issues with python-apt in Ubuntu/hardy.
750
751 This test only runs on Ubuntu/hardy systems.
752
753 The version of python-apt in Ubuntu/hardy has problems with
754 contents containing '\0' character.
755
756 The documented workaround for it is passing the original
757 file-descriptor to apt_pkg.sha256sum(), instead of its contents.
758
759 The python-apt version in Ubuntu/Intrepid has a fix for this issue,
760 but it already has many other features that makes a backport
761 practically unfeasible. That's mainly why this 'bug' is documented
762 as a LP test, the current code was modified to cope with it.
763
764 Once the issue with python-apt is gone, either by having a backport
765 available in hardy or a production upgrade, this test will fail. At
766 that point we will be able to revert the affected code and remove
767 this test, restoring the balance of the force.
768
769 See https://bugs.edge.launchpad.net/soyuz/+bug/243630 and
770 https://bugs.edge.launchpad.net/soyuz/+bug/269014.
771 """
772 # XXX cprov 20090218 bug-279248: when hardy's apt gets fixed by a
773 # SRU, this test will fail in PQM/Buildbot. Then we should change
774 # the actual code for passing file descriptors instead of text to
775 # apt (it will perform better this way) and obviously remove this
776 # test.
777
778 # Skip this test if it's not being run on Ubuntu/hardy.
779 lsb_info = get_lsb_information()
780 if (lsb_info.get('ID') != 'Ubuntu' or
781 lsb_info.get('CODENAME') != 'hardy'):
782 return
783
784 def _getSHA256(content):
785 """Return checksums for the given content.
786
787 Return a tuple containing the checksum corresponding to the
788 given content (as string) and a file containing the same string.
789 """
790 # Write the given content in a tempfile.
791 test_filepath = tempfile.mktemp()
792 test_file = open(test_filepath, 'w')
793 test_file.write(content)
794 test_file.close()
795 # Generate the checksums for the two sources.
796 text = sha256(content).hexdigest()
797 file = sha256(open(test_filepath)).hexdigest()
798 # Remove the tempfile.
799 os.unlink(test_filepath)
800 return text, file
801
802 # Apt does the right thing for ordinary strings, both, file and text
803 # checksums are identical.
804 text, file = _getSHA256("foobar")
805 self.assertEqual(text, file)
806
807 # On the other hand, there is a mismatch for strings containing '\0'
808 text, file = _getSHA256("foo\0bar")
809 self.assertNotEqual(
810 text, file, "Python-apt no longer creates bad SHA256 sums.")
811
812 def _getReleaseFileOrigin(self, contents):748 def _getReleaseFileOrigin(self, contents):
813 origin_header = 'Origin: '749 origin_header = 'Origin: '
814 [origin_line] = [750 [origin_line] = [
815751
=== modified file 'lib/lp/archiveuploader/nascentuploadfile.py'
--- lib/lp/archiveuploader/nascentuploadfile.py 2009-12-14 13:49:03 +0000
+++ lib/lp/archiveuploader/nascentuploadfile.py 2010-02-10 00:32:23 +0000
@@ -21,9 +21,8 @@
2121
22import apt_inst22import apt_inst
23import apt_pkg23import apt_pkg
24import hashlib
24import os25import os
25import md5
26import sha
27import subprocess26import subprocess
28import sys27import sys
29import time28import time
@@ -214,8 +213,8 @@
214213
215 # Read in the file and compute its md5 and sha1 checksums and remember214 # Read in the file and compute its md5 and sha1 checksums and remember
216 # the size of the file as read-in.215 # the size of the file as read-in.
217 digest = md5.md5()216 digest = hashlib.md5()
218 sha_cksum = sha.sha()217 sha_cksum = hashlib.sha1()
219 ckfile = open(self.filepath, "r")218 ckfile = open(self.filepath, "r")
220 size = 0219 size = 0
221 for chunk in filechunks(ckfile):220 for chunk in filechunks(ckfile):
222221
=== modified file 'lib/lp/services/mail/sendmail.py'
--- lib/lp/services/mail/sendmail.py 2009-07-23 18:34:25 +0000
+++ lib/lp/services/mail/sendmail.py 2010-02-10 00:32:23 +0000
@@ -22,11 +22,14 @@
22 'simple_sendmail',22 'simple_sendmail',
23 'simple_sendmail_from_person',23 'simple_sendmail_from_person',
24 'raw_sendmail',24 'raw_sendmail',
25 'validate_message']25 'validate_message',
26 ]
27
28
29import hashlib
30import sets
2631
27from binascii import b2a_qp32from binascii import b2a_qp
28import sha
29import sets
30from email.Encoders import encode_base6433from email.Encoders import encode_base64
31from email.Utils import getaddresses, make_msgid, formatdate, formataddr34from email.Utils import getaddresses, make_msgid, formatdate, formataddr
32from email.Message import Message35from email.Message import Message
@@ -375,7 +378,7 @@
375 # helps security, but still exposes us to a replay attack; we consider the378 # helps security, but still exposes us to a replay attack; we consider the
376 # risk low.379 # risk low.
377 del message['X-Launchpad-Hash']380 del message['X-Launchpad-Hash']
378 hash = sha.new(config.mailman.shared_secret)381 hash = hashlib.sha1(config.mailman.shared_secret)
379 hash.update(str(message['message-id']))382 hash.update(str(message['message-id']))
380 message['X-Launchpad-Hash'] = hash.hexdigest()383 message['X-Launchpad-Hash'] = hash.hexdigest()
381384
382385
=== modified file 'lib/lp/soyuz/doc/soyuz-upload.txt.disabled'
--- lib/lp/soyuz/doc/soyuz-upload.txt.disabled 2009-05-13 14:05:27 +0000
+++ lib/lp/soyuz/doc/soyuz-upload.txt.disabled 2010-02-10 00:32:23 +0000
@@ -144,9 +144,9 @@
144each FTP session. Below we ensure that, and also that the content144each FTP session. Below we ensure that, and also that the content
145of these files match the uploaded ones.145of these files match the uploaded ones.
146146
147 >>> import md5147 >>> import hashlib
148 >>> def get_md5(filename):148 >>> def get_md5(filename):
149 ... return md5.new(open(filename).read()).digest()149 ... return hashlib.md5(open(filename).read()).digest()
150150
151 >>> def get_upload_dir(num, dir=incoming_dir):151 >>> def get_upload_dir(num, dir=incoming_dir):
152 ... """Return the path to the upload, if found in the dir."""152 ... """Return the path to the upload, if found in the dir."""
153153
=== modified file 'lib/lp/soyuz/scripts/ftpmaster.py'
--- lib/lp/soyuz/scripts/ftpmaster.py 2009-12-13 11:55:40 +0000
+++ lib/lp/soyuz/scripts/ftpmaster.py 2010-02-10 00:32:23 +0000
@@ -21,7 +21,7 @@
2121
22import apt_pkg22import apt_pkg
23import commands23import commands
24import md524import hashlib
25import os25import os
26import stat26import stat
27import sys27import sys
@@ -836,7 +836,7 @@
836 @classmethod836 @classmethod
837 def generateMD5Sum(self, filename):837 def generateMD5Sum(self, filename):
838 file_handle = open(filename)838 file_handle = open(filename)
839 md5sum = md5.md5(file_handle.read()).hexdigest()839 md5sum = hashlib.md5(file_handle.read()).hexdigest()
840 file_handle.close()840 file_handle.close()
841 return md5sum841 return md5sum
842842
843843
=== modified file 'lib/lp/soyuz/scripts/gina/library.py'
--- lib/lp/soyuz/scripts/gina/library.py 2009-06-25 04:06:00 +0000
+++ lib/lp/soyuz/scripts/gina/library.py 2010-02-10 00:32:23 +0000
@@ -5,12 +5,15 @@
55
6__metaclass__ = type6__metaclass__ = type
77
8
9import hashlib
8import os10import os
9import sha
1011
11from zope.component import getUtility12from zope.component import getUtility
1213
13from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet14from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
15
16
14def _libType(fname):17def _libType(fname):
15 if fname.endswith(".dsc"):18 if fname.endswith(".dsc"):
16 return "text/x-debian-source-package"19 return "text/x-debian-source-package"
@@ -41,7 +44,7 @@
41def checkLibraryForFile(path, filename):44def checkLibraryForFile(path, filename):
42 fullpath = os.path.join(path, filename)45 fullpath = os.path.join(path, filename)
43 assert os.path.exists(fullpath)46 assert os.path.exists(fullpath)
44 digester = sha.sha()47 digester = hashlib.sha1()
45 openfile = open(fullpath, "r")48 openfile = open(fullpath, "r")
46 for chunk in iter(lambda: openfile.read(1024*4), ''):49 for chunk in iter(lambda: openfile.read(1024*4), ''):
47 digester.update(chunk)50 digester.update(chunk)
4851
=== modified file 'lib/lp/soyuz/scripts/queue.py'
--- lib/lp/soyuz/scripts/queue.py 2009-08-28 06:39:38 +0000
+++ lib/lp/soyuz/scripts/queue.py 2010-02-10 00:32:23 +0000
@@ -9,7 +9,6 @@
9# as Launchpad contains lots of queues.9# as Launchpad contains lots of queues.
1010
11__metaclass__ = type11__metaclass__ = type
12
13__all__ = [12__all__ = [
14 'CommandRunner',13 'CommandRunner',
15 'CommandRunnerError',14 'CommandRunnerError',
@@ -17,11 +16,12 @@
17 'name_queue_map'16 'name_queue_map'
18 ]17 ]
1918
19
20import errno20import errno
21import hashlib
21import pytz22import pytz
2223
23from datetime import datetime24from datetime import datetime
24from sha import sha
2525
26from zope.component import getUtility26from zope.component import getUtility
2727
@@ -420,7 +420,7 @@
420 libfile.close()420 libfile.close()
421 else:421 else:
422 # Check sha against existing file (bug #67014)422 # Check sha against existing file (bug #67014)
423 existing_sha = sha()423 existing_sha = hashlib.sha1()
424 for chunk in filechunks(existing_file):424 for chunk in filechunks(existing_file):
425 existing_sha.update(chunk)425 existing_sha.update(chunk)
426 existing_file.close()426 existing_file.close()
427427
=== modified file 'lib/lp/soyuz/scripts/tests/test_queue.py'
--- lib/lp/soyuz/scripts/tests/test_queue.py 2009-12-13 11:55:40 +0000
+++ lib/lp/soyuz/scripts/tests/test_queue.py 2010-02-10 00:32:23 +0000
@@ -4,14 +4,17 @@
4"""queue tool base class tests."""4"""queue tool base class tests."""
55
6__metaclass__ = type6__metaclass__ = type
77__all__ = [
8__all__ = ['upload_bar_source']8 'upload_bar_source',
99 ]
10
11
12import hashlib
10import os13import os
11import shutil14import shutil
12import tempfile15import tempfile
16
13from unittest import TestCase, TestLoader17from unittest import TestCase, TestLoader
14from sha import sha
1518
16from zope.component import getUtility19from zope.component import getUtility
17from zope.security.proxy import removeSecurityProxy20from zope.security.proxy import removeSecurityProxy
@@ -929,7 +932,7 @@
929932
930 def _getsha1(self, filename):933 def _getsha1(self, filename):
931 """Return a sha1 hex digest of a file"""934 """Return a sha1 hex digest of a file"""
932 file_sha = sha()935 file_sha = hashlib.sha1()
933 opened_file = open(filename,"r")936 opened_file = open(filename,"r")
934 for chunk in filechunks(opened_file):937 for chunk in filechunks(opened_file):
935 file_sha.update(chunk)938 file_sha.update(chunk)