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>
-&lt;Listener className="org.apache.catalina.core.AprLifecycleListener" 
SSLEngine="someengine" SSLRandomSeed="somedevice" /&gt;
+&lt;Listener className="org.apache.catalina.core.AprLifecycleListener"
+          SSLEngine="someengine" SSLRandomSeed="somedevice" /&gt;
 </source>
 The default value is
 <source>
-&lt;Listener className="org.apache.catalina.core.AprLifecycleListener" 
SSLEngine="on" SSLRandomSeed="builtin" /&gt;
+&lt;Listener className="org.apache.catalina.core.AprLifecycleListener"
+          SSLEngine="on" SSLRandomSeed="builtin" /&gt;
 </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>
-&lt;Listener className="org.apache.catalina.core.AprLifecycleListener" 
SSLEngine="off" /&gt;
+&lt;Listener className="org.apache.catalina.core.AprLifecycleListener"
+          SSLEngine="off" /&gt;
 </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&lt;SessionTrackingMode&gt; 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

Reply via email to