* Set session cookie in request object. Fixes bug 547.

http://helma.org/bugs/show_bug.cgi?id=547
* Use java.security.SecureRandom for session id generation,
  with fallback to java.util.Random.
This commit is contained in:
hns 2007-09-25 11:01:30 +00:00
parent f7f2604969
commit fd598f23cf

View file

@ -24,6 +24,8 @@ import helma.framework.core.Application;
import helma.util.*;
import java.io.*;
import java.util.*;
import java.security.SecureRandom;
import java.security.NoSuchAlgorithmException;
import javax.servlet.*;
import javax.servlet.http.*;
@ -64,6 +66,11 @@ public abstract class AbstractServletClient extends HttpServlet {
// if fals, an error response is written to the client immediately without entering helma
boolean uploadSoftfail = false;
// Random number generator for session ids
Random random;
// whether the random number generator is secure
boolean secureRandom;
/**
* Init this servlet.
*
@ -113,6 +120,20 @@ public abstract class AbstractServletClient extends HttpServlet {
// generally disable response caching for clients?
caching = !("false".equalsIgnoreCase(init.getInitParameter("caching")));
// Get random number generator for session ids
try {
random = SecureRandom.getInstance("SHA1PRNG");
secureRandom = true;
} catch (NoSuchAlgorithmException nsa) {
random = new Random();
secureRandom = false;
}
random.setSeed(random.nextLong() ^ System.currentTimeMillis()
^ hashCode()
^ Runtime.getRuntime().freeMemory());
random.nextLong();
}
/**
@ -157,9 +178,8 @@ public abstract class AbstractServletClient extends HttpServlet {
if (sessionCookieName.equals(key)) {
reqtrans.setSession(reqCookies[i].getValue());
} else {
reqtrans.setCookie(key, reqCookies[i]);
}
reqtrans.setCookie(key, reqCookies[i]);
} catch (Exception badCookie) {
log("Error setting cookie", badCookie);
}
@ -254,7 +274,8 @@ public abstract class AbstractServletClient extends HttpServlet {
Cookie c = resCookies[i].getCookie("/", resCookieDomain);
response.addCookie(c);
} catch (Exception ignore) {
} catch (Exception x) {
getApplication().logEvent("Error adding cookie: " + x);
}
}
@ -351,7 +372,9 @@ public abstract class AbstractServletClient extends HttpServlet {
writer.write("Error in application ");
try {
writer.write(getApplication().getName());
} catch (Exception besafe) {}
} catch (Exception besafe) {
// ignore
}
writer.write("</h3>");
writer.write(message);
writer.write("</body></html>");
@ -508,40 +531,46 @@ public abstract class AbstractServletClient extends HttpServlet {
if (protectedSessionCookie) {
// If protected session cookies are enabled we also force a new session
// if the existing session id doesn't match the client's ip address
StringBuffer b = new StringBuffer();
addIPAddress(b, request.getRemoteAddr());
addIPAddress(b, request.getHeader("X-Forwarded-For"));
addIPAddress(b, request.getHeader("Client-ip"));
if (reqtrans.getSession() == null || !reqtrans.getSession().startsWith(b.toString())) {
response.addCookie(createSessionCookie(b, reqtrans, domain));
StringBuffer buffer = new StringBuffer();
addIPAddress(buffer, request.getRemoteAddr());
addIPAddress(buffer, request.getHeader("X-Forwarded-For"));
addIPAddress(buffer, request.getHeader("Client-ip"));
if (reqtrans.getSession() == null || !reqtrans.getSession().startsWith(buffer.toString())) {
response.addCookie(createSession(buffer.toString(), reqtrans, domain));
}
} else if (reqtrans.getSession() == null) {
response.addCookie(createSessionCookie(new StringBuffer(), reqtrans, domain));
response.addCookie(createSession("", reqtrans, domain));
}
}
/**
* Create a new session cookie.
*
* @param b
* @param reqtrans
* @param domain
* @param prefix the session id prefix
* @param reqtrans the request object
* @param domain the cookie domain
* @return the session cookie
*/
private Cookie createSessionCookie(StringBuffer b,
private Cookie createSession(String prefix,
RequestTrans reqtrans,
String domain) {
b.append (Long.toString(Math.round(Math.random() * Long.MAX_VALUE) -
System.currentTimeMillis(), 36));
reqtrans.setSession(b.toString());
Cookie cookie = new Cookie(sessionCookieName, reqtrans.getSession());
cookie.setPath("/");
if (domain != null) {
cookie.setDomain(domain);
Application app = getApplication();
String id = null;
while (id == null || app.getSession(id) != null) {
long l = secureRandom ?
random.nextLong() :
random.nextLong() + Runtime.getRuntime().freeMemory() ^ hashCode();
if (l < 0)
l = -l;
id = prefix + Long.toString(l, 36);
}
reqtrans.setSession(id);
Cookie cookie = new Cookie(sessionCookieName, id);
cookie.setPath("/");
if (domain != null)
cookie.setDomain(domain);
return cookie;
}