File: get-random-string-backport.patch

package info (click to toggle)
python-django 1.2.3-3%2Bsqueeze15
  • links: PTS, VCS
  • area: main
  • in suites: squeeze-lts
  • size: 29,720 kB
  • ctags: 21,538
  • sloc: python: 101,631; xml: 574; makefile: 149; sh: 121; sql: 7
file content (53 lines) | stat: -rw-r--r-- 1,915 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Description: Backport get_random_string from django.utils.crypto
 It's needed by on the the following security fixes.
Author: Raphaƫl Hertzog <hertzog@debian.org>, Thorsten Alteholz <alteholz@debian.org>
Origin: backport, file copy + hand edit
Last-Update: 2014-09-29
--- /dev/null
+++ b/django/utils/crypto.py
@@ -0,0 +1,45 @@
+"""
+Django's standard crypto functions and utilities.
+"""
+
+import hashlib
+import time
+
+# Use the system PRNG if possible
+import random
+try:
+    random = random.SystemRandom()
+    using_sysrandom = True
+except NotImplementedError:
+    import warnings
+    warnings.warn('A secure pseudo-random number generator is not available '
+                  'on your system. Falling back to Mersenne Twister.')
+    using_sysrandom = False
+
+from django.conf import settings
+
+
+def get_random_string(length=12,
+                      allowed_chars='abcdefghijklmnopqrstuvwxyz'
+                                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):
+    """
+    Returns a securely generated random string.
+
+    The default length of 12 with the a-z, A-Z, 0-9 character set returns
+    a 71-bit value. log_2((26+26+10)^12) =~ 71 bits
+    """
+    if not using_sysrandom:
+        # This is ugly, and a hack, but it makes things better than
+        # the alternative of predictability. This re-seeds the PRNG
+        # using a value that is hard for an attacker to predict, every
+        # time a random string is required. This may change the
+        # properties of the chosen random sequence slightly, but this
+        # is better than absolute predictability.
+        random.seed(
+            hashlib.sha256(
+                "%s%s%s" % (
+                    random.getstate(),
+                    time.time(),
+                    settings.SECRET_KEY)
+                ).digest())
+    return ''.join([random.choice(allowed_chars) for i in range(length)])