yet faster web2py_uuid by caching urandom results
This commit is contained in:
@@ -1 +1 @@
|
||||
Version 2.0.9 (2012-09-29 17:16:28) dev
|
||||
Version 2.0.9 (2012-09-29 17:56:36) dev
|
||||
|
||||
+27
-7
@@ -10,6 +10,7 @@ This file specifically includes utilities for security.
|
||||
"""
|
||||
|
||||
import string
|
||||
import threading
|
||||
import struct
|
||||
import hashlib
|
||||
import hmac
|
||||
@@ -110,6 +111,7 @@ def initialize_urandom():
|
||||
random.seed(node_id + microseconds)
|
||||
try:
|
||||
os.urandom(1)
|
||||
have_urandom = True
|
||||
try:
|
||||
# try to add process-specific entropy
|
||||
frandom = open('/dev/urandom','wb')
|
||||
@@ -121,13 +123,31 @@ def initialize_urandom():
|
||||
# works anyway
|
||||
pass
|
||||
except NotImplementedError:
|
||||
have_urandom = False
|
||||
logger.warning(
|
||||
"""Cryptographically secure session management is not possible on your system because
|
||||
your system does not provide a cryptographically secure entropy source.
|
||||
This is not specific to web2py; consider deploying on a different operating system.""")
|
||||
return ctokens
|
||||
CTOKENS = initialize_urandom()
|
||||
UNPACKED_CTOKENS = struct.unpack('=QQ',string.join((chr(x) for x in CTOKENS),''))
|
||||
unpacked_ctokens = struct.unpack('=QQ',string.join(
|
||||
(chr(x) for x in ctokens),''))
|
||||
return unpacked_ctokens, have_urandom
|
||||
UNPACKED_CTOKENS, HAVE_URANDOM = initialize_urandom()
|
||||
|
||||
def fast_urandom16(urandom=[], locker = threading.RLock()):
|
||||
"""
|
||||
this is 4x faster than calling os.urandom(16) and prevents
|
||||
the "too many files open" issue with concurrent access to os.urandom()
|
||||
"""
|
||||
try:
|
||||
return urandom.pop()
|
||||
except IndexError:
|
||||
try:
|
||||
locker.acquire()
|
||||
ur = os.urandom(16*1024)
|
||||
urandom += [ur[i:i+16] for i in xrange(16,1024*16,16)]
|
||||
return ur[0:16]
|
||||
finally:
|
||||
locker.release()
|
||||
|
||||
def web2py_uuid(ctokens=UNPACKED_CTOKENS):
|
||||
"""
|
||||
@@ -139,12 +159,12 @@ def web2py_uuid(ctokens=UNPACKED_CTOKENS):
|
||||
"""
|
||||
rand_longs = struct.unpack('=QQ', bytes(bytearray(
|
||||
random.randrange(256) for i in xrange(16))))
|
||||
try:
|
||||
urand_longs = struct.unpack('=QQ', os.urandom(16))
|
||||
byte_s = struct.pack('=QQ',
|
||||
if HAVE_URANDOM:
|
||||
urand_longs = struct.unpack('=QQ', fast_urandom16())
|
||||
byte_s = struct.pack('=QQ',
|
||||
rand_longs[0]^urand_longs[0]^ctokens[0],
|
||||
rand_longs[1]^urand_longs[1]^ctokens[1])
|
||||
except NotImplementedError:
|
||||
else:
|
||||
byte_s = struct.pack('=QQ',
|
||||
rand_longs[0]^ctokens[0],
|
||||
rand_longs[1]^ctokens[1])
|
||||
|
||||
Reference in New Issue
Block a user