cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
costin 01/09/06 21:52:18 Modified:src/share/org/apache/tomcat/modules/session SessionIdGenerator.java Log: Usefull for debugging session creation. Revision ChangesPath 1.6 +1 -0 jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionIdGenerator.java Index: SessionIdGenerator.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionIdGenerator.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- SessionIdGenerator.java 2001/08/21 05:38:24 1.5 +++ SessionIdGenerator.java 2001/09/07 04:52:18 1.6 @@ -145,6 +145,7 @@ if( state==ServerSession.STATE_NEW ) { String jsIdent=req.getJvmRoute(); String newId=createNewId( jsIdent ); + if(debug>0) log("Generate new session id " + newId ); sess.getId().setString( newId ); } return state;
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
costin 01/08/20 22:38:24 Modified:src/share/org/apache/tomcat/modules/session SessionIdGenerator.java Log: Update for the fix in compat. Revision ChangesPath 1.5 +1 -1 jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionIdGenerator.java Index: SessionIdGenerator.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionIdGenerator.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- SessionIdGenerator.java 2001/04/21 19:33:11 1.4 +++ SessionIdGenerator.java 2001/08/21 05:38:24 1.5 @@ -177,7 +177,7 @@ // We're in a sandbox... PriviledgedIdGenerator di = new PriviledgedIdGenerator(this, jsIdent); try { - newId= (String)jdk11Compat.doPrivileged(di); + newId= (String)jdk11Compat.doPrivileged(di, jdk11Compat.getAccessControlContext()); } catch( Exception ex ) { newId=null; }
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
costin 01/04/21 12:33:11 Modified:src/etc server.xml src/share/org/apache/tomcat/modules/session SessionIdGenerator.java Log: Fix server.xml with the right name of the attribute. Delay Random creation ( each random creates a thread ) That concludes the fix of 1418, no hanging threads after shutdown. Note that shutdown/init is not completely debugged or tested - but at least there are no gross errors and kind-of works. In time things will improve ( the assumption is you don't do a soft restart every hour ). Soft restart is better in many cases - like when you embed tomcat in an application, as it doesn't require to restart the java vm and should clean up all the resources and return to a stable state. Of course, that requires that all modules respect the server state and clean up resources. Revision ChangesPath 1.74 +1 -6 jakarta-tomcat/src/etc/server.xml Index: server.xml === RCS file: /home/cvs/jakarta-tomcat/src/etc/server.xml,v retrieving revision 1.73 retrieving revision 1.74 diff -u -r1.73 -r1.74 --- server.xml2001/04/21 17:45:40 1.73 +++ server.xml2001/04/21 19:33:10 1.74 @@ -6,11 +6,6 @@ will be used, and if not set "." will be used. webapps/, work/ and log/ will be relative to this ( unless set explicitely to absolute paths ). - You can also specify a "randomClass" attribute, which determines - a subclass of java.util.Random will be used for generating session IDs. - By default this is "java.security.SecureRandom". - Specifying "java.util.Random" will speed up Tomcat startup, - but it will cause sessions to be less secure. --> @@ -41,7 +36,7 @@ +randomFile="/dev/urandom" /> 1.4 +19 -26 jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionIdGenerator.java Index: SessionIdGenerator.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionIdGenerator.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- SessionIdGenerator.java 2001/04/21 17:45:40 1.3 +++ SessionIdGenerator.java 2001/04/21 19:33:11 1.4 @@ -108,7 +108,6 @@ public final void setRandomClass(String randomClass) { this.randomClassName=randomClass; - randomSource=createRandomClass( randomClassName ); } /** Use /dev/random-type special device. This is new code, but may reduce the @@ -157,15 +156,6 @@ /** Init session management stuff for this context. */ public void engineInit(ContextManager cm) throws TomcatException { - if( randomSource==null ) { - // backward compatibility - String randomClass=(String)cm.getProperty("randomClass" ); - // set a reasonable default - if( randomClass==null ) { - randomClass="java.security.SecureRandom"; - } - setRandomClass(randomClass); - } } @@ -207,24 +197,27 @@ } } -private Random createRandomClass( String s ) { - Random randomSource=null; - String className = s; - if (className != null) { - try { - Class randomClass = Class.forName(className); - long time=System.currentTimeMillis(); - randomSource = (java.util.Random)randomClass.newInstance(); - time = System.currentTimeMillis() - time; - // Since this can take a lot of time, let the user know - log( "Created random " + s + " in " + time ); - } catch (Exception e) { - e.printStackTrace(); +/** Create the random generator using the configured class name, and + * defaulting to java.security.SecureRandom + */ +private void createRandomClass() { + if( randomClassName==null ) { + // backward compatibility + randomClassName=(String)cm.getProperty("randomClass" ); + // set a reasonable default + if( randomClassName==null ) { + randomClassName="java.security.SecureRandom"; } } + try { + Class randomClass = Class.forName(randomClassName); + randomSource = (java.util.Random)randomClass.newInstance(); + } catch (Exception e) { + log("SessionIdGenerator.createRandomClass", e); + } if (randomSource == null) randomSource = new java.security.SecureRandom(); - return randomSource; + log( "Created random class " + randomSource.getClass().
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
costin 01/04/21 10:45:41 Modified:src/etc server.xml src/share/org/apache/tomcat/modules/session SessionIdGenerator.java Log: Check in for 1385, from [EMAIL PROTECTED] (Bojan Smojver). Any random file can be specified. The default ( in server.xml ) is to use /dev/urandom if it exists. To minimize user configuration we do set it in server.xml and let the module decide if it exists or not. The difference in speed is quite significant - instead of waiting 4-5 seconds on the first JSP page ( or servlet with session ) now we have instant response. Submitted by: [EMAIL PROTECTED] (Bojan Smojver) Revision ChangesPath 1.73 +2 -1 jakarta-tomcat/src/etc/server.xml Index: server.xml === RCS file: /home/cvs/jakarta-tomcat/src/etc/server.xml,v retrieving revision 1.72 retrieving revision 1.73 diff -u -r1.72 -r1.73 --- server.xml2001/03/24 06:49:29 1.72 +++ server.xml2001/04/21 17:45:40 1.73 @@ -40,7 +40,8 @@ - + 1.3 +44 -29 jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionIdGenerator.java Index: SessionIdGenerator.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionIdGenerator.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- SessionIdGenerator.java 2001/04/10 06:58:22 1.2 +++ SessionIdGenerator.java 2001/04/21 17:45:40 1.3 @@ -95,7 +95,9 @@ String randomClassName=null; Random randomSource=null; + DataInputStream randomIS=null; +String devRandomSource="/dev/urandom"; static Jdk11Compat jdk11Compat=Jdk11Compat.getJdkCompat(); @@ -109,15 +111,29 @@ randomSource=createRandomClass( randomClassName ); } -/** Use /dev/random special device. This is new code, but may reduce the - * big delay in generating the random - */ -public void setUseDevRandom( boolean u ) { - if( ! u ) return; +/** Use /dev/random-type special device. This is new code, but may reduce the + * big delay in generating the random. + * + * You must specify a path to a random generator file. Use /dev/urandom + * for linux ( or similar ) systems. Use /dev/random for maximum security + * ( it may block if not enough "random" exist ). You can also use + * a pipe that generates random. + * + * The code will check if the file exists, and default to java Random + * if not found. There is a significant performance difference, very + * visible on the first call to getSession ( like in the first JSP ) + * - so use it if available. + */ +public void setRandomFile( String s ) { + // as a hack, you can use a static file - and genarate the same + // session ids ( good for strange debugging ) try { - randomIS= new DataInputStream( new FileInputStream("/dev/random")); + devRandomSource=s; + File f=new File( devRandomSource ); + if( ! f.exists() ) return; + randomIS= new DataInputStream( new FileInputStream(f)); randomIS.readLong(); - log( "Opening /dev/random"); + log( "Opening " + devRandomSource ); } catch( IOException ex ) { randomIS=null; } @@ -141,8 +157,10 @@ /** Init session management stuff for this context. */ public void engineInit(ContextManager cm) throws TomcatException { - if( randomSource==null && randomIS==null ) { + if( randomSource==null ) { + // backward compatibility String randomClass=(String)cm.getProperty("randomClass" ); + // set a reasonable default if( randomClass==null ) { randomClass="java.security.SecureRandom"; } @@ -161,13 +179,13 @@ * JSP or servlet may not have sufficient Permissions. */ String newId; + if( System.getSecurityManager() == null ) { - newId= SessionIdGenerator.getIdentifier(randomSource, randomIS, jsIdent); + newId= getIdentifier(jsIdent); return newId; } // We're in a sandbox... - PriviledgedIdGenerator di = new - PriviledgedIdGenerator(randomSource,randomIS, jsIdent); + PriviledgedIdGenerator di = new PriviledgedIdGenerator(this, jsIdent); try { newId= (String)jdk11Compat.doPrivileged(di); } catch( Exception ex ) { @@ -178,18 +196,14 @@ // Sandbox support static class PriviledgedIdGenerator extends Action { - private Random randomSource; - pr
Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
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.javaMon Apr 16 21:28:34 2001 +++ jakarta-tomcat-3.3-src-cvs-debug/src/share/org/apache/tomcat/modules/session /SessionIdGenerator.javaMon 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
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
> I'm aware of /dev/urandom being non-blocking, but my understanding of > /dev/urandom is that it is not cryptographicaly secure. ... > Any thoughts on that? [perhaps more thoughts than anyone here cares to hear, but what the heck] 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. /dev/urandom is going to do as good of a job of stretching the available entropy as any other computationally reasonable approach that you could implement. My summary of the criticism of /dev/urandom is that it might not be a hot idea to use it to generate a long-lived private/public key pair, but I can't see how you can do any better if you need a long, reliable stream of randomness (e.g. a whole bunch of hard-to-predict SessionIDs.) Here's this from the source code of linux/drivers/char/random.c: * When random bytes are desired, they are obtained by taking the SHA * hash of the contents of the "entropy pool". The SHA hash avoids * exposing the internal state of the entropy pool. It is believed to * be computationally infeasible to derive any useful information * about the input of SHA from its output. Even if it is possible to * analyze SHA in some clever way, as long as the amount of data * returned from the generator is less than the inherent entropy in * the pool, the output data is totally unpredictable. For this * reason, the routine decreases its internal estimate of how many * bits of "true randomness" are contained in the entropy pool as it * outputs random numbers. * * If this estimate goes to zero, the routine can still generate * random numbers; however, an attacker may (at least in theory) be * able to infer the future output of the generator from prior * outputs. This requires successful cryptanalysis of SHA, which is * not believed to be feasible, but there is a remote possibility. * Nonetheless, these numbers should be useful for the vast majority * of purposes. Let's think about how someone might attack a weakness in a SessionID generator. Assume that the victim computer's version of Linux has a bug that causes /dev/urandom to be seeded with all zeroes every time it boots, and that it never adds any entropy. If the opponent guessed or knew that this was the case, then the opponent could connect to the webserver, get a SessionID, and would then be able to make very good guesses about what other SessionIDs were currently in use. (By starting from all zeroes, and applying the algorithm until the obtained SessionID was reached.) Assuming that some sort of "entropy" is being added, the next thing the attacker could do is to come up with a way to either predict what is being added as "entropy", or at least guess at it with substantially more effectiveness than random chance. One early version of this many years ago was when Ian Goldberg and Dave Wagner discovered that an early version of Netscape's web server was seeding their random number generator with nothing more than the time and the PID, both of which were sufficiently easy to guess at that it was quite easy to predict what session keys would be generated. However, unless the attacker has successfully cryptanalyzed SHA (which would have far greater consequences than the ability to predict SessionIDs in Tomact :-) the attacker is going to have to successfully model ALL entropy ever added in. After the first eighty or so bits of "real entropy," it's going to be easier to just guess random SessionIDs (with some cleverness about predicting the time and the session counter, which are both predictable and inter-related) Note that the chance of guessing _a_ session (as opposed to a particular session) goes up steadily with the total number of valid sessions. (Let's say, for the sake of example, that you have a 1/2^80 chance of guessing a particular session; if you have 2048 valid sessions, it improves to a 1/2^69 chance.) For this reason, if you're really paranoid, you'll want to increase the part of the SessionID from /dev/urandom to 128 bits and ditch the use of the time (unless it has semantic value down the food chain that I'm missing.) This way, as long as you have more than 128 bits of "real entropy", it's going to be "easier" for the attacker to make the on average num_sessions/2^127 guesses needed to find a valid SessionID. Hope this is helpful! Cheers, Doug
Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
Doug Barnes wrote: > The answer to these arguments are: use /dev/urandom, not > /dev/random. It's going to do as good or better than anything > you're going to seed with /dev/random, and IT WILL NOT BLOCK. > > I may be wrong (I'm just starting to poke around in related > code) but it doesn't look like the time and the session counter > values you're appending to create the SessionID have any > subsequent meaning. If you're looking for more entropy, I'd > ditch the time and use another long's worth of /dev/urandom. I'm aware of /dev/urandom being non-blocking, but my understanding of /dev/urandom is that it is not cryptographicaly secure. From the Linux random manual page (man 4 random): When read, /dev/urandom device will return as many bytes as are requested. As a result, if there is not sufficient entropy in the entropy pool, the returned values are theo retically vulnerable to a cryptographic attack on the algorithms used by the driver. Any thoughts on that? Bojan
Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
Bojan, et. al.: The answer to these arguments are: use /dev/urandom, not /dev/random. It's going to do as good or better than anything you're going to seed with /dev/random, and IT WILL NOT BLOCK. I may be wrong (I'm just starting to poke around in related code) but it doesn't look like the time and the session counter values you're appending to create the SessionID have any subsequent meaning. If you're looking for more entropy, I'd ditch the time and use another long's worth of /dev/urandom. With respect to leaving the device open, this seems a lot better than opening and closing it every time you need to cough up a SessionID. I can't see how this could have any possible downside except for using up a file descriptor. Cheers, Doug
Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
[EMAIL PROTECTED] wrote: > As pointed out by someone else, at some point on a system that is not > busy processes will hang on /dev/random waiting for their next chance to > catch some randomness generated by things like mouse moves. And if you > are on a server, the mouse may never move. There will be other trips > into the kernel, but I think a better strategy would be to get a random > seed and close your particular connection. What do you think? I think I've covered that one in one of my other e-mails, but here is the summary: - we should document this properly so that all users can make an informed decision (*very important*, otherwise there's going to be tons of e-mail about sudden hangs of Tomcat if this was a bad idea) - if I'm pointed towards the right document I'll submit a patch - on a real life server the requests to Apache/Tomcat are coming through network cards which generates 'kernel noise' and therefore /dev/random shouldn't really block; you don't have to move the mouse or touch the keyboard to get random data, any kernel driver counts (I just verified that by pinging my Linux box from another box); usually the disk is touched as well when you hit the web pages - the next problem might be a heavily loaded box (ie. will there be enough random data for all sessions) - usually on a heavily loaded machine there will be plenty of random data, so I don't think heavily loaded boxes should be an issue - I don't think that opening and closing the /dev/random would make much difference except for the fact that opening/closing might generate some random data in the kernel; I'll give here one bad scenario with /dev/random being constantly opened/closed: we open the /dev/random (let's say this generates some random data) and then attempt to read that data, but there wasn't generated and the read blocks - back to square one :-( Having said all that, it is my belief everyone should test this in their particular situation to verify if this approach is good for them or not. Although I can qualify as a Linux user and hardly as a Linux admin, I'm nowhere close to being a kernel expert. So all of the above could be pure BS (did you notice these are my initials - funny, ha ;-) Bojan
Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
On 11 Apr, Bojan Smojver wrote: > [EMAIL PROTECTED] wrote: >> Given that tomcat should run for days or weeks at a time, I don't >> think you want to keep /dev/random open. There maybe other processes >> that also need random data during that time. > > Are you really sure that other processes are unable to use /dev/random > while Tomcat is using it? It sure doesn't worry my Linux machine. Try > multiple cats on /dev/random. Works just fine. Or maybe I missed > something... > > Bojan As pointed out by someone else, at some point on a system that is not busy processes will hang on /dev/random waiting for their next chance to catch some randomness generated by things like mouse moves. And if you are on a server, the mouse may never move. There will be other trips into the kernel, but I think a better strategy would be to get a random seed and close your particular connection. What do you think? =eas=
Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
[EMAIL PROTECTED] wrote: > Given that tomcat should run for days or weeks at a time, I don't think > you want to keep /dev/random open. There maybe other processes that also > need random data during that time. Are you really sure that other processes are unable to use /dev/random while Tomcat is using it? It sure doesn't worry my Linux machine. Try multiple cats on /dev/random. Works just fine. Or maybe I missed something... Bojan
Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
On 10 Apr, Bojan Smojver wrote: > [EMAIL PROTECTED] wrote: > >> The patch allows systems that have /dev/random to use it instead of >> the slower Random. Instead of checking for OS==linux ( as in >> submited patch ) we use an option of the module. > > Cool. > >> The code if the option "useDevRandom" is not set is the same as >> before. If you set useDevRandom="true" then /dev/random will be >> used. > > Very cool. Where do I whack this option? server.xml? I know it must be > a silly question to ask on Tomcat Dev list... :-) > >> ( Bojan - please review and let me know if it is not what you >> intended, I'm not sure if the /dev/ransom needs to be closed/open >> all the time ) > > I don't think it needs to be opened/closed all the time. Honestly I > can't say for sure. There must be some true Linux experts out there > that can enlighten us on that one. My knowledge is limited to the > manual page > (man 4 random) where this file is explained as giving secure random > numbers. If 'entropy pool' is empty, /dev/random will block until this > pool is filled (ie. until there are events in the kernel that can fill > the pool again). The pool gets filled by the 'noise' produced by > drivers and other kernel sources. Whether opening and closing of the > stream makes a difference, I really couldn't say, but it seem to me > that it shouldn't (except for the fact that code execution itself > might fill the pool). > >>From Tomcat's perspective it's really better to keep it open. It's >>going > to run faster. I'm guessing all open streams get closed when Tomcat is > shut down anyway, so that's fine. > > And thanks for acting so quickly on this! > > Bojan Given that tomcat should run for days or weeks at a time, I don't think you want to keep /dev/random open. There maybe other processes that also need random data during that time. =eas=
Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
On Tue, 10 Apr 2001, Bojan Smojver wrote: > > The code if the option "useDevRandom" is not set is the same as before. > > If you set useDevRandom="true" then /dev/random will be used. > > Very cool. Where do I whack this option? server.xml? I know it must be a > silly question to ask on Tomcat Dev list... :-) > >From Tomcat's perspective it's really better to keep it open. It's going > to run faster. I'm guessing all open streams get closed when Tomcat is > shut down anyway, so that's fine. > > And thanks for acting so quickly on this! Thanks for sending the patches :-) Note that the option will be disabled by default ( I'm even thinking of creating a new DevRandomGenerator and moving it in proposals, but the code doesn't affect in any way "normal" random generation and is simple enough). The main question is what happens on high load - can /dev/random generate randoms fast enough ? If not, probably we should use it only to initialize the java random genearator. Costin
Re: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
[EMAIL PROTECTED] wrote: > The patch allows systems that have /dev/random to use it instead of the > slower Random. Instead of checking for OS==linux ( as in submited patch ) > we use an option of the module. Cool. > The code if the option "useDevRandom" is not set is the same as before. > If you set useDevRandom="true" then /dev/random will be used. Very cool. Where do I whack this option? server.xml? I know it must be a silly question to ask on Tomcat Dev list... :-) > ( Bojan - please review and let me know if it is not what you intended, > I'm not sure if the /dev/ransom needs to be closed/open all the time ) I don't think it needs to be opened/closed all the time. Honestly I can't say for sure. There must be some true Linux experts out there that can enlighten us on that one. My knowledge is limited to the manual page (man 4 random) where this file is explained as giving secure random numbers. If 'entropy pool' is empty, /dev/random will block until this pool is filled (ie. until there are events in the kernel that can fill the pool again). The pool gets filled by the 'noise' produced by drivers and other kernel sources. Whether opening and closing of the stream makes a difference, I really couldn't say, but it seem to me that it shouldn't (except for the fact that code execution itself might fill the pool). >From Tomcat's perspective it's really better to keep it open. It's going to run faster. I'm guessing all open streams get closed when Tomcat is shut down anyway, so that's fine. And thanks for acting so quickly on this! Bojan
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/session SessionIdGenerator.java
costin 01/04/09 23:58:23 Modified:src/share/org/apache/tomcat/modules/session SessionIdGenerator.java Log: Patch from Bojan Smojver <[EMAIL PROTECTED]>, slightly modified. The patch allows systems that have /dev/random to use it instead of the slower Random. Instead of checking for OS==linux ( as in submited patch ) we use an option of the module. The code if the option "useDevRandom" is not set is the same as before. If you set useDevRandom="true" then /dev/random will be used. ( Bojan - please review and let me know if it is not what you intended, I'm not sure if the /dev/ransom needs to be closed/open all the time ) Submitted by: Bojan Smojver <[EMAIL PROTECTED]> Revision ChangesPath 1.2 +37 -7 jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionIdGenerator.java Index: SessionIdGenerator.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionIdGenerator.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SessionIdGenerator.java 2001/03/21 06:54:01 1.1 +++ SessionIdGenerator.java 2001/04/10 06:58:22 1.2 @@ -95,6 +95,7 @@ String randomClassName=null; Random randomSource=null; +DataInputStream randomIS=null; static Jdk11Compat jdk11Compat=Jdk11Compat.getJdkCompat(); @@ -108,7 +109,21 @@ randomSource=createRandomClass( randomClassName ); } +/** Use /dev/random special device. 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; + } +} + // Tomcat request events public int sessionState( Request req, ServerSession sess, int state ) { @@ -126,7 +141,7 @@ /** Init session management stuff for this context. */ public void engineInit(ContextManager cm) throws TomcatException { - if( randomSource==null ) { + if( randomSource==null && randomIS==null ) { String randomClass=(String)cm.getProperty("randomClass" ); if( randomClass==null ) { randomClass="java.security.SecureRandom"; @@ -147,12 +162,12 @@ */ String newId; if( System.getSecurityManager() == null ) { - newId= SessionIdGenerator.getIdentifier(randomSource, jsIdent); + newId= SessionIdGenerator.getIdentifier(randomSource, randomIS, jsIdent); return newId; } // We're in a sandbox... PriviledgedIdGenerator di = new - PriviledgedIdGenerator(randomSource,jsIdent); + PriviledgedIdGenerator(randomSource,randomIS, jsIdent); try { newId= (String)jdk11Compat.doPrivileged(di); } catch( Exception ex ) { @@ -165,12 +180,15 @@ static class PriviledgedIdGenerator extends Action { private Random randomSource; private String jsIdent; - public PriviledgedIdGenerator(Random rs, String ident) { + DataInputStream randomIS; + public PriviledgedIdGenerator(Random rs, DataInputStream randomIS,String ident) { randomSource = rs; jsIdent = ident; + this.randomIS=randomIS; } public Object run() { return SessionIdGenerator.getIdentifier(randomSource, + randomIS, jsIdent); } } @@ -231,18 +249,30 @@ // ** NOTE that this must work together with get_jserv_session_balance() // ** in jserv_balance.c static synchronized public String getIdentifier (Random randomSource, + DataInputStream devRandomIS, String jsIdent) { StringBuffer sessionId = new StringBuffer(); - if( randomSource==null) + if( randomSource==null && devRandomIS==null) throw new RuntimeException( "No random source " ); // random value .. -long n = randomSource.nextLong(); +long n = 0; + if( devRandomIS!=null ) { + try { + n=devRandomIS.readLong(); + System.out.println("Getting /dev/random " + n ); + } catch( IOException ex ) { + ex.printStackTrace(); + } + } else { + n=randomSource.nextLong(); + } +