patch from dwayne c. litzenberger to fix urandom support to work from within a chroot. i modified it slightly to remove os.urandom calls completely, since our direct file access is nearly identical to what python was doing.
This commit is contained in:
parent
4f52c13900
commit
613d2a2f24
2
Makefile
2
Makefile
|
@ -65,5 +65,7 @@ test:
|
||||||
# README
|
# README
|
||||||
# transport.py
|
# transport.py
|
||||||
#
|
#
|
||||||
|
# TRY on windows vm
|
||||||
|
# POST gpg sig on website!
|
||||||
# POST md5sum on website!
|
# POST md5sum on website!
|
||||||
# RUN setup.py
|
# RUN setup.py
|
||||||
|
|
|
@ -20,51 +20,43 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Detect an OS random number source
|
##
|
||||||
osrandom_source = None
|
## Find potential random number sources
|
||||||
|
##
|
||||||
|
|
||||||
# Try os.urandom
|
# Try to open /dev/urandom now so that paramiko will be able to access
|
||||||
if osrandom_source is None:
|
# it even if os.chroot() is invoked later.
|
||||||
try:
|
try:
|
||||||
from os import urandom
|
_dev_urandom = open("/dev/urandom", "rb", 0)
|
||||||
osrandom_source = "os.urandom"
|
except EnvironmentError:
|
||||||
except ImportError:
|
_dev_urandom = None
|
||||||
pass
|
|
||||||
|
|
||||||
# Try winrandom
|
# Try to import the "winrandom" module
|
||||||
if osrandom_source is None:
|
try:
|
||||||
try:
|
from Crypto.Util import winrandom
|
||||||
from Crypto.Util import winrandom
|
except ImportError:
|
||||||
osrandom_source = "winrandom"
|
winrandom = None
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Try /dev/urandom
|
|
||||||
if osrandom_source is None:
|
|
||||||
try:
|
|
||||||
_dev_urandom = open("/dev/urandom", "rb", 0)
|
|
||||||
def urandom(bytes):
|
|
||||||
return _dev_urandom.read(bytes)
|
|
||||||
osrandom_source = "/dev/urandom"
|
|
||||||
except (OSError, IOError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Give up
|
##
|
||||||
if osrandom_source is None:
|
## Define RandomPool classes
|
||||||
raise ImportError("Cannot find OS entropy source")
|
##
|
||||||
|
|
||||||
|
def _workaround_windows_cryptgenrandom_bug(self):
|
||||||
|
# According to "Cryptanalysis of the Random Number Generator of the
|
||||||
|
# Windows Operating System", by Leo Dorrendorf and Zvi Gutterman
|
||||||
|
# and Benny Pinkas <http://eprint.iacr.org/2007/419>,
|
||||||
|
# CryptGenRandom only updates its internal state using kernel-provided
|
||||||
|
# random data every 128KiB of output.
|
||||||
|
self.get_bytes(128*1024) # discard 128 KiB of output
|
||||||
|
|
||||||
|
|
||||||
class BaseOSRandomPool(object):
|
class BaseOSRandomPool(object):
|
||||||
def __init__(self, numbytes=160, cipher=None, hash=None):
|
def __init__(self, numbytes=160, cipher=None, hash=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def stir(self, s=''):
|
def stir(self, s=''):
|
||||||
# According to "Cryptanalysis of the Random Number Generator of the
|
pass
|
||||||
# Windows Operating System", by Leo Dorrendorf and Zvi Gutterman
|
|
||||||
# and Benny Pinkas <http://eprint.iacr.org/2007/419>,
|
|
||||||
# CryptGenRandom only updates its internal state using kernel-provided
|
|
||||||
# random data every 128KiB of output.
|
|
||||||
if osrandom_source == 'winrandom' or sys.platform == 'win32':
|
|
||||||
self.get_bytes(128*1024) # discard 128 KiB of output
|
|
||||||
|
|
||||||
def randomize(self, N=0):
|
def randomize(self, N=0):
|
||||||
self.stir()
|
self.stir()
|
||||||
|
@ -72,22 +64,75 @@ class BaseOSRandomPool(object):
|
||||||
def add_event(self, s=None):
|
def add_event(self, s=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class WinrandomOSRandomPool(BaseOSRandomPool):
|
|
||||||
|
class WinRandomPool(BaseOSRandomPool):
|
||||||
|
"""RandomPool that uses the C{winrandom} module for input"""
|
||||||
def __init__(self, numbytes=160, cipher=None, hash=None):
|
def __init__(self, numbytes=160, cipher=None, hash=None):
|
||||||
self._wr = winrandom.new()
|
self._wr = winrandom.new()
|
||||||
self.get_bytes = self._wr.get_bytes
|
self.get_bytes = self._wr.get_bytes
|
||||||
self.randomize()
|
self.randomize()
|
||||||
|
|
||||||
class UrandomOSRandomPool(BaseOSRandomPool):
|
def stir(self, s=''):
|
||||||
|
_workaround_windows_cryptgenrandom_bug(self)
|
||||||
|
|
||||||
|
|
||||||
|
class DevUrandomPool(BaseOSRandomPool):
|
||||||
|
"""RandomPool that uses the C{/dev/urandom} special device node for input"""
|
||||||
def __init__(self, numbytes=160, cipher=None, hash=None):
|
def __init__(self, numbytes=160, cipher=None, hash=None):
|
||||||
self.get_bytes = urandom
|
|
||||||
self.randomize()
|
self.randomize()
|
||||||
|
|
||||||
if osrandom_source in ("/dev/urandom", "os.urandom"):
|
def get_bytes(self, n):
|
||||||
OSRandomPool = UrandomOSRandomPool
|
bytes = ""
|
||||||
elif osrandom_source == "winrandom":
|
while len(bytes) < n:
|
||||||
OSRandomPool = WinrandomOSRandomPool
|
bytes += _dev_urandom.read(n - len(bytes))
|
||||||
else:
|
return bytes
|
||||||
raise AssertionError("Unrecognized osrandom_source %r" % (osrandom_source,))
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Detect default random number source
|
||||||
|
##
|
||||||
|
osrandom_source = None
|
||||||
|
|
||||||
|
# Try /dev/urandom
|
||||||
|
if osrandom_source is None and _dev_urandom is not None:
|
||||||
|
osrandom_source = "/dev/urandom"
|
||||||
|
DefaultRandomPoolClass = DevUrandomPool
|
||||||
|
|
||||||
|
# Try winrandom
|
||||||
|
if osrandom_source is None and winrandom is not None:
|
||||||
|
osrandom_source = "winrandom"
|
||||||
|
DefaultRandomPoolClass = WinRandomPool
|
||||||
|
|
||||||
|
# Give up
|
||||||
|
if osrandom_source is None:
|
||||||
|
raise ImportError("Cannot find OS entropy source")
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Define wrapper class
|
||||||
|
##
|
||||||
|
|
||||||
|
class OSRandomPool(object):
|
||||||
|
"""RandomPool wrapper.
|
||||||
|
|
||||||
|
The C{randpool} attribute of this object may be modified by users of this class at runtime.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, instance=None):
|
||||||
|
if instance is None:
|
||||||
|
instance = DefaultRandomPoolClass()
|
||||||
|
self.randpool = instance
|
||||||
|
|
||||||
|
def stir(self, s=''):
|
||||||
|
self.randpool.stir(s)
|
||||||
|
|
||||||
|
def randomize(self, N=0):
|
||||||
|
self.randpool.randomize(N)
|
||||||
|
|
||||||
|
def add_event(self, s=None):
|
||||||
|
self.randpool.add_event(s)
|
||||||
|
|
||||||
|
def get_bytes(self, N):
|
||||||
|
return self.randpool.get_bytes(N)
|
||||||
|
|
||||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
# vim:set ts=4 sw=4 sts=4 expandtab:
|
||||||
|
|
Loading…
Reference in New Issue