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: [email protected]
For additional commands, e-mail: [email protected]