Author: markt Date: Sat Jan 30 19:46:02 2010 New Revision: 904859 URL: http://svn.apache.org/viewvc?rev=904859&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=48311 Only the APR lifecycle listener should try and initialise APR Patch also syncs all APR lifecycle listener changes from 6.0.x to 5.5.x
Modified: tomcat/tc5.5.x/trunk/STATUS.txt tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/connector/Connector.java tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/core/AprLifecycleListener.java tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml tomcat/tc5.5.x/trunk/container/webapps/docs/ssl-howto.xml Modified: tomcat/tc5.5.x/trunk/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/STATUS.txt?rev=904859&r1=904858&r2=904859&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/STATUS.txt (original) +++ tomcat/tc5.5.x/trunk/STATUS.txt Sat Jan 30 19:46:02 2010 @@ -102,16 +102,6 @@ +1: markt, rjung -1: -* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=48311 - Only the APR lifecycle listener should try and initialise APR - Patch also syncs all APR lifecycle listener changes from 6.0.x to 5.5.x - http://people.apache.org/~markt/patches/2009-11-27-bug48300-tc5.patch - +1: markt, rjung, kkolinko - -1: - kkolinko: 1. It introduces SSLEngine property in AprLifecycleListener, - it could be described in ssl-howto.html, see 6.0. 2. BZ 48613 is - an issue that existed before this patch, but it makes it noticeable. - * Address https://issues.apache.org/bugzilla/show_bug.cgi?id=45255 Prevent session fixation by changing session ID on authentication by default If you don't like the session ID changing by default, feel free to caveat your Modified: tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/connector/Connector.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/connector/Connector.java?rev=904859&r1=904858&r2=904859&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/connector/Connector.java (original) +++ tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/connector/Connector.java Sat Jan 30 19:46:02 2010 @@ -32,6 +32,7 @@ import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleListener; import org.apache.catalina.Service; +import org.apache.catalina.core.AprLifecycleListener; import org.apache.catalina.core.StandardEngine; import org.apache.catalina.util.LifecycleSupport; import org.apache.catalina.util.StringManager; @@ -607,23 +608,7 @@ */ public void setProtocol(String protocol) { - // Test APR support - boolean apr = false; - try { - String methodName = "initialize"; - Class paramTypes[] = new Class[1]; - paramTypes[0] = String.class; - Object paramValues[] = new Object[1]; - paramValues[0] = null; - Method method = Class.forName("org.apache.tomcat.jni.Library") - .getMethod(methodName, paramTypes); - method.invoke(null, paramValues); - apr = true; - } catch (Throwable t) { - // Ignore - } - - if (apr) { + if (AprLifecycleListener.isAprAvailable()) { if ("HTTP/1.1".equals(protocol)) { setProtocolHandlerClassName ("org.apache.coyote.http11.Http11AprProtocol"); Modified: tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/core/AprLifecycleListener.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/core/AprLifecycleListener.java?rev=904859&r1=904858&r2=904859&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/core/AprLifecycleListener.java (original) +++ tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/core/AprLifecycleListener.java Sat Jan 30 19:46:02 2010 @@ -5,9 +5,9 @@ * 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. @@ -18,20 +18,25 @@ package org.apache.catalina.core; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; + import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleListener; import org.apache.catalina.util.StringManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.tomcat.jni.Library; + /** * Implementation of <code>LifecycleListener</code> that will init and * and destroy APR. - * + * * @author Remy Maucherat + * @author Filip Hanik * @version $Revision$ $Date$ * @since 4.1 */ @@ -44,12 +49,11 @@ /** * The string manager for this package. */ - protected StringManager sm = + protected static StringManager sm = StringManager.getManager(Constants.Package); - protected static String SSLRandomSeed = "builtin"; - - // -------------------------------------------------------------- Constants + + // ---------------------------------------------- Constants protected static final int REQUIRED_MAJOR = 1; @@ -58,8 +62,20 @@ protected static final int RECOMMENDED_PV = 17; - // ---------------------------------------------- LifecycleListener Methods + // ---------------------------------------------- Properties + protected static String SSLEngine = "on"; //default on + protected static String SSLRandomSeed = "builtin"; + protected static boolean sslInitialized = false; + protected static boolean aprInitialized = false; + protected static boolean sslAvailable = false; + protected static boolean aprAvailable = false; + + public static boolean isAprAvailable() { + init(); + return aprAvailable; + } + // ---------------------------------------------- LifecycleListener Methods /** * Primary entry point for startup and shutdown events. @@ -69,65 +85,24 @@ public void lifecycleEvent(LifecycleEvent event) { if (Lifecycle.INIT_EVENT.equals(event.getType())) { - int major = 0; - int minor = 0; - int patch = 0; - try { - String methodName = "initialize"; - Class paramTypes[] = new Class[1]; - paramTypes[0] = String.class; - Object paramValues[] = new Object[1]; - paramValues[0] = null; - Class clazz = Class.forName("org.apache.tomcat.jni.Library"); - Method method = clazz.getMethod(methodName, paramTypes); - method.invoke(null, paramValues); - - major = clazz.getField("TCN_MAJOR_VERSION").getInt(null); - minor = clazz.getField("TCN_MINOR_VERSION").getInt(null); - patch = clazz.getField("TCN_PATCH_VERSION").getInt(null); - - methodName = "randSet"; - paramValues[0] = SSLRandomSeed; - clazz = Class.forName("org.apache.tomcat.jni.SSL"); - method = clazz.getMethod(methodName, paramTypes); - method.invoke(null, paramValues); - } catch (Throwable t) { - if (!log.isDebugEnabled()) { - log.info(sm.getString("aprListener.aprInit", - System.getProperty("java.library.path"))); - } else { - log.debug(sm.getString("aprListener.aprInit", - System.getProperty("java.library.path")), t); + init(); + if (aprAvailable) { + try { + initializeSSL(); + } catch (Throwable t) { + if (!log.isDebugEnabled()) { + log.info(sm.getString("aprListener.sslInit")); + } else { + log.debug(sm.getString("aprListener.sslInit"), t); + } } - return; - } - if ((major != REQUIRED_MAJOR) || (minor != REQUIRED_MINOR) - || (patch < REQUIRED_PATCH)) { - log.error(sm.getString("aprListener.tcnInvalid", major + "." - + minor + "." + patch, REQUIRED_MAJOR + "." - + REQUIRED_MINOR + "." + REQUIRED_PATCH)); - } - if (patch < RECOMMENDED_PV) { - /* The version is lower then recommended. - * Instruct the user to consider upgrading the native - * to the current stable version. - */ - if (!log.isDebugEnabled()) { - log.info(sm.getString("aprListener.tcnVersion", major + "." - + minor + "." + patch, REQUIRED_MAJOR + "." - + REQUIRED_MINOR + "." + RECOMMENDED_PV)); - } else { - log.debug(sm.getString("aprListener.tcnVersion", major + "." - + minor + "." + patch, REQUIRED_MAJOR + "." - + REQUIRED_MINOR + "." + RECOMMENDED_PV)); - } } } else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) { + if (!aprAvailable) { + return; + } try { - String methodName = "terminate"; - Method method = Class.forName("org.apache.tomcat.jni.Library") - .getMethod(methodName, (Class [])null); - method.invoke(null, (Object []) null); + terminateAPR(); } catch (Throwable t) { if (!log.isDebugEnabled()) { log.info(sm.getString("aprListener.aprDestroy")); @@ -139,11 +114,141 @@ } + private static synchronized void terminateAPR() + throws ClassNotFoundException, NoSuchMethodException, + IllegalAccessException, InvocationTargetException + { + String methodName = "terminate"; + Method method = Class.forName("org.apache.tomcat.jni.Library") + .getMethod(methodName, (Class [])null); + method.invoke(null, (Object []) null); + } + + private static void init() + { + int major = 0; + int minor = 0; + int patch = 0; + if (aprInitialized) { + return; + } + aprInitialized = true; + + try { + String methodName = "initialize"; + Class paramTypes[] = new Class[1]; + paramTypes[0] = String.class; + Object paramValues[] = new Object[1]; + paramValues[0] = null; + Class clazz = Class.forName("org.apache.tomcat.jni.Library"); + Method method = clazz.getMethod(methodName, paramTypes); + method.invoke(null, paramValues); + major = clazz.getField("TCN_MAJOR_VERSION").getInt(null); + minor = clazz.getField("TCN_MINOR_VERSION").getInt(null); + patch = clazz.getField("TCN_PATCH_VERSION").getInt(null); + } catch (Throwable t) { + if (!log.isDebugEnabled()) { + log.info(sm.getString("aprListener.aprInit", + System.getProperty("java.library.path"))); + } else { + log.debug(sm.getString("aprListener.aprInit", + System.getProperty("java.library.path")), t); + } + return; + } + if ((major != REQUIRED_MAJOR) || + (minor != REQUIRED_MINOR) || + (patch < REQUIRED_PATCH)) { + log.error(sm.getString("aprListener.tcnInvalid", major + "." + + minor + "." + patch, + REQUIRED_MAJOR + "." + + REQUIRED_MINOR + "." + + REQUIRED_PATCH)); + try { + // Terminate the APR in case the version + // is below required. + terminateAPR(); + } catch (Throwable t) { + // Ignore + } + return; + } + if (patch < RECOMMENDED_PV) { + if (!log.isDebugEnabled()) { + log.info(sm.getString("aprListener.tcnVersion", major + "." + + minor + "." + patch, + REQUIRED_MAJOR + "." + + REQUIRED_MINOR + "." + + RECOMMENDED_PV)); + } else { + log.debug(sm.getString("aprListener.tcnVersion", major + "." + + minor + "." + patch, + REQUIRED_MAJOR + "." + + REQUIRED_MINOR + "." + + RECOMMENDED_PV)); + } + } + if (!log.isDebugEnabled()) { + log.info(sm.getString("aprListener.tcnValid", major + "." + + minor + "." + patch)); + } + else { + log.debug(sm.getString("aprListener.tcnValid", major + "." + + minor + "." + patch)); + } + // Log APR flags + log.info(sm.getString("aprListener.flags", Library.APR_HAVE_IPV6, + Library.APR_HAS_SENDFILE, Library.APR_HAS_SO_ACCEPTFILTER, + Library.APR_HAS_RANDOM)); + aprAvailable = true; + } + + private static synchronized void initializeSSL() + throws ClassNotFoundException, NoSuchMethodException, + IllegalAccessException, InvocationTargetException + { + + if ("off".equalsIgnoreCase(SSLEngine)) { + return; + } + if (sslInitialized) { + //only once per VM + return; + } + sslInitialized = true; + + String methodName = "randSet"; + Class paramTypes[] = new Class[1]; + paramTypes[0] = String.class; + Object paramValues[] = new Object[1]; + paramValues[0] = SSLRandomSeed; + Class clazz = Class.forName("org.apache.tomcat.jni.SSL"); + Method method = clazz.getMethod(methodName, paramTypes); + method.invoke(null, paramValues); + + + methodName = "initialize"; + paramValues[0] = "on".equalsIgnoreCase(SSLEngine)?null:SSLEngine; + method = clazz.getMethod(methodName, paramTypes); + method.invoke(null, paramValues); + + sslAvailable = true; + } + + public String getSSLEngine() { + return SSLEngine; + } + + public void setSSLEngine(String SSLEngine) { + this.SSLEngine = SSLEngine; + } + public String getSSLRandomSeed() { return SSLRandomSeed; } public void setSSLRandomSeed(String SSLRandomSeed) { - AprLifecycleListener.SSLRandomSeed = SSLRandomSeed; + this.SSLRandomSeed = SSLRandomSeed; } + } Modified: tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml?rev=904859&r1=904858&r2=904859&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml (original) +++ tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml Sat Jan 30 19:46:02 2010 @@ -164,6 +164,10 @@ Greg Vanore. (markt) </fix> <fix> + <bug>48311</bug>: APR should not be initialised if the APR life-cycle + listener is not enabled. (markt) + </fix> + <fix> CVE-2009-3555. Provide option to disable legacy SSL renegotiation. (markt/costin) </fix> Modified: tomcat/tc5.5.x/trunk/container/webapps/docs/ssl-howto.xml URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/webapps/docs/ssl-howto.xml?rev=904859&r1=904858&r2=904859&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/container/webapps/docs/ssl-howto.xml (original) +++ tomcat/tc5.5.x/trunk/container/webapps/docs/ssl-howto.xml Sat Jan 30 19:46:02 2010 @@ -281,23 +281,97 @@ </subsection> <subsection name="Edit the Tomcat Configuration File"> +<p> +Tomcat can use two different implementations of SSL: +<ul> +<li>the JSSE implementation provided as part of the Java runtime (since 1.4)</li> +<li>the APR implementation, which uses the OpenSSL engine by default.</li> +</ul> +The exact configuration details depend on which implementation is being used. +The implementation used by Tomcat is chosen automatically unless it is overriden as described below. +If the installation uses <a href="apr.html">APR</a> +- i.e. you have installed the Tomcat native library - +then it will use the APR SSL implementation, otherwise it will use the Java JSSE implementation. +</p> + +<p> + To avoid auto configuration you can define which implementation to use by specifying a classname + in the <b>protocol</b> attribute of the Connector.<br/> + To define a Java (JSSE) connector, regardless of whether the APR library is loaded or not do: +<source> +<-- Define a blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 --> +<Connector protocol="org.apache.coyote.http11.Http11Protocol" + port="8443" .../> + +<-- Define a non-blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 --> +<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" + port="8443" .../> +</source> +Alternatively, to specify an APR connector (the APR library must be available) use: +<source> +<-- Define a APR SSL Coyote HTTP/1.1 Connector on port 8443 --> +<Connector protocol="org.apache.coyote.http11.Http11AprProtocol" + port="8443" .../> +</source> + +</p> + +<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" /> +</source> +The default value is +<source> +<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" /> +</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 +sources like "/dev/urandom" that will allow quicker starts of Tomcat. -<p>The final step is to configure your secure socket in the -<code>$CATALINA_HOME/conf/server.xml</code> file, where -<code>$CATALINA_HOME</code> represents the directory into which you -installed Tomcat 5. An example <code><Connector></code> element +</p> + +<p>The final step is to configure the Connector in the +<code>$CATALINA_BASE/conf/server.xml</code> file, where +<code>$CATALINA_BASE</code> represents the base directory for the +Tomcat 6 instance. An example <code><Connector></code> element for an SSL connector is included in the default <code>server.xml</code> -file installed with Tomcat. It will look something like this:</p> +file installed with Tomcat. For JSSE, it should look something like this:</p> <source> <-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --> <!-- <Connector - port="8443" minProcessors="5" maxProcessors="75" - enableLookups="true" disableUploadTimeout="true" - acceptCount="100" debug="0" scheme="https" secure="true"; + port="8443" maxThreads="200" + scheme="https" secure="true" SSLEnabled="true" + keystoreFile="${user.home}/.keystore" keystorePass="changeit" clientAuth="false" sslProtocol="TLS"/> --> </source> +<p> + The example above will throw an error if you have the APR and the Tomcat Native libraries in your path, + as Tomcat will try to use the APR connector. The APR connector uses different attributes for + SSL keys and certificates. An example of an APR configuration is: +<source> +<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --> +<!-- +<Connector + port="8443" maxThreads="200" + scheme="https" secure="true" SSLEnabled="true" + SSLCertificateFile="/usr/local/ssl/server.crt" + SSLCertificateKeyFile="/usr/local/ssl/server.pem" + clientAuth="optional" SSLProtocol="TLSv1"/> +--> +</source> +</p> <p>You will note that the Connector element itself is commented out by default, so you will need to remove the comment tags around it. Then, you can @@ -319,93 +393,17 @@ value specified for the <code>redirectPort</code> attribute on the non-SSL connector. This allows Tomcat to automatically redirect users who attempt to access a page with a security constraint specifying - that SSL is required, as required by the Servlet 2.4 Specification.</p> + that SSL is required, as required by the Servlet Specification.</p> </em></blockquote> -<p>There are additional option used to configure the SSL protocol. - You may need to add or change the following attribute -values, depending on how you configured your keystore earlier:</p> - -<table border="1"> - <tr> - <th>Attribute</th> - <th>Description</th> - </tr> - <tr> - <td><code>clientAuth</code></td> - <td>Set this value to <code>true</code> if you want Tomcat to require - all SSL clients to present a client Certificate in order to use - this socket. Set this value to <code>want</code> if you want Tomcat - to request a client Certificate, but not fail if one isn't presented. - For using clientAuth on a per-user or per-session basis, check out - the tips in - <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=34643"; title="Bugzilla 34643">Bugzilla 34643</a>. - </td> - </tr> - <tr> - <td><code>keystoreFile</code></td> - <td>Add this attribute if the keystore file you created is not in - the default place that Tomcat expects (a file named - <code>.keystore</code> in the user home directory under - which Tomcat is running). You can specify an absolute pathname, - or a relative pathname that is resolved against the - <code>$CATALINA_BASE</code> environment variable.</td> - </tr> - <tr> - <td><code>keystorePass</code></td> - <td>Add this element if you used a different keystore (and Certificate) - password than the one Tomcat expects (<code>changeit</code>).</td> - </tr> - <tr> - <td><code>keystoreType</code></td> - <td>Add this element if using a keystore type other than - <code>JKS</code>.</td> - </tr> - <tr> - <td><code>sslProtocol</code></td> - <td>The encryption/decryption protocol to be used on this socket. - It is not recommended to change this value if you are using Sun's - JVM. It is reported that IBM's 1.4.1 implementation - of the TLS protocol is not compatible with some popular browsers. - In this case, use the value <code>SSL</code>.</td> - </tr> - <tr> - <td><code>ciphers</code></td> - <td>The comma separated list of encryption ciphers that this socket is - allowed to use. By default, the default ciphers for the JVM will be - used. Note that this usually means that the weak export grade ciphers - will be included in the list of available ciphers. The ciphers are - specified using the JSSE cipher naming convention.</td> - </tr> - <tr> - <td><code>algorithm</code></td> - <td>The <code>X509</code> algorithm to use. This defaults to the Sun - implementation (<code>SunX509</code>). For IBM JVMs you should use - the value <code>IbmX509</code>. For other vendors, consult the JVM - documentation for the correct value. - </td> - </tr> - <tr> - <td><code>truststoreFile</code></td> - <td>The TrustStore file to use to validate client certificates.</td> - </tr> - <tr> - <td><code>truststorePass</code></td> - <td>The password to access the TrustStore. This defaults to the value - of <code>keystorePass</code>.</td> - </tr> - <tr> - <td><code>truststoreType</code></td> - <td>Add this element if your are using a different format for the - TrustStore then you are using for the KeyStore.</td> - </tr> - <tr> - <td><code>keyAlias</code></td> - <td>Add this element if your have more than one key in the KeyStore. - If the element is not present the first key read in the KeyStore - will be used.</td> - </tr> -</table> +<p>There are additional options used to configure the SSL protocol. You may +need to add or change some attributes, depending on how you configured your +keystore earlier. If you are using a Java JSSE based SSL connector then +configuration options are documented in the +<a href="config/http.html">Java HTTP connector</a> configuration +reference. If you are using the APR/native connector then refer to the +<a href="apr.html">APR connector</a> configuration guide for details of the +available configuration options.</p> <p>After completing these configuration changes, you must restart Tomcat as you normally do, and you should be in business. You should be able to access --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org