Merge jv
authorMerge Script
Fri, 25 Mar 2016 06:53:03 +0100
branchjv
changeset 3778 e45a8bf6639d
parent 3774 1fa5447ac076 (current diff)
parent 3777 5315f5caf69a (diff)
child 3786 1a036255aa50
Merge
--- a/Random.st	Thu Mar 24 07:05:34 2016 +0100
+++ b/Random.st	Fri Mar 25 06:53:03 2016 +0100
@@ -77,6 +77,11 @@
     =======================================================================================
     DO NOT USE THIS GENERATOR FOR CRYPTOGRAPHY OR OTHER SECURITY RELATED WORK, 
     because linear congruential generators are predictable and can be broken easily!!
+
+    Smalltalk/X includes a better generator named RandomGenerator, which uses the best
+    available generator of the system (either OS-random, /dev/random or as a less dangerous
+    fallback, an RC4-based random generator.
+    Please use that one.
     =======================================================================================
 
     Notice: although being included here,
--- a/RandomGenerator.st	Thu Mar 24 07:05:34 2016 +0100
+++ b/RandomGenerator.st	Fri Mar 25 06:53:03 2016 +0100
@@ -14,10 +14,10 @@
 "{ NameSpace: Smalltalk }"
 
 Random subclass:#RandomGenerator
-	instanceVariableNames:''
-	classVariableNames:'RandFile SharedRandomGenerator'
-	poolDictionaries:''
-	category:'Magnitude-Numbers'
+        instanceVariableNames:''
+        classVariableNames:'HasOSRandom RandFile SharedRandomGenerator RandomDevicePathes'
+        poolDictionaries:''
+        category:'Magnitude-Numbers'
 !
 
 !RandomGenerator class methodsFor:'documentation'!
@@ -38,16 +38,16 @@
 
 documentation
 "
+    This is a Random number generator, 
+    which uses either a OS random number generator or /dev/urandom,
+    or an ST/X internal random number generator.
+
     Warning: this generator should not be used for cryptographic work 
-    unless: 
+    UNLESS: 
         1) you are running on linux, solaris or osx,
         2) you have a working /dev/urandom.
         3) you can trust your /dev/urandom (I don't really know if any/all of them are good)
 
-    This is a Random number generator, 
-    which uses either a OS random number generator (/dev/urandom),
-    or an ST/X internal random number generator.
-
     [author:]
         Stefan Vogel
 
@@ -58,7 +58,9 @@
     [instance variables:]
 
     [class variables:]
-        RandFile        the FileStream we get random numbers from
+        HasOSRandom     true if the operatingSystem supports random numbers
+        RandFile        (if HasOSRandom is false and non-nil) the FileStream (/dev/random),
+                        we get random numbers from
 "
 ! !
 
@@ -77,17 +79,16 @@
 
     |randDevName|
 
-    RandFile isStream ifTrue:[
+    RandFile notNil ifTrue:[
         RandFile close.
+        RandFile := nil.            
     ].
 
-    RandFile := false.              "prevent retry"
-
     randDevName := self randPath.
     randDevName notNil ifTrue:[
         randDevName := randDevName asFilename.
         randDevName isReadable ifTrue:[
-            RandFile := randDevName readStream
+            RandFile := randDevName readStream.
         ].
     ].
 ! !
@@ -109,31 +110,36 @@
         ^ SharedRandomGenerator.
     ].
 
-    [
-        "fetch a random byte - and check if the OS generator works"
-        result := OperatingSystem randomBytesInto:1.
-    ] on:PrimitiveFailure do:[:ex| ].
-
-    result notNil ifTrue:[
+    HasOSRandom == nil ifTrue:[
+        "/ see if there is an OS or CPU-random generator
+        [
+            "fetch a random byte - and check if the OS generator works"
+            result := OperatingSystem randomBytesInto:1.
+        ] on:PrimitiveFailure do:[:ex| ].
+        HasOSRandom := result notNil.
+    ].
+    
+    HasOSRandom ifTrue:[
         "OperatingSystem knows how to get random bytes"
-        RandFile := true.
         SharedRandomGenerator := self basicNew.
         ^ SharedRandomGenerator.
-    ] ifFalse:[
-        RandFile isNil ifTrue:[
-            self openRandFile.
-        ].
-        RandFile isStream ifTrue:[
-            SharedRandomGenerator := self basicNew.
-            ^ SharedRandomGenerator.
-        ].
+    ].
+    
+    RandFile isNil ifTrue:[
+        self openRandFile.
+    ].
+    RandFile notNil ifTrue:[
+        SharedRandomGenerator := self basicNew.
+        ^ SharedRandomGenerator.
     ].
 
+    "/ fallback    
     Rc4Cipher notNil ifTrue:[
         SharedRandomGenerator := Rc4Cipher random.
         ^ SharedRandomGenerator.
     ].
 
+    "/ last fallback - not very good   
     SharedRandomGenerator := Random sharedGenerator.
     ^ SharedRandomGenerator.
 ! !
@@ -151,10 +157,14 @@
 update:something with:aParameter from:changedObject
     "handle image restarts and flush any device resource handles"
 
-    SharedRandomGenerator := nil.
-    RandFile notNil ifTrue:[
-        RandFile := nil.
-        self openRandFile.
+    (changedObject == ObjectMemory) ifTrue:[
+        (something == #returnFromSnapshot) ifTrue:[
+            SharedRandomGenerator notNil ifTrue:[
+                SharedRandomGenerator := nil.
+                HasOSRandom := RandFile := nil.
+                self new. "/ opens a new sharedGenerator
+            ]
+        ]
     ].
 ! !
 
@@ -163,8 +173,34 @@
 randPath
     "path to a file/device that is a source or random numbers"
 
-    OperatingSystem isUNIXlike ifTrue:[^ '/dev/urandom'].
+    |pathesOrNil|
+
+    pathesOrNil := self randomDevicePathes.
+    pathesOrNil notNil ifTrue:[
+        pathesOrNil do:[:triedRandom |
+            triedRandom asFilename exists ifTrue:[
+                ^ triedRandom
+            ]
+        ].    
+    ].
     ^ nil.
+!
+
+randomDevicePathes
+    "pathes to look for OS sources of random numbers"
+
+    RandomDevicePathes notNil ifTrue:[^ RandomDevicePathes].
+    OperatingSystem isUNIXlike ifTrue:[
+        ^ #( '/dev/urandom' '/dev/random' )
+    ].
+    ^ nil.
+!
+
+randomDevicePathes:aCollectionOfpathesOrNil
+    "configurable pathes to look for OS sources of random numbers.
+     (can be set during early startup in an rc-file)"
+
+    RandomDevicePathes := aCollectionOfpathesOrNil.
 ! !
 
 !RandomGenerator methodsFor:'basic reading'!
@@ -172,10 +208,9 @@
 nextByte
     "get the next random byte"
 
-    RandFile == true ifTrue:[
+    HasOSRandom == true ifTrue:[
         ^ OperatingSystem randomBytesInto:1.
     ].
-
     RandFile isOpen ifFalse:[
         self class openRandFile.
     ].
@@ -204,7 +239,7 @@
 nextBytes:cnt
     "get the next cnt random bytes"
 
-    RandFile == true ifTrue:[
+    HasOSRandom == true ifTrue:[
         ^ OperatingSystem randomBytesInto:(ByteArray new:cnt).
     ].
     RandFile isOpen ifFalse:[
@@ -299,7 +334,7 @@
 
     intSize := SmallInteger maxBytes.
 
-    RandFile == true ifTrue:[
+    HasOSRandom == true ifTrue:[
         ^ OperatingSystem randomBytesInto:intSize.
     ].