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 | |