]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Try using os.urandom() to get the seed.
authorBob Halley <halley@nominum.com>
Thu, 12 Nov 2009 18:16:09 +0000 (03:16 +0900)
committerBob Halley <halley@nominum.com>
Thu, 12 Nov 2009 18:16:09 +0000 (03:16 +0900)
Lock access to the entropy pool to avoid races in multithreaded situations.

If a seed wasn't supplied, don't do the seeding operation until someone
actually wants to get random numbers.

dns/entropy.py

index fa448d1018b46f655323c72f110cae618d2dead7..9e10d126cc38419850a600969d0666ea6a380a4c 100644 (file)
@@ -13,6 +13,7 @@
 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
+import os
 import time
 try:
     import threading as _threading
@@ -25,15 +26,6 @@ class EntropyPool(object):
         self.digest = None
         self.next_byte = 0
         self.lock = _threading.Lock()
-        if seed is None:
-            try:
-                r = file('/dev/random', 'r', 0)
-                try:
-                    seed = r.read(16)
-                finally:
-                    r.close()
-            except:
-                seed = str(time.time())
         try:
             import hashlib
             self.hash = hashlib.sha1()
@@ -48,7 +40,11 @@ class EntropyPool(object):
                 self.hash = md5.new()
                 self.hash_len = 16
         self.pool = '\0' * self.hash_len
-        self.stir(seed)
+        if not seed is None:
+            self.stir(seed)
+            self.seeded = True
+        else:
+            self.seeded = False
 
     def stir(self, entropy, already_locked=False):
         if not already_locked:
@@ -66,8 +62,25 @@ class EntropyPool(object):
             if not already_locked:
                 self.lock.release()
 
+    def _maybe_seed(self):
+        if not self.seeded:
+            try:
+                seed = os.urandom(16)
+            except:
+                try:
+                    r = file('/dev/urandom', 'r', 0)
+                    try:
+                        seed = r.read(16)
+                    finally:
+                        r.close()
+                except:
+                    seed = str(time.time())
+            self.seeded = True
+            self.stir(seed, True)
+
     def random_8(self):
         self.lock.acquire()
+        self._maybe_seed()
         try:
             if self.digest is None or self.next_byte == self.hash_len:
                 self.hash.update(self.pool)