diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py
index f0ef124..deb6cb9 100644
|
a
|
b
|
|
| 1 | 1 | from django import forms |
| 2 | 2 | from django.forms.util import flatatt |
| 3 | 3 | from django.template import loader |
| 4 | | from django.utils.encoding import smart_str |
| 5 | 4 | from django.utils.http import int_to_base36 |
| 6 | 5 | from django.utils.safestring import mark_safe |
| 7 | 6 | from django.utils.translation import ugettext, ugettext_lazy as _ |
| … |
… |
class ReadOnlyPasswordHashWidget(forms.Widget):
|
| 26 | 25 | |
| 27 | 26 | final_attrs = self.build_attrs(attrs) |
| 28 | 27 | |
| 29 | | encoded = smart_str(encoded) |
| 30 | | |
| 31 | 28 | if len(encoded) == 32 and '$' not in encoded: |
| 32 | 29 | algorithm = 'unsalted_md5' |
| 33 | 30 | else: |
diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py
index 52d204c..11a6313 100644
|
a
|
b
|
def check_password(password, encoded, setter=None, preferred='default'):
|
| 40 | 40 | return False |
| 41 | 41 | |
| 42 | 42 | preferred = get_hasher(preferred) |
| 43 | | raw_password = password |
| 44 | | password = smart_str(password) |
| 45 | | encoded = smart_str(encoded) |
| 46 | 43 | |
| 47 | 44 | if len(encoded) == 32 and '$' not in encoded: |
| 48 | 45 | hasher = get_hasher('unsalted_md5') |
| … |
… |
def check_password(password, encoded, setter=None, preferred='default'):
|
| 53 | 50 | must_update = hasher.algorithm != preferred.algorithm |
| 54 | 51 | is_correct = hasher.verify(password, encoded) |
| 55 | 52 | if setter and is_correct and must_update: |
| 56 | | setter(raw_password) |
| | 53 | setter(password) |
| 57 | 54 | return is_correct |
| 58 | 55 | |
| 59 | 56 | |
| … |
… |
def make_password(password, salt=None, hasher='default'):
|
| 69 | 66 | return UNUSABLE_PASSWORD |
| 70 | 67 | |
| 71 | 68 | hasher = get_hasher(hasher) |
| 72 | | password = smart_str(password) |
| 73 | 69 | |
| 74 | 70 | if not salt: |
| 75 | 71 | salt = hasher.salt() |
| 76 | | salt = smart_str(salt) |
| 77 | 72 | |
| 78 | 73 | return hasher.encode(password, salt) |
| 79 | 74 | |
| … |
… |
class SHA1PasswordHasher(BasePasswordHasher):
|
| 291 | 286 | def encode(self, password, salt): |
| 292 | 287 | assert password |
| 293 | 288 | assert salt and '$' not in salt |
| 294 | | hash = hashlib.sha1(salt + password).hexdigest() |
| | 289 | hash = hashlib.sha1(smart_str(salt + password)).hexdigest() |
| 295 | 290 | return "%s$%s$%s" % (self.algorithm, salt, hash) |
| 296 | 291 | |
| 297 | 292 | def verify(self, password, encoded): |
| … |
… |
class MD5PasswordHasher(BasePasswordHasher):
|
| 319 | 314 | def encode(self, password, salt): |
| 320 | 315 | assert password |
| 321 | 316 | assert salt and '$' not in salt |
| 322 | | hash = hashlib.md5(salt + password).hexdigest() |
| | 317 | hash = hashlib.md5(smart_str(salt + password)).hexdigest() |
| 323 | 318 | return "%s$%s$%s" % (self.algorithm, salt, hash) |
| 324 | 319 | |
| 325 | 320 | def verify(self, password, encoded): |
| … |
… |
class UnsaltedMD5PasswordHasher(BasePasswordHasher):
|
| 353 | 348 | return '' |
| 354 | 349 | |
| 355 | 350 | def encode(self, password, salt): |
| 356 | | return hashlib.md5(password).hexdigest() |
| | 351 | return hashlib.md5(smart_str(password)).hexdigest() |
| 357 | 352 | |
| 358 | 353 | def verify(self, password, encoded): |
| 359 | 354 | encoded_2 = self.encode(password, '') |
diff --git a/django/utils/crypto.py b/django/utils/crypto.py
index 9d6486c..0fce060 100644
|
a
|
b
|
except NotImplementedError:
|
| 22 | 22 | using_sysrandom = False |
| 23 | 23 | |
| 24 | 24 | from django.conf import settings |
| | 25 | from django.utils.encoding import smart_str |
| 25 | 26 | |
| 26 | 27 | |
| 27 | 28 | _trans_5c = b"".join([chr(x ^ 0x5C) for x in xrange(256)]) |
| … |
… |
def pbkdf2(password, salt, iterations, dklen=0, digest=None):
|
| 137 | 138 | assert iterations > 0 |
| 138 | 139 | if not digest: |
| 139 | 140 | digest = hashlib.sha256 |
| | 141 | password = smart_str(password) |
| | 142 | salt = smart_str(salt) |
| 140 | 143 | hlen = digest().digest_size |
| 141 | 144 | if not dklen: |
| 142 | 145 | dklen = hlen |
diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
index 0d86a52..696f332 100644
|
a
|
b
|
If you were using the ``data`` parameter in a PUT request without a
|
| 128 | 128 | ``content_type``, you must encode your data before passing it to the test |
| 129 | 129 | client and set the ``content_type`` argument. |
| 130 | 130 | |
| | 131 | String types of hasher method parameters |
| | 132 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | 133 | |
| | 134 | If you have written a :ref:`custom password hasher <auth_password_storage>`, |
| | 135 | your ``encode()``, ``verify()`` or ``safe_summary()`` methods should accept |
| | 136 | Unicode parameters (``password``, ``salt`` or ``encoded``). If any of the |
| | 137 | hashing methods need byte strings, you can use the |
| | 138 | :func:`~django.utils.encoding.smart_str` utility to encode the strings. |
| | 139 | |
| 131 | 140 | Features deprecated in 1.5 |
| 132 | 141 | ========================== |
| 133 | 142 | |