mirror of https://github.com/django/django.git
[1.5.x] Fixed #18144 -- Added backwards compatibility with old unsalted MD5 passwords
Thanks apreobrazhensky at gmail.com for the report.
Backport of 63d6a50dd
from master.
This commit is contained in:
parent
fd61ce9c4f
commit
c39be8b836
|
@ -132,7 +132,8 @@ def identify_hasher(encoded):
|
||||||
get_hasher() to return hasher. Raises ValueError if
|
get_hasher() to return hasher. Raises ValueError if
|
||||||
algorithm cannot be identified, or if hasher is not loaded.
|
algorithm cannot be identified, or if hasher is not loaded.
|
||||||
"""
|
"""
|
||||||
if len(encoded) == 32 and '$' not in encoded:
|
if ((len(encoded) == 32 and '$' not in encoded) or
|
||||||
|
len(encoded) == 37 and encoded.startswith('md5$$')):
|
||||||
algorithm = 'unsalted_md5'
|
algorithm = 'unsalted_md5'
|
||||||
else:
|
else:
|
||||||
algorithm = encoded.split('$', 1)[0]
|
algorithm = encoded.split('$', 1)[0]
|
||||||
|
@ -372,6 +373,8 @@ class UnsaltedMD5PasswordHasher(BasePasswordHasher):
|
||||||
return hashlib.md5(force_bytes(password)).hexdigest()
|
return hashlib.md5(force_bytes(password)).hexdigest()
|
||||||
|
|
||||||
def verify(self, password, encoded):
|
def verify(self, password, encoded):
|
||||||
|
if len(encoded) == 37 and encoded.startswith('md5$$'):
|
||||||
|
encoded = encoded[5:]
|
||||||
encoded_2 = self.encode(password, '')
|
encoded_2 = self.encode(password, '')
|
||||||
return constant_time_compare(encoded, encoded_2)
|
return constant_time_compare(encoded, encoded_2)
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,11 @@ class TestUtilsHashPass(unittest.TestCase):
|
||||||
self.assertTrue(check_password('lètmein', encoded))
|
self.assertTrue(check_password('lètmein', encoded))
|
||||||
self.assertFalse(check_password('lètmeinz', encoded))
|
self.assertFalse(check_password('lètmeinz', encoded))
|
||||||
self.assertEqual(identify_hasher(encoded).algorithm, "unsalted_md5")
|
self.assertEqual(identify_hasher(encoded).algorithm, "unsalted_md5")
|
||||||
|
# Alternate unsalted syntax
|
||||||
|
alt_encoded = "md5$$%s" % encoded
|
||||||
|
self.assertTrue(is_password_usable(alt_encoded))
|
||||||
|
self.assertTrue(check_password('lètmein', alt_encoded))
|
||||||
|
self.assertFalse(check_password('lètmeinz', alt_encoded))
|
||||||
|
|
||||||
@skipUnless(crypt, "no crypt module to generate password.")
|
@skipUnless(crypt, "no crypt module to generate password.")
|
||||||
def test_crypt(self):
|
def test_crypt(self):
|
||||||
|
|
Loading…
Reference in New Issue