patch from dwayne litzenberger to fix the PRNG to be more resilient when using windows, and some forking/threading environments.
This commit is contained in:
parent
38835bc24c
commit
84eebc02f6
|
@ -95,22 +95,10 @@ CONNECTION_FAILED_CODE = {
|
||||||
DISCONNECT_SERVICE_NOT_AVAILABLE, DISCONNECT_AUTH_CANCELLED_BY_USER, \
|
DISCONNECT_SERVICE_NOT_AVAILABLE, DISCONNECT_AUTH_CANCELLED_BY_USER, \
|
||||||
DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 7, 13, 14
|
DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 7, 13, 14
|
||||||
|
|
||||||
|
from osrandom import OSRandomPool
|
||||||
from Crypto.Util.randpool import PersistentRandomPool, RandomPool
|
|
||||||
|
|
||||||
# keep a crypto-strong PRNG nearby
|
# keep a crypto-strong PRNG nearby
|
||||||
import os
|
randpool = OSRandomPool()
|
||||||
try:
|
|
||||||
randpool = PersistentRandomPool(os.path.join(os.path.expanduser('~'), '/.randpool'))
|
|
||||||
except:
|
|
||||||
# the above will likely fail on Windows - fall back to non-persistent random pool
|
|
||||||
randpool = RandomPool()
|
|
||||||
|
|
||||||
try:
|
|
||||||
randpool.randomize()
|
|
||||||
except:
|
|
||||||
# earlier versions of pyCrypto (pre-2.0) don't have randomize()
|
|
||||||
pass
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
if sys.version_info < (2, 3):
|
if sys.version_info < (2, 3):
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: ascii -*-
|
||||||
|
# Copyright (C) 2008 Dwayne C. Litzenberger <dlitz@dlitz.net>
|
||||||
|
#
|
||||||
|
# This file is part of paramiko.
|
||||||
|
#
|
||||||
|
# Paramiko is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
# Software Foundation; either version 2.1 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
|
# details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Detect an OS random number source
|
||||||
|
osrandom_source = None
|
||||||
|
|
||||||
|
# Try os.urandom
|
||||||
|
if osrandom_source is None:
|
||||||
|
try:
|
||||||
|
from os import urandom
|
||||||
|
osrandom_source = "os.urandom"
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Try winrandom
|
||||||
|
if osrandom_source is None:
|
||||||
|
try:
|
||||||
|
from Crypto.Util import winrandom
|
||||||
|
osrandom_source = "winrandom"
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Try /dev/urandom
|
||||||
|
if osrandom_source is None:
|
||||||
|
try:
|
||||||
|
_dev_urandom = open("/dev/urandom", "rb", 0)
|
||||||
|
def urandom(bytes):
|
||||||
|
return _def_urandom.read(bytes)
|
||||||
|
osrandom_source = "/dev/urandom"
|
||||||
|
except (OSError, IOError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Give up
|
||||||
|
if osrandom_source is None:
|
||||||
|
raise ImportError("Cannot find OS entropy source")
|
||||||
|
|
||||||
|
class BaseOSRandomPool(object):
|
||||||
|
def __init__(self, numbytes=160, cipher=None, hash=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stir(self, s=''):
|
||||||
|
# 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.
|
||||||
|
if osrandom_source == 'winrandom' or sys.platform == 'win32':
|
||||||
|
self.get_bytes(128*1024) # discard 128 KiB of output
|
||||||
|
|
||||||
|
def randomize(self, N=0):
|
||||||
|
self.stir()
|
||||||
|
|
||||||
|
def add_event(self, s=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class WinrandomOSRandomPool(BaseOSRandomPool):
|
||||||
|
def __init__(self, numbytes=160, cipher=None, hash=None):
|
||||||
|
self._wr = winrandom.new()
|
||||||
|
self.get_bytes = self._wr.get_bytes
|
||||||
|
self.randomize()
|
||||||
|
|
||||||
|
class UrandomOSRandomPool(BaseOSRandomPool):
|
||||||
|
def __init__(self, numbytes=160, cipher=None, hash=None):
|
||||||
|
self.get_bytes = urandom
|
||||||
|
self.randomize()
|
||||||
|
|
||||||
|
if osrandom_source in ("/dev/urandom", "os.urandom"):
|
||||||
|
OSRandomPool = UrandomOSRandomPool
|
||||||
|
elif osrandom_source == "winrandom":
|
||||||
|
OSRandomPool = WinrandomOSRandomPool
|
||||||
|
else:
|
||||||
|
raise AssertionError("Unrecognized osrandom_source %r" % (osrandom_source,))
|
||||||
|
|
||||||
|
# vim:set ts=4 sw=4 sts=4 expandtab:
|
Loading…
Reference in New Issue