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