From 154eb0d7a71decd87d885dc921c7acebe773fcb6 Mon Sep 17 00:00:00 2001 From: Allen Short Date: Thu, 4 Apr 2013 14:39:12 -0700 Subject: [PATCH] decode unicode passwords before salting+hashing (bug 858262) --- apps/users/models.py | 16 +++++++++++++++- apps/users/tests/test_models.py | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/apps/users/models.py b/apps/users/models.py index f1c453c350..2310767c1a 100644 --- a/apps/users/models.py +++ b/apps/users/models.py @@ -326,7 +326,21 @@ class UserProfile(amo.models.OnChangeMixin, amo.models.ModelBase): return valid algo, salt, hsh = self.password.split('$') - return hsh == get_hexdigest(algo, salt, raw_password) + #Complication due to getpersonas account migration; we don't + #know if passwords were utf-8 or latin-1 when hashed. If you + #can prove that they are one or the other, you can delete one + #of these branches. + if '+base64' in algo and isinstance(raw_password, unicode): + if hsh == get_hexdigest(algo, salt, raw_password.encode('utf-8')): + return True + else: + try: + return hsh == get_hexdigest(algo, salt, + raw_password.encode('latin1')) + except UnicodeEncodeError: + return False + else: + return hsh == get_hexdigest(algo, salt, raw_password) def set_password(self, raw_password, algorithm='sha512'): self.password = create_password(algorithm, raw_password) diff --git a/apps/users/tests/test_models.py b/apps/users/tests/test_models.py index 83ee085d29..3ae7c334dc 100644 --- a/apps/users/tests/test_models.py +++ b/apps/users/tests/test_models.py @@ -271,6 +271,26 @@ class TestPasswords(amo.tests.TestCase): (encodestring(self.bytes_), hsh)) assert u.check_password('password') is True + def test_persona_sha512_base64_maybe_utf8(self): + hsh = hashlib.sha512(self.bytes_ + self.utf.encode('utf8')).hexdigest() + u = UserProfile(password='sha512+base64$%s$%s' % + (encodestring(self.bytes_), hsh)) + assert u.check_password(self.utf) is True + + def test_persona_sha512_base64_maybe_latin1(self): + passwd = u'fo\xf3' + hsh = hashlib.sha512(self.bytes_ + passwd.encode('latin1')).hexdigest() + u = UserProfile(password='sha512+base64$%s$%s' % + (encodestring(self.bytes_), hsh)) + assert u.check_password(passwd) is True + + def test_persona_sha512_base64_maybe_not_latin1(self): + passwd = u'fo\xf3' + hsh = hashlib.sha512(self.bytes_ + passwd.encode('latin1')).hexdigest() + u = UserProfile(password='sha512+base64$%s$%s' % + (encodestring(self.bytes_), hsh)) + assert u.check_password(self.utf) is False + def test_persona_sha512_md5_base64(self): md5 = hashlib.md5('password').hexdigest() hsh = hashlib.sha512(self.bytes_ + md5).hexdigest()