Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #13969 -- Extended length of salt used when setting the passwor…

…d. Thanks to cyounkins for the initial patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16453 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 650739ef172049a294f53bf51b70f6bb2d3f5dd5 1 parent c159374
Jannis Leidel authored June 26, 2011

Showing 1 changed file with 29 additions and 8 deletions. Show diff stats Hide diff stats

  1. 37  django/contrib/auth/models.py
37  django/contrib/auth/models.py
... ...
@@ -1,10 +1,12 @@
1 1
 import datetime
2 2
 import hashlib
  3
+import random
3 4
 import urllib
4 5
 
5 6
 from django.contrib import auth
6 7
 from django.contrib.auth.signals import user_logged_in
7 8
 from django.core.exceptions import ImproperlyConfigured
  9
+from django.core.mail import send_mail
8 10
 from django.db import models
9 11
 from django.db.models.manager import EmptyManager
10 12
 from django.contrib.contenttypes.models import ContentType
@@ -34,6 +36,21 @@ def get_hexdigest(algorithm, salt, raw_password):
34 36
         return hashlib.sha1(salt + raw_password).hexdigest()
35 37
     raise ValueError("Got unknown password algorithm type in password.")
36 38
 
  39
+def get_random_string(length=12, allowed_chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):
  40
+    """
  41
+    Returns a random string of length characters from the set of a-z, A-Z, 0-9
  42
+    for use as a salt.
  43
+
  44
+    The default length of 12 with the a-z, A-Z, 0-9 character set returns
  45
+    a 71-bit salt. log_2((26+26+10)^12) =~ 71 bits
  46
+    """
  47
+    import random
  48
+    try:
  49
+        random = random.SystemRandom()
  50
+    except NotImplementedError:
  51
+        pass
  52
+    return ''.join([random.choice(allowed_chars) for i in range(length)])
  53
+
37 54
 def check_password(raw_password, enc_password):
38 55
     """
39 56
     Returns a boolean of whether the raw_password was correct. Handles
@@ -145,11 +162,13 @@ def create_superuser(self, username, email, password):
145 162
         return u
146 163
 
147 164
     def make_random_password(self, length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'):
148  
-        "Generates a random password with the given length and given allowed_chars"
  165
+        """
  166
+        Generates a random password with the given length
  167
+        and given allowed_chars
  168
+        """
149 169
         # Note that default value of allowed_chars does not have "I" or letters
150 170
         # that look like it -- just to avoid confusion.
151  
-        from random import choice
152  
-        return ''.join([choice(allowed_chars) for i in range(length)])
  171
+        return get_random_string(length, allowed_chars)
153 172
 
154 173
 
155 174
 # A few helper functions for common logic between User and AnonymousUser.
@@ -244,7 +263,9 @@ def is_authenticated(self):
244 263
         return True
245 264
 
246 265
     def get_full_name(self):
247  
-        "Returns the first_name plus the last_name, with a space in between."
  266
+        """
  267
+        Returns the first_name plus the last_name, with a space in between.
  268
+        """
248 269
         full_name = u'%s %s' % (self.first_name, self.last_name)
249 270
         return full_name.strip()
250 271
 
@@ -252,9 +273,8 @@ def set_password(self, raw_password):
252 273
         if raw_password is None:
253 274
             self.set_unusable_password()
254 275
         else:
255  
-            import random
256 276
             algo = 'sha1'
257  
-            salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
  277
+            salt = get_random_string()
258 278
             hsh = get_hexdigest(algo, salt, raw_password)
259 279
             self.password = '%s$%s$%s' % (algo, salt, hsh)
260 280
 
@@ -346,8 +366,9 @@ def has_module_perms(self, app_label):
346 366
         return _user_has_module_perms(self, app_label)
347 367
 
348 368
     def email_user(self, subject, message, from_email=None):
349  
-        "Sends an email to this User."
350  
-        from django.core.mail import send_mail
  369
+        """
  370
+        Sends an email to this User.
  371
+        """
351 372
         send_mail(subject, message, from_email, [self.email])
352 373
 
353 374
     def get_profile(self):

0 notes on commit 650739e

Please sign in to comment.
Something went wrong with that request. Please try again.