Author: markt Date: Mon Jan 12 05:39:35 2009 New Revision: 733748 URL: http://svn.apache.org/viewvc?rev=733748&view=rev Log: Support for setting SessionTrackingMode Most of this commit is to support invalidating the SSL session by the session manager. I'm not sure yet that support for SSL session tracking is a good idea. There are quite a few limitations (see the ssl howto doc) and the changes to do it are fairly invasive. The option remains to remove this at a later date and not support SSL session tracking in Tomcat 7.
Added: tomcat/trunk/java/org/apache/tomcat/util/net/SSLSessionManager.java (with props) Modified: tomcat/trunk/java/org/apache/catalina/Globals.java tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java tomcat/trunk/java/org/apache/catalina/connector/Request.java tomcat/trunk/java/org/apache/catalina/connector/Response.java tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java tomcat/trunk/java/org/apache/catalina/core/ApplicationContextFacade.java tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/ha/session/JvmRouteBinderValve.java tomcat/trunk/java/org/apache/catalina/session/Constants.java tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java tomcat/trunk/java/org/apache/coyote/ActionCode.java tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/SSLSupport.java tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESupport.java tomcat/trunk/webapps/docs/ssl-howto.xml Modified: tomcat/trunk/java/org/apache/catalina/Globals.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Globals.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Globals.java (original) +++ tomcat/trunk/java/org/apache/catalina/Globals.java Mon Jan 12 05:39:35 2009 @@ -145,6 +145,14 @@ /** + * The request attribute key for the session manager. + * This one is a Tomcat extension to the Servlet spec. + */ + public static final String SSL_SESSION_MGR_ATTR = + "javax.servlet.request.ssl_session_mgr"; + + + /** * The servlet context attribute under which the managed bean Registry * will be stored for privileged contexts (if enabled). */ Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Mon Jan 12 05:39:35 2009 @@ -19,6 +19,9 @@ package org.apache.catalina.connector; import java.io.IOException; +import java.util.EnumSet; + +import javax.servlet.SessionTrackingMode; import org.apache.catalina.CometEvent; import org.apache.catalina.Context; @@ -36,6 +39,7 @@ import org.apache.tomcat.util.buf.MessageBytes; import org.apache.tomcat.util.http.Cookies; import org.apache.tomcat.util.http.ServerCookie; +import org.apache.tomcat.util.net.SSLSupport; import org.apache.tomcat.util.net.SocketStatus; @@ -55,6 +59,8 @@ // -------------------------------------------------------------- Constants + private static final EnumSet<SessionTrackingMode> SSL_ONLY = + EnumSet.of(SessionTrackingMode.SSL); public static final int ADAPTER_NOTES = 1; @@ -505,12 +511,32 @@ // Parse session Id parseSessionCookiesId(req, request); - + parseSessionSslId(request); return true; } /** + * Look for SSL sesison ID if required. Only look for SSL Session ID if it + * is the only tracking method enabled. + */ + protected void parseSessionSslId(Request request) { + if (request.getRequestedSessionId() == null && + SSL_ONLY.equals(request.getServletContext() + .getEffectiveSessionTrackingModes()) && + Boolean.TRUE.equals( + request.getConnector().getAttribute("SSLEnabled"))) { + // TODO Is there a better way to map SSL sessions to our sesison ID? + // TODO The request.getAttribute() will cause a number of other SSL + // attribute to be populated. Is this a performance concern? + request.setRequestedSessionId( + request.getAttribute(SSLSupport.SESSION_ID_KEY).toString()); + request.setRequestedSessionSSL(true); + } + } + + + /** * Parse session id in URL. */ protected void parseSessionId(org.apache.coyote.Request req, Request request) { @@ -518,7 +544,9 @@ ByteChunk uriBC = req.requestURI().getByteChunk(); int semicolon = uriBC.indexOf(match, 0, match.length(), 0); - if (semicolon > 0) { + if (semicolon > 0 && + request.getServletContext().getEffectiveSessionTrackingModes() + .contains(SessionTrackingMode.URL)) { // Parse session ID, and extract it from the decoded request URI int start = uriBC.getStart(); @@ -563,7 +591,9 @@ // from a parent context with a session ID may be present which would // overwrite the valid session ID encoded in the URL Context context = (Context) request.getMappingData().context; - if (context != null && !context.getCookies()) + if (context != null && !context.getServletContext() + .getEffectiveSessionTrackingModes().contains( + SessionTrackingMode.COOKIE)) return; // Parse session id from cookies Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Mon Jan 12 05:39:35 2009 @@ -46,6 +46,7 @@ import javax.servlet.ServletRequestAttributeListener; import javax.servlet.ServletResponse; import javax.servlet.SessionCookieConfig; +import javax.servlet.SessionTrackingMode; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @@ -333,6 +334,12 @@ /** + * Was the requested session ID obtained from the SSL session? + */ + protected boolean requestedSessionSSL = false; + + + /** * Parse locales. */ protected boolean localesParsed = false; @@ -1505,8 +1512,7 @@ } public ServletContext getServletContext() { - // TODO SERVLET3 - return null; + return context.getServletContext(); } public boolean isAsyncStarted() { @@ -1736,6 +1742,20 @@ /** + * Set a flag indicating whether or not the requested session ID for this + * request came in through SSL. This is normally called by the + * HTTP Connector, when it parses the request headers. + * + * @param flag The new flag + */ + public void setRequestedSessionSSL(boolean flag) { + + this.requestedSessionSSL = flag; + + } + + + /** * Set the unparsed request URI for this Request. This will normally be * called by the HTTP Connector, when it parses the request headers. * @@ -2321,6 +2341,15 @@ coyoteRequest.action(ActionCode.ACTION_COMET_SETTIMEOUT,new Long(timeout)); } + /** + * Not part of Servlet 3 spec but probably should be. + * @return + */ + public boolean isRequestedSessionIdFromSSL() { + return requestedSessionSSL; + } + + // ------------------------------------------------------ Protected Methods @@ -2360,7 +2389,8 @@ if (!create) return (null); if ((context != null) && (response != null) && - context.getCookies() && + context.getServletContext().getEffectiveSessionTrackingModes(). + contains(SessionTrackingMode.COOKIE) && response.getResponse().isCommitted()) { throw new IllegalStateException (sm.getString("coyoteRequest.sessionCreateCommitted")); @@ -2369,16 +2399,26 @@ // Attempt to reuse session id if one was submitted in a cookie // Do not reuse the session id if it is from a URL, to prevent possible // phishing attacks - if (connector.getEmptySessionPath() - && isRequestedSessionIdFromCookie()) { + // Use the SSL session ID if one is present. + if ((connector.getEmptySessionPath() + && isRequestedSessionIdFromCookie()) || requestedSessionSSL ) { session = manager.createSession(getRequestedSessionId()); + if (requestedSessionSSL) { + coyoteRequest.action(ActionCode.ACTION_REQ_SSL_SESSION_MGR, + null); + session.setNote( + org.apache.catalina.session.Constants.SESS_SSL_MGMT, + getAttribute(Globals.SSL_SESSION_MGR_ATTR)); + } } else { session = manager.createSession(null); } // Creating a new session cookie based on that session if ((session != null) && (getContext() != null) - && getContext().getCookies()) { + && getContext().getServletContext(). + getEffectiveSessionTrackingModes().contains( + SessionTrackingMode.COOKIE)) { Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME, session.getIdInternal()); configureSessionCookie(cookie); Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Response.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Response.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Response.java Mon Jan 12 05:39:35 2009 @@ -35,6 +35,7 @@ import java.util.Vector; import javax.servlet.ServletOutputStream; +import javax.servlet.SessionTrackingMode; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; @@ -1420,6 +1421,11 @@ if (hreq.isRequestedSessionIdFromCookie()) return (false); + // Is URL encoding permitted + if (!hreq.getServletContext().getEffectiveSessionTrackingModes(). + contains(SessionTrackingMode.URL)) + return false; + if (SecurityUtil.isPackageProtectionEnabled()) { return ( AccessController.doPrivileged(new PrivilegedAction<Boolean>() { Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java Mon Jan 12 05:39:35 2009 @@ -44,8 +44,10 @@ import javax.servlet.SessionTrackingMode; import org.apache.catalina.Context; +import org.apache.catalina.Engine; import org.apache.catalina.Host; import org.apache.catalina.Wrapper; +import org.apache.catalina.connector.Connector; import org.apache.catalina.deploy.ApplicationParameter; import org.apache.catalina.util.Enumerator; import org.apache.catalina.util.ResourceSet; @@ -85,6 +87,9 @@ super(); this.context = context; this.basePath = basePath; + + // Populate default session tracking modes + populateDefaultSessionTrackingModes(); } @@ -154,6 +159,12 @@ * Session Cookie config */ private SessionCookieConfig sessionCookieConfig; + + /** + * Session tracking modes + */ + private EnumSet<SessionTrackingMode> sessionTrackingModes = null; + private EnumSet<SessionTrackingMode> defaultSessionTrackingModes = null; // --------------------------------------------------------- Public Methods @@ -840,15 +851,50 @@ } + /** + * By default {...@link SessionTrackingMode#URL} is always supported, {...@link + * SessionTrackingMode#COOKIE} is supported unless the <code>cookies</code> + * attribute has been set to <code>false</code> for the context and {...@link + * SessionTrackingMode#SSL} is supported if at least one of the connectors + * used by this context has the attribute <code>SSLEnabled</code> set to + * <code>true</code>. + */ public EnumSet<SessionTrackingMode> getDefaultSessionTrackingModes() { - // TODO SERVLET3 - return null; + return defaultSessionTrackingModes; } + private void populateDefaultSessionTrackingModes() { + // URL re-writing is always enabled by default + defaultSessionTrackingModes = EnumSet.of(SessionTrackingMode.URL); + + if (context.getCookies()) { + defaultSessionTrackingModes.add(SessionTrackingMode.COOKIE); + } + + // Context > Host > Engine > Service + Connector[] connectors = ((Engine) context.getParent().getParent()) + .getService().findConnectors(); + // Need at least one SSL enabled connector to use the SSL session ID. + // has to be SSL enabled so we can close the SSL session. + // TODO extend this for SSL sessions managed by accelerators, web + // servers etc + for (Connector connector : connectors) { + if (Boolean.TRUE.equals(connector.getAttribute("SSLEnabled"))) { + defaultSessionTrackingModes.add(SessionTrackingMode.SSL); + break; + } + } + } + /** + * Return the supplied value if one was previously set, else return the + * defaults. + */ public EnumSet<SessionTrackingMode> getEffectiveSessionTrackingModes() { - // TODO SERVLET3 - return null; + if (sessionTrackingModes != null) { + return sessionTrackingModes; + } + return defaultSessionTrackingModes; } @@ -862,9 +908,33 @@ } + /** + * @throws IllegalStateException if the context has already been initialised + * @throws IllegalArgumentException TODO SERVLET3 Something to do with SSL + * but the spec language is not clear + * If an unsupported tracking mode is + * requested + */ public void setSessionTrackingModes( EnumSet<SessionTrackingMode> sessionTrackingModes) { - // TODO SERVLET3 + + if (context.getAvailable()) { + throw new IllegalStateException( + sm.getString("applicationContext.setSessionTracking.ise", + getContextPath())); + } + + // Check that only supported tracking modes have been requested + for (SessionTrackingMode sessionTrackingMode : sessionTrackingModes) { + if (!defaultSessionTrackingModes.contains(sessionTrackingMode)) { + throw new IllegalArgumentException(sm.getString( + "applicationContext.setSessionTracking.iae", + sessionTrackingMode.toString(), getContextPath())); + } + } + // TODO SERVLET3 - The SSL test + + this.sessionTrackingModes = sessionTrackingModes; } Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationContextFacade.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationContextFacade.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/ApplicationContextFacade.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/ApplicationContextFacade.java Mon Jan 12 05:39:35 2009 @@ -105,6 +105,9 @@ classCache.put("getRealPath", clazz); classCache.put("getAttribute", clazz); classCache.put("log", clazz); + classCache.put("getDefaultSessionTrackingModes", clazz); + classCache.put("getEffectiveSessionTrackingModes", clazz); + classCache.put("setSessionTrackingModes", clazz); } @@ -396,14 +399,22 @@ public EnumSet<SessionTrackingMode> getDefaultSessionTrackingModes() { - // TODO SERVLET3 - return null; + if (SecurityUtil.isPackageProtectionEnabled()) { + return (EnumSet<SessionTrackingMode>) + doPrivileged("getDefaultSessionTrackingModes", null); + } else { + return context.getDefaultSessionTrackingModes(); + } } public EnumSet<SessionTrackingMode> getEffectiveSessionTrackingModes() { - // TODO SERVLET3 - return null; + if (SecurityUtil.isPackageProtectionEnabled()) { + return (EnumSet<SessionTrackingMode>) + doPrivileged("getEffectiveSessionTrackingModes", null); + } else { + return context.getEffectiveSessionTrackingModes(); + } } @@ -420,7 +431,12 @@ public void setSessionTrackingModes( EnumSet<SessionTrackingMode> sessionTrackingModes) { - // TODO SERVLET3 + if (SecurityUtil.isPackageProtectionEnabled()) { + doPrivileged("setSessionTrackingModes", + new Object[]{sessionTrackingModes}); + } else { + context.setSessionTrackingModes(sessionTrackingModes); + } } Modified: tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties Mon Jan 12 05:39:35 2009 @@ -18,6 +18,8 @@ applicationContext.requestDispatcher.iae=Path {0} does not start with a "/" character applicationContext.resourcePaths.iae=Path {0} does not start with a "/" character applicationContext.setAttribute.namenull=Name cannot be null +applicationContext.setSessionTracking.ise=The session tracking modes for context {0} cannot be set whilst the context is running +applicationContext.setSessionTracking.iae=The session tracking mode {0} requested for context {1} is not supported by that context applicationDispatcher.allocateException=Allocate exception for servlet {0} applicationDispatcher.deallocateException=Deallocate exception for servlet {0} applicationDispatcher.forward.ise=Cannot forward after response has been committed Modified: tomcat/trunk/java/org/apache/catalina/ha/session/JvmRouteBinderValve.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/session/JvmRouteBinderValve.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/ha/session/JvmRouteBinderValve.java (original) +++ tomcat/trunk/java/org/apache/catalina/ha/session/JvmRouteBinderValve.java Mon Jan 12 05:39:35 2009 @@ -19,6 +19,7 @@ import java.io.IOException; import javax.servlet.ServletException; +import javax.servlet.SessionTrackingMode; import javax.servlet.http.Cookie; import org.apache.catalina.Container; @@ -431,7 +432,8 @@ Response response, String sessionId) { if (response != null) { Context context = request.getContext(); - if (context.getCookies()) { + if (context.getServletContext().getEffectiveSessionTrackingModes() + .contains(SessionTrackingMode.COOKIE)) { // set a new session cookie Cookie newCookie = new Cookie(Globals.SESSION_COOKIE_NAME, sessionId); Modified: tomcat/trunk/java/org/apache/catalina/session/Constants.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/Constants.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/session/Constants.java (original) +++ tomcat/trunk/java/org/apache/catalina/session/Constants.java Mon Jan 12 05:39:35 2009 @@ -29,4 +29,10 @@ public static final String Package = "org.apache.catalina.session"; + /** + * Name of note containing SSL session manager + */ + public static final String SESS_SSL_MGMT = + "org.apache.catalina.session.SSL_MGMT"; + } Modified: tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java Mon Jan 12 05:39:35 2009 @@ -53,6 +53,7 @@ import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.modeler.Registry; +import org.apache.tomcat.util.net.SSLSessionManager; /** @@ -907,6 +908,12 @@ public void remove(Session session) { sessions.remove(session.getIdInternal()); + // Close the underlying SSL session + SSLSessionManager mgr = + (SSLSessionManager) session.getNote(Constants.SESS_SSL_MGMT); + if (mgr != null) { + mgr.invalidateSession(); + } } Modified: tomcat/trunk/java/org/apache/coyote/ActionCode.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ActionCode.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ActionCode.java (original) +++ tomcat/trunk/java/org/apache/coyote/ActionCode.java Mon Jan 12 05:39:35 2009 @@ -17,6 +17,8 @@ package org.apache.coyote; +import org.apache.tomcat.util.net.SSLSessionManager; + /** * Enumerated class containing the adapter event codes. @@ -161,6 +163,12 @@ */ public static final ActionCode ACTION_COMET_SETTIMEOUT = new ActionCode(25); + /** + * Callback for lazy evaluation - obtain the SSL Session Manager + */ + public static final ActionCode ACTION_REQ_SSL_SESSION_MGR = + new ActionCode(26); + // ----------------------------------------------------------- Constructors int code; Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Mon Jan 12 05:39:35 2009 @@ -1198,6 +1198,9 @@ //no op } else if (actionCode == ActionCode.ACTION_COMET_SETTIMEOUT) { //no op + } else if (actionCode == ActionCode.ACTION_REQ_SSL_SESSION_MGR) { + //TODO SERVLET3 provide a hook to enable the SSL session to be + // invalidated } } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Mon Jan 12 05:39:35 2009 @@ -1236,8 +1236,11 @@ RequestInfo rp = request.getRequestProcessor(); if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE ) //async handling attach.setTimeout(timeout); + } else if (actionCode == ActionCode.ACTION_REQ_SSL_SESSION_MGR) { + if( sslSupport != null) { + request.setAttribute(SSLSupport.SESSION_MGR, sslSupport); + } } - } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Mon Jan 12 05:39:35 2009 @@ -1105,6 +1105,10 @@ InternalInputBuffer internalBuffer = (InternalInputBuffer) request.getInputBuffer(); internalBuffer.addActiveFilter(savedBody); + } else if (actionCode == ActionCode.ACTION_REQ_SSL_SESSION_MGR) { + if( sslSupport != null) { + request.setAttribute(SSLSupport.SESSION_MGR, sslSupport); + } } } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Mon Jan 12 05:39:35 2009 @@ -87,6 +87,13 @@ */ public static final String SESSION_ID_KEY = "javax.servlet.request.ssl_session"; + /** + * The request attribute key for the session manager. + * This one is a Tomcat extension to the Servlet spec. + */ + public static final String SESSION_MGR = + "javax.servlet.request.ssl_session_mgr"; + // ----------------------------------------------------------------- Fields Added: tomcat/trunk/java/org/apache/tomcat/util/net/SSLSessionManager.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLSessionManager.java?rev=733748&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/SSLSessionManager.java (added) +++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLSessionManager.java Mon Jan 12 05:39:35 2009 @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tomcat.util.net; + +/** + * Defines an interface used to manage SSL sessions. The manager operates on a + * single session. + * + * $Id$ + */ +public interface SSLSessionManager { + /** + * Invalidate the specified SSL session + * @param sessionId The ID of the session to invalidate. + */ + public void invalidateSession(); +} Propchange: tomcat/trunk/java/org/apache/tomcat/util/net/SSLSessionManager.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: tomcat/trunk/java/org/apache/tomcat/util/net/SSLSessionManager.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SSLSupport.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLSupport.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/SSLSupport.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLSupport.java Mon Jan 12 05:39:35 2009 @@ -49,6 +49,14 @@ public static final String SESSION_ID_KEY = "javax.servlet.request.ssl_session"; /** + * The request attribute key for the session manager. + * This one is a Tomcat extension to the Servlet spec. + */ + public static final String SESSION_MGR = + "javax.servlet.request.ssl_session_mgr"; + + + /** * A mapping table to determine the number of effective bits in the key * when using a cipher suite containing the specified cipher name. The * underlying data came from the TLS Specification (RFC 2246), Appendix C. Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESupport.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESupport.java?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESupport.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESupport.java Mon Jan 12 05:39:35 2009 @@ -31,6 +31,7 @@ import javax.net.ssl.SSLSocket; import javax.security.cert.X509Certificate; +import org.apache.tomcat.util.net.SSLSessionManager; import org.apache.tomcat.util.net.SSLSupport; /** JSSESupport @@ -48,7 +49,7 @@ Parts cribbed from CertificatesValve */ -class JSSESupport implements SSLSupport { +class JSSESupport implements SSLSupport, SSLSessionManager { private static org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory.getLog(JSSESupport.class); @@ -232,5 +233,11 @@ } } + /** + * Invalidate the session this support object is associated with. + */ + public void invalidateSession() { + session.invalidate(); + } } Modified: tomcat/trunk/webapps/docs/ssl-howto.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/ssl-howto.xml?rev=733748&r1=733747&r2=733748&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/ssl-howto.xml (original) +++ tomcat/trunk/webapps/docs/ssl-howto.xml Mon Jan 12 05:39:35 2009 @@ -284,18 +284,21 @@ <subsection name="Edit the Tomcat Configuration File"> <p>If you are using APR, you have the option of configuring an alternative engine to OpenSSL. <source> -<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="someengine" SSLRandomSeed="somedevice" /> +<Listener className="org.apache.catalina.core.AprLifecycleListener" + SSLEngine="someengine" SSLRandomSeed="somedevice" /> </source> The default value is <source> -<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" SSLRandomSeed="builtin" /> +<Listener className="org.apache.catalina.core.AprLifecycleListener" + SSLEngine="on" SSLRandomSeed="builtin" /> </source> So to use SSL under APR, make sure the SSLEngine attribute is set to something other than <code>off</code>. The default value is <code>on</code> and if you specify another value, it has to be a valid engine name. <br/> If you haven't compiled in SSL support into your Tomcat Native library, then you can turn this initialization off <source> -<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" /> +<Listener className="org.apache.catalina.core.AprLifecycleListener" + SSLEngine="off" /> </source> SSLRandomSeed allows to specify a source of entropy. Productive system needs a reliable source of entropy but entropy may need a lot of time to be collected therefore test systems could use no blocking entropy @@ -634,6 +637,67 @@ </section> +<section name="Using the SSL for session tracking in your application"> + <p>This is a new feature in the Servlet 3.0 specification. Because is uses the + SSL session ID associated with the physical client server connection there + are a number of limitations. They are: + <ul> + <li>The SSL connection must be managed by Tomcat, i.e. Tomcat must have a + connector with the attribute <strong>SSLEnabled</strong> set to + <code>true</code>. This is to enable Tomcat to invalidate the SSL + session if the HTTP session is invalidated. If SSL conections are + managed by a proxy or a hardware accelerator this is not possibe.</li> + <li>It cannot be used in conjunction with session replication as the SSL + session IDs will be different on each node.</li> + <li>When <code>session.invalidate()</code> is called within the application + <code>response.setHeader("Connection", "close")</code> must also be + called as invalidating the session does not affect any current + connections.</li> + <li>HTTP session timeouts, keep-alive timeouts and SSL session timeouts + should be consistent. Note that the default JSSE SSL session timeout + (24 hours) is significantly longer than the default Tomcat HTTP Sesson + timeout (30 minutes).</li> + </ul> + </p> + + <p> + To enable SSL session tracking you need to use a context listener to set the + tracking mode for the context to be just SSL (if any other tracking mode is + enabled, it will be used in preference). It might look something like: + <source> +package org.apache.tomcat.example; + +import java.util.EnumSet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.SessionTrackingMode; + +public class SessionTrackingModeListener implements ServletContextListener { + + @Override + public void contextDestroyed(ServletContextEvent event) { + // Do nothing + } + + @Override + public void contextInitialized(ServletContextEvent event) { + ServletContext context = event.getServletContext(); + EnumSet<SessionTrackingMode> modes = + EnumSet.of(SessionTrackingMode.SSL); + + context.setSessionTrackingModes(modes); + } + +} + </source> + </p> + <p>Note: SSL session tracking is implemented for the BIO and NIO connetcors. + It is not yet implemented for the APR connector.</p> + +</section> + <section name="Miscellaneous Tips and Bits"> <p>To access the SSL session ID from the request, use:<br /> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org