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