Delayed encoding of password and salt in password checking.
Applied the rule that string encoding should happen as late as possible. This is also a preparation for Python 3 compatibility.
This commit is contained in:
parent
9c096ab981
commit
eb286aa22f
|
@ -1,7 +1,6 @@
|
|||
from django import forms
|
||||
from django.forms.util import flatatt
|
||||
from django.template import loader
|
||||
from django.utils.encoding import smart_str
|
||||
from django.utils.http import int_to_base36
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
|
@ -26,8 +25,6 @@ class ReadOnlyPasswordHashWidget(forms.Widget):
|
|||
|
||||
final_attrs = self.build_attrs(attrs)
|
||||
|
||||
encoded = smart_str(encoded)
|
||||
|
||||
if len(encoded) == 32 and '$' not in encoded:
|
||||
algorithm = 'unsalted_md5'
|
||||
else:
|
||||
|
|
|
@ -40,9 +40,6 @@ def check_password(password, encoded, setter=None, preferred='default'):
|
|||
return False
|
||||
|
||||
preferred = get_hasher(preferred)
|
||||
raw_password = password
|
||||
password = smart_str(password)
|
||||
encoded = smart_str(encoded)
|
||||
|
||||
if len(encoded) == 32 and '$' not in encoded:
|
||||
hasher = get_hasher('unsalted_md5')
|
||||
|
@ -53,7 +50,7 @@ def check_password(password, encoded, setter=None, preferred='default'):
|
|||
must_update = hasher.algorithm != preferred.algorithm
|
||||
is_correct = hasher.verify(password, encoded)
|
||||
if setter and is_correct and must_update:
|
||||
setter(raw_password)
|
||||
setter(password)
|
||||
return is_correct
|
||||
|
||||
|
||||
|
@ -69,11 +66,9 @@ def make_password(password, salt=None, hasher='default'):
|
|||
return UNUSABLE_PASSWORD
|
||||
|
||||
hasher = get_hasher(hasher)
|
||||
password = smart_str(password)
|
||||
|
||||
if not salt:
|
||||
salt = hasher.salt()
|
||||
salt = smart_str(salt)
|
||||
|
||||
return hasher.encode(password, salt)
|
||||
|
||||
|
@ -291,7 +286,7 @@ class SHA1PasswordHasher(BasePasswordHasher):
|
|||
def encode(self, password, salt):
|
||||
assert password
|
||||
assert salt and '$' not in salt
|
||||
hash = hashlib.sha1(salt + password).hexdigest()
|
||||
hash = hashlib.sha1(smart_str(salt + password)).hexdigest()
|
||||
return "%s$%s$%s" % (self.algorithm, salt, hash)
|
||||
|
||||
def verify(self, password, encoded):
|
||||
|
@ -319,7 +314,7 @@ class MD5PasswordHasher(BasePasswordHasher):
|
|||
def encode(self, password, salt):
|
||||
assert password
|
||||
assert salt and '$' not in salt
|
||||
hash = hashlib.md5(salt + password).hexdigest()
|
||||
hash = hashlib.md5(smart_str(salt + password)).hexdigest()
|
||||
return "%s$%s$%s" % (self.algorithm, salt, hash)
|
||||
|
||||
def verify(self, password, encoded):
|
||||
|
@ -353,7 +348,7 @@ class UnsaltedMD5PasswordHasher(BasePasswordHasher):
|
|||
return ''
|
||||
|
||||
def encode(self, password, salt):
|
||||
return hashlib.md5(password).hexdigest()
|
||||
return hashlib.md5(smart_str(password)).hexdigest()
|
||||
|
||||
def verify(self, password, encoded):
|
||||
encoded_2 = self.encode(password, '')
|
||||
|
|
|
@ -22,6 +22,7 @@ except NotImplementedError:
|
|||
using_sysrandom = False
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.encoding import smart_str
|
||||
|
||||
|
||||
_trans_5c = b"".join([chr(x ^ 0x5C) for x in xrange(256)])
|
||||
|
@ -137,6 +138,8 @@ def pbkdf2(password, salt, iterations, dklen=0, digest=None):
|
|||
assert iterations > 0
|
||||
if not digest:
|
||||
digest = hashlib.sha256
|
||||
password = smart_str(password)
|
||||
salt = smart_str(salt)
|
||||
hlen = digest().digest_size
|
||||
if not dklen:
|
||||
dklen = hlen
|
||||
|
|
|
@ -128,6 +128,15 @@ If you were using the ``data`` parameter in a PUT request without a
|
|||
``content_type``, you must encode your data before passing it to the test
|
||||
client and set the ``content_type`` argument.
|
||||
|
||||
String types of hasher method parameters
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you have written a :ref:`custom password hasher <auth_password_storage>`,
|
||||
your ``encode()``, ``verify()`` or ``safe_summary()`` methods should accept
|
||||
Unicode parameters (``password``, ``salt`` or ``encoded``). If any of the
|
||||
hashing methods need byte strings, you can use the
|
||||
:func:`~django.utils.encoding.smart_str` utility to encode the strings.
|
||||
|
||||
Features deprecated in 1.5
|
||||
==========================
|
||||
|
||||
|
|
Loading…
Reference in New Issue