diff options
author | Bob Halley <halley@nominum.com> | 2009-11-13 03:16:09 +0900 |
---|---|---|
committer | Bob Halley <halley@nominum.com> | 2009-11-13 03:16:09 +0900 |
commit | b37425d20991bc147932d1eddea01e1d929ceb5d (patch) | |
tree | 89e3b45031bd76416ce1a4d2bbd8a9726fe96d0e /dns/entropy.py | |
parent | 0ed52292ad711521d96d84e74ae71539043906de (diff) | |
download | dnspython-b37425d20991bc147932d1eddea01e1d929ceb5d.tar.gz |
Try using os.urandom() to get the seed.
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.
Diffstat (limited to 'dns/entropy.py')
-rw-r--r-- | dns/entropy.py | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/dns/entropy.py b/dns/entropy.py index fa448d1..9e10d12 100644 --- a/dns/entropy.py +++ b/dns/entropy.py @@ -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) |