You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by jo...@locus.apache.org on 2000/05/23 02:43:49 UTC
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util SessionIdGenerator.java
jon 00/05/22 17:43:48
Modified: src/share/org/apache/tomcat/util SessionIdGenerator.java
Log:
use the JServ session generation code....
Revision Changes Path
1.2 +88 -33 jakarta-tomcat/src/share/org/apache/tomcat/util/SessionIdGenerator.java
Index: SessionIdGenerator.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/SessionIdGenerator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SessionIdGenerator.java 1999/10/09 00:20:56 1.1
+++ SessionIdGenerator.java 2000/05/23 00:43:47 1.2
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/SessionIdGenerator.java,v 1.1 1999/10/09 00:20:56 duncan Exp $
- * $Revision: 1.1 $
- * $Date: 1999/10/09 00:20:56 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/SessionIdGenerator.java,v 1.2 2000/05/23 00:43:47 jon Exp $
+ * $Revision: 1.2 $
+ * $Date: 2000/05/23 00:43:47 $
*
* ====================================================================
*
@@ -65,44 +65,99 @@
package org.apache.tomcat.util;
/**
- * Generates sesssion ids for the system. The ids produced by this
- * class aren't very sophisticated being just a random number followed
- * by a synchronized counter.
+ * This class generates a unique 10+ character id. This is good
+ * for authenticating users or tracking users around.
+ * <p>
+ * This code was borrowed from Apache JServ.JServServletManager.java.
+ * It is what Apache JServ uses to generate session ids for users.
+ * Unfortunately, it was not included in Apache JServ as a class
+ * so I had to create one here in order to use it.
*
* @author James Duncan Davidson [duncan@eng.sun.com]
* @author Jason Hunter [jhunter@acm.org]
+ * @author Jon S. Stevens <a href="mailto:jon@latchkey.com">jon@latchkey.com</a>
*/
-
public class SessionIdGenerator {
- private static int counter = 1010;
+ /*
+ * Create a suitable string for session identification
+ * Use synchronized count and time to ensure uniqueness.
+ * Use random string to ensure timestamp cannot be guessed
+ * by programmed attack.
+ *
+ * format of id is <6 chars random><3 chars time><1+ char count>
+ */
+ static private int session_count = 0;
+ static private long lastTimeVal = 0;
+ static private java.util.Random randomSource = new java.util.Random();
+
+ // MAX_RADIX is 36
+ /*
+ * we want to have a random string with a length of
+ * 6 characters. Since we encode it BASE 36, we've to
+ * modulo it with the following value:
+ */
+ public final static long maxRandomLen = 2176782336L; // 36 ** 6
+
+ /*
+ * The session identifier must be unique within the typical lifespan
+ * of a Session, the value can roll over after that. 3 characters:
+ * (this means a roll over after over an day which is much larger
+ * than a typical lifespan)
+ */
+ public final static long maxSessionLifespanTics = 46656; // 36 ** 3
+
+ /*
+ * millisecons between different tics. So this means that the
+ * 3-character time string has a new value every 2 seconds:
+ */
+ public final static long ticDifference = 2000;
+
+ // ** NOTE that this must work together with get_jserv_session_balance()
+ // ** in jserv_balance.c
+ static synchronized public String getIdentifier (String jsIdent)
+ {
+ StringBuffer sessionId = new StringBuffer();
- public static synchronized String generateId() {
+ // random value ..
+ long n = randomSource.nextLong();
+ if (n < 0) n = -n;
+ n %= maxRandomLen;
+ // add maxLen to pad the leading characters with '0'; remove
+ // first digit with substring.
+ n += maxRandomLen;
+ sessionId.append (Long.toString(n, Character.MAX_RADIX)
+ .substring(1));
+
+ long timeVal = (System.currentTimeMillis() / ticDifference);
+ // cut..
+ timeVal %= maxSessionLifespanTics;
+ // padding, see above
+ timeVal += maxSessionLifespanTics;
+
+ sessionId.append (Long.toString (timeVal, Character.MAX_RADIX)
+ .substring(1));
- // XXX
- // This code is not very secure at all. It's good enough
- // for a reference implementation where you want to make
- // sure to not repeat under most circumstances -- but its
- // not anything that could be considered to be safe for
- // military or banking use.
-
- // maybe.....
- // replace with some sort of MD5 hash so that it is impossible
- // to figure out which is the counter and which is the random
-
- Integer i = new Integer(counter++);
- StringBuffer buf = new StringBuffer();
- String dString = Double.toString(Math.abs(Math.random()));
-
- // we do the substring to get rid of the initial '0.'
- // characters.
-
- buf.append("To");
- buf.append(i);
- buf.append("mC");
- buf.append(dString.substring(2, dString.length()));
- buf.append("At");
+ /*
+ * make the string unique: append the session count since last
+ * time flip.
+ */
+ // count sessions only within tics. So the 'real' session count
+ // isn't exposed to the public ..
+ if (lastTimeVal != timeVal) {
+ lastTimeVal = timeVal;
+ session_count = 0;
+ }
+ sessionId.append (Long.toString (++session_count,
+ Character.MAX_RADIX));
+
+ if (jsIdent != null && jsIdent.length() > 0) {
+ return sessionId.toString()+"."+jsIdent;
+ }
+ return sessionId.toString();
+ }
- return buf.toString();
+ public static synchronized String generateId() {
+ return getIdentifier(null);
}
}
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util SessionIdGenerator.java
Posted by Tomas Rokicki <ro...@instantis.com>.
Finally, even if we do go with the patch you outlined, which doesn't
really fix anything, the code you copied has an obvious bug:
+ long n = randomSource.nextLong();
+ if (n < 0) n = -n;
+ n %= maxRandomLen;
The problem here is that if randomSource.nextLong returns
0x8000 0000 0000 0000, which it will with exceedingly low
probability, then the if (n < 0) n = -n will have no effect
due to two's complement arithmetic, and n will be negative,
even after the modulus, and various other bad things will
occur.
I don't know where the if (n < 0) n = -n idiom comes from
but I'm so sick of seeing such an obvious bug in all the
books and all the code. Better is just
long n = randomSource.nextLong() ;
n = n & 0x7fff ffff ffff ffff ; // remove the spaces
n %= maxRandomLen ;
or even
long n = randomSource.nextLong() ;
n %= maxRandomLen ;
if (n < 0) n = -n ;
I mean, of all the combinations of these statements that
can perform this function, people seem to always hit on
the one that fails (although admittedly with low probability).
-tom
-----Original Message-----
From: jon@locus.apache.org [mailto:jon@locus.apache.org]
Sent: Monday, May 22, 2000 5:44 PM
To: jakarta-tomcat-cvs@apache.org
Subject: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util
SessionIdGenerator.java
jon 00/05/22 17:43:48
Modified: src/share/org/apache/tomcat/util SessionIdGenerator.java
Log:
use the JServ session generation code....
Revision Changes Path
1.2 +88 -33
jakarta-tomcat/src/share/org/apache/tomcat/util/SessionIdGenerator.java
Index: SessionIdGenerator.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/SessionIdGenerator
.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SessionIdGenerator.java 1999/10/09 00:20:56 1.1
+++ SessionIdGenerator.java 2000/05/23 00:43:47 1.2
@@ -1,7 +1,7 @@
/*
- * $Header:
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/SessionIdGenerator
.java,v 1.1 1999/10/09 00:20:56 duncan Exp $
- * $Revision: 1.1 $
- * $Date: 1999/10/09 00:20:56 $
+ * $Header:
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/SessionIdGenerator
.java,v 1.2 2000/05/23 00:43:47 jon Exp $
+ * $Revision: 1.2 $
+ * $Date: 2000/05/23 00:43:47 $
*
* ====================================================================
*
@@ -65,44 +65,99 @@
package org.apache.tomcat.util;
/**
- * Generates sesssion ids for the system. The ids produced by this
- * class aren't very sophisticated being just a random number followed
- * by a synchronized counter.
+ * This class generates a unique 10+ character id. This is good
+ * for authenticating users or tracking users around.
+ * <p>
+ * This code was borrowed from Apache JServ.JServServletManager.java.
+ * It is what Apache JServ uses to generate session ids for users.
+ * Unfortunately, it was not included in Apache JServ as a class
+ * so I had to create one here in order to use it.
*
* @author James Duncan Davidson [duncan@eng.sun.com]
* @author Jason Hunter [jhunter@acm.org]
+ * @author Jon S. Stevens <a
href="mailto:jon@latchkey.com">jon@latchkey.com</a>
*/
-
public class SessionIdGenerator {
- private static int counter = 1010;
+ /*
+ * Create a suitable string for session identification
+ * Use synchronized count and time to ensure uniqueness.
+ * Use random string to ensure timestamp cannot be guessed
+ * by programmed attack.
+ *
+ * format of id is <6 chars random><3 chars time><1+ char count>
+ */
+ static private int session_count = 0;
+ static private long lastTimeVal = 0;
+ static private java.util.Random randomSource = new
java.util.Random();
+
+ // MAX_RADIX is 36
+ /*
+ * we want to have a random string with a length of
+ * 6 characters. Since we encode it BASE 36, we've to
+ * modulo it with the following value:
+ */
+ public final static long maxRandomLen = 2176782336L; // 36 ** 6
+
+ /*
+ * The session identifier must be unique within the typical lifespan
+ * of a Session, the value can roll over after that. 3 characters:
+ * (this means a roll over after over an day which is much larger
+ * than a typical lifespan)
+ */
+ public final static long maxSessionLifespanTics = 46656; // 36 ** 3
+
+ /*
+ * millisecons between different tics. So this means that the
+ * 3-character time string has a new value every 2 seconds:
+ */
+ public final static long ticDifference = 2000;
+
+ // ** NOTE that this must work together with
get_jserv_session_balance()
+ // ** in jserv_balance.c
+ static synchronized public String getIdentifier (String jsIdent)
+ {
+ StringBuffer sessionId = new StringBuffer();
- public static synchronized String generateId() {
+ // random value ..
+ long n = randomSource.nextLong();
+ if (n < 0) n = -n;
+ n %= maxRandomLen;
+ // add maxLen to pad the leading characters with '0'; remove
+ // first digit with substring.
+ n += maxRandomLen;
+ sessionId.append (Long.toString(n, Character.MAX_RADIX)
+ .substring(1));
+
+ long timeVal = (System.currentTimeMillis() / ticDifference);
+ // cut..
+ timeVal %= maxSessionLifespanTics;
+ // padding, see above
+ timeVal += maxSessionLifespanTics;
+
+ sessionId.append (Long.toString (timeVal, Character.MAX_RADIX)
+ .substring(1));
- // XXX
- // This code is not very secure at all. It's good enough
- // for a reference implementation where you want to make
- // sure to not repeat under most circumstances -- but its
- // not anything that could be considered to be safe for
- // military or banking use.
-
- // maybe.....
- // replace with some sort of MD5 hash so that it is impossible
- // to figure out which is the counter and which is the random
-
- Integer i = new Integer(counter++);
- StringBuffer buf = new StringBuffer();
- String dString = Double.toString(Math.abs(Math.random()));
-
- // we do the substring to get rid of the initial '0.'
- // characters.
-
- buf.append("To");
- buf.append(i);
- buf.append("mC");
- buf.append(dString.substring(2, dString.length()));
- buf.append("At");
+ /*
+ * make the string unique: append the session count since last
+ * time flip.
+ */
+ // count sessions only within tics. So the 'real' session count
+ // isn't exposed to the public ..
+ if (lastTimeVal != timeVal) {
+ lastTimeVal = timeVal;
+ session_count = 0;
+ }
+ sessionId.append (Long.toString (++session_count,
+ Character.MAX_RADIX));
+
+ if (jsIdent != null && jsIdent.length() > 0) {
+ return sessionId.toString()+"."+jsIdent;
+ }
+ return sessionId.toString();
+ }
- return buf.toString();
+ public static synchronized String generateId() {
+ return getIdentifier(null);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org