Doug Barnes wrote:

> You only have so much entropy that's available on a given machine at a
> given time. From the same manpage, you can see that if you have access
> to more entropy than /dev/random knows about normally, you can write it
> back to /dev/random (they give an example) but at the end of the day,
> you need to decide -- is it more important that the SessionIDs be safe
> from an opponent with vast computational and/or intercept capabilities,
> or is it more important to not block. My guess is that in the vast
> majority of cases it's more important to not block.

I think you're right on the money there. It's all about choices.
Therefore, I've prepared a patch that can utilise both /dev/random (for
extremely paranoid) and /dev/urandom for not so paranoid, which should
be the default. Then the people can make their choices (I've included
warnings about /dev/random). /dev/urandom should be at least as good as
java.security.SecureRandom, which is also computational and was the
reason for this patch in the first place (its slowness on Linux, that
is).

> Hope this is helpful!

This was very helpful and I belive should be added to the FAQ's of
Tomcat so that people understand what they are dealing with as far as
the session ID's are concerned. Maybe you could produce a little patch
along those lines ;-)

I was actually surprised that the SessionID was so 'short', but I don't
understand the implications down the 'food chain', so I can't comment on
that one. Some of the real Tomcat developers are probably a better bet.

Here is the patch (I had to move some of the code to engineInit,
hopefully without breaking too many things):
-------- Cut ---------------------------------------------------------

---
jakarta-tomcat-3.3-build/src/share/org/apache/tomcat/modules/session/SessionId
Generator.java        Mon Apr 16 21:28:34 2001
+++
jakarta-tomcat-3.3-src-cvs-debug/src/share/org/apache/tomcat/modules/session
/SessionIdGenerator.java        Mon Apr 16 21:40:20 2001
@@ -96,6 +96,8 @@
     String randomClassName=null;
     Random randomSource=null;
     DataInputStream randomIS=null;
+    boolean beParanoid=false;
+    boolean useDevRandom=false;
     
     static Jdk11Compat jdk11Compat=Jdk11Compat.getJdkCompat();
     
@@ -109,18 +111,26 @@
        randomSource=createRandomClass( randomClassName );
     }
 
-    /** Use /dev/random special device. This is new code, but may
reduce the
-     *  big delay in generating the random
+    /** When using special device random generator, be paranoid and
+     *  use /dev/random. When this option is not set (default), the
+     *  device /dev/urandom is used, which should be at least as safe
+     *  as java.security.SecureRandom.
+     *
+     *  Reads to /dev/random might block until additional environmental
+     *  noise is gathered and this can cause problems (ie. Tomcat might
+     *  hang until such noise is generated).
+     *  USE WITH CAUTION!!!
+     */
+    public void setBeParanoid( boolean p ) {
+        beParanoid = p;
+    }
+    
+
+    /** Use special device to generate random. This is new code,
+     *  but may reduce the big delay in generating the random.
      */
     public void setUseDevRandom( boolean u ) {
-       if( ! u ) return;
-       try {
-           randomIS= new DataInputStream( new
FileInputStream("/dev/random"));
-           randomIS.readLong();
-           log( "Opening /dev/random");
-       } catch( IOException ex ) {
-           randomIS=null;
-       }
+        useDevRandom = u;
     }
     
     
@@ -141,6 +151,23 @@
     /** Init session management stuff for this context. 
      */
     public void engineInit(ContextManager cm) throws TomcatException {
+        if( useDevRandom ){
+            String device="/dev/urandom";
+
+            if( beParanoid )
+                device="/dev/random";
+
+           try {
+               randomIS= new DataInputStream( new FileInputStream(
device ));
+               randomIS.readLong();
+               log( "Opening " + device );
+           } catch( IOException ex ) {
+               randomIS=null;
+           }
+        }
+
+       /* The following code gets executed even if randomIS is null due
to
+           IOException above, so we are covered */
        if( randomSource==null && randomIS==null ) {
            String randomClass=(String)cm.getProperty("randomClass" );
            if( randomClass==null ) {
@@ -261,7 +288,7 @@
        if( devRandomIS!=null ) {
            try {
                n=devRandomIS.readLong();
-               System.out.println("Getting /dev/random " + n );
+                System.out.println( "Getting from random device " + n
);
            } catch( IOException ex ) {
                ex.printStackTrace();
            }

-------- Cut ---------------------------------------------------------

Thanks,
Bojan

Reply via email to