From 0cad225c48cdf5d29520c65a0e23e044e60d7c6d Mon Sep 17 00:00:00 2001
From: fhanik
Date: Thu, 19 Oct 2006 16:45:45 +0000
Subject: [PATCH] SSLEngine is an attribute of the APR lifecycle listener to
initialize the native SSL layer once per VM. All HTTP connectors share an
attribute called SSLEnabled with true/false values to turn on SSL at the
socket level. The scheme and secure attributes simply override the
request.getScheme and request.isSecure values.
git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@465675 13f79535-47bb-0310-9956-ffa450edef68
---
conf/server.xml | 2 +-
.../apache/catalina/core/AprLifecycleListener.java | 31 +++++++-
.../apache/catalina/core/LocalStrings.properties | 1 +
.../apache/coyote/http11/Http11AprProcessor.java | 2 +-
.../apache/coyote/http11/Http11AprProtocol.java | 4 +-
.../apache/coyote/http11/Http11NioProcessor.java | 2 +-
.../apache/coyote/http11/Http11NioProtocol.java | 4 +-
java/org/apache/coyote/http11/Http11Protocol.java | 8 +-
java/org/apache/tomcat/util/net/AprEndpoint.java | 16 ++--
java/org/apache/tomcat/util/net/NioEndpoint.java | 8 +-
webapps/docs/apr.xml | 22 +++++-
webapps/docs/changelog.xml | 5 +-
webapps/docs/config/http.xml | 8 +-
webapps/docs/ssl-howto.xml | 88 ++++++++++++++++++++--
14 files changed, 161 insertions(+), 40 deletions(-)
diff --git a/conf/server.xml b/conf/server.xml
index 72640ddd3..7b3c5ae69 100644
--- a/conf/server.xml
+++ b/conf/server.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/java/org/apache/catalina/core/AprLifecycleListener.java b/java/org/apache/catalina/core/AprLifecycleListener.java
index 42920916b..fd3cfd273 100644
--- a/java/org/apache/catalina/core/AprLifecycleListener.java
+++ b/java/org/apache/catalina/core/AprLifecycleListener.java
@@ -24,6 +24,8 @@ import org.apache.catalina.LifecycleListener;
import org.apache.catalina.util.StringManager;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
+import java.lang.reflect.InvocationTargetException;
+
/**
@@ -56,9 +58,12 @@ public class AprLifecycleListener
protected static final int RECOMMENDED_PV = 6;
+ // ---------------------------------------------- Properties
+ protected static String SSLEngine = "on"; //default on
+ protected static boolean sslInitialized = false;
+
// ---------------------------------------------- LifecycleListener Methods
-
/**
* Primary entry point for startup and shutdown events.
*
@@ -83,6 +88,7 @@ public class AprLifecycleListener
minor = clazz.getField("TCN_MINOR_VERSION").getInt(null);
patch = clazz.getField("TCN_PATCH_VERSION").getInt(null);
} catch (Throwable t) {
+ t.printStackTrace();
if (!log.isDebugEnabled()) {
log.info(sm.getString("aprListener.aprInit",
System.getProperty("java.library.path")));
@@ -109,6 +115,11 @@ public class AprLifecycleListener
+ REQUIRED_MINOR + "." + RECOMMENDED_PV));
}
}
+ try {
+ initializeSSL();
+ }catch ( Throwable t ) {
+ log.error(sm.getString("aprListener.sslInit",t.getMessage()),t);
+ }
} else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) {
try {
String methodName = "terminate";
@@ -125,6 +136,24 @@ public class AprLifecycleListener
}
}
+
+ public static synchronized void initializeSSL()
+ throws ClassNotFoundException,NoSuchMethodException,
+ IllegalAccessException,InvocationTargetException{
+
+ if ("off".equalsIgnoreCase(SSLEngine) ) return;
+ if ( sslInitialized ) return; //only once per VM
+ String methodName = "initialize";
+ Class paramTypes[] = new Class[1];
+ paramTypes[0] = String.class;
+ Object paramValues[] = new Object[1];
+ paramValues[0] = "on".equalsIgnoreCase(SSLEngine)?null:SSLEngine;
+ Class clazz = Class.forName("org.apache.tomcat.jni.SSL");
+ Method method = clazz.getMethod(methodName, paramTypes);
+ method.invoke(null, paramValues);
+ sslInitialized = true;
+
+ }
}
diff --git a/java/org/apache/catalina/core/LocalStrings.properties b/java/org/apache/catalina/core/LocalStrings.properties
index d57878e6d..4c81b9dc6 100644
--- a/java/org/apache/catalina/core/LocalStrings.properties
+++ b/java/org/apache/catalina/core/LocalStrings.properties
@@ -18,6 +18,7 @@ aprListener.aprInit=The Apache Tomcat Native library which allows optimal perfor
aprListener.tcnInvalid=An incompatible version {0} of the Apache Tomcat Native library is installed, while Tomcat requires version {1}
aprListener.tcnVersion=An older version {0} of the Apache Tomcat Native library is installed, while Tomcat recommends version greater then {1}
aprListener.aprDestroy=Failed shutdown of Apache Portable Runtime
+aprListener.sslInit=Unable to initialize the SSLEngine, failed with message: {0}
containerBase.addDefaultMapper=Exception configuring default mapper of class {0}
containerBase.alreadyStarted=Container {0} has already been started
containerBase.notConfigured=No basic Valve has been configured
diff --git a/java/org/apache/coyote/http11/Http11AprProcessor.java b/java/org/apache/coyote/http11/Http11AprProcessor.java
index 21e96df6d..3469bb3d2 100644
--- a/java/org/apache/coyote/http11/Http11AprProcessor.java
+++ b/java/org/apache/coyote/http11/Http11AprProcessor.java
@@ -102,7 +102,7 @@ public class Http11AprProcessor implements ActionHook {
response.setOutputBuffer(outputBuffer);
request.setResponse(response);
- ssl = !"off".equalsIgnoreCase(endpoint.getSSLEngine());
+ ssl = endpoint.isSSLEnabled();
initializeFilters();
diff --git a/java/org/apache/coyote/http11/Http11AprProtocol.java b/java/org/apache/coyote/http11/Http11AprProtocol.java
index 359672ef4..1975807c2 100644
--- a/java/org/apache/coyote/http11/Http11AprProtocol.java
+++ b/java/org/apache/coyote/http11/Http11AprProtocol.java
@@ -509,8 +509,8 @@ public class Http11AprProtocol implements ProtocolHandler, MBeanRegistration
/**
* SSL engine.
*/
- public String getSSLEngine() { return ep.getSSLEngine(); }
- public void setSSLEngine(String SSLEngine) { ep.setSSLEngine(SSLEngine); }
+ public boolean isSSLEnabled() { return ep.isSSLEnabled(); }
+ public void setSSLEnabled(boolean SSLEnabled) { ep.setSSLEnabled(SSLEnabled); }
/**
diff --git a/java/org/apache/coyote/http11/Http11NioProcessor.java b/java/org/apache/coyote/http11/Http11NioProcessor.java
index d781149c1..e87f5f46c 100644
--- a/java/org/apache/coyote/http11/Http11NioProcessor.java
+++ b/java/org/apache/coyote/http11/Http11NioProcessor.java
@@ -103,7 +103,7 @@ public class Http11NioProcessor implements ActionHook {
response.setOutputBuffer(outputBuffer);
request.setResponse(response);
- ssl = "on".equalsIgnoreCase(endpoint.getSSLEngine());
+ ssl = endpoint.isSSLEnabled();
initializeFilters();
diff --git a/java/org/apache/coyote/http11/Http11NioProtocol.java b/java/org/apache/coyote/http11/Http11NioProtocol.java
index a8ff9e3c7..0804a6863 100644
--- a/java/org/apache/coyote/http11/Http11NioProtocol.java
+++ b/java/org/apache/coyote/http11/Http11NioProtocol.java
@@ -537,8 +537,8 @@ public class Http11NioProtocol implements ProtocolHandler, MBeanRegistration
public String getCiphers() { return ep.getCiphers();}
public void setCiphers(String s) { ep.setCiphers(s);}
- public String getSSLEngine() { return ep.getSSLEngine(); }
- public void setSSLEngine(String SSLEngine) { ep.setSSLEngine(SSLEngine); }
+ public boolean getSSLEnabled() { return ep.isSSLEnabled(); }
+ public void setSSLEnabled(boolean SSLEnabled) { ep.setSSLEnabled(SSLEnabled); }
diff --git a/java/org/apache/coyote/http11/Http11Protocol.java b/java/org/apache/coyote/http11/Http11Protocol.java
index 5e83b83f2..7cebed472 100644
--- a/java/org/apache/coyote/http11/Http11Protocol.java
+++ b/java/org/apache/coyote/http11/Http11Protocol.java
@@ -146,7 +146,7 @@ public class Http11Protocol
// Verify the validity of the configured socket factory
try {
- if ("on".equalsIgnoreCase(getSSLEngine())) {
+ if (isSSLEnabled()) {
sslImplementation =
SSLImplementation.getInstance(sslImplementationName);
socketFactory = sslImplementation.getServerSocketFactory();
@@ -252,9 +252,9 @@ public class Http11Protocol
public boolean getSecure() { return secure; }
public void setSecure(boolean b) { secure = b; }
- protected String SSLEngine = "off";
- public String getSSLEngine() { return SSLEngine;}
- public void setSSLEngine(String SSLEngine) {this.SSLEngine = SSLEngine;}
+ protected boolean SSLEnabled = false;
+ public boolean isSSLEnabled() { return SSLEnabled;}
+ public void setSSLEnabled(boolean SSLEnabled) {this.SSLEnabled = SSLEnabled;}
/**
* Name of the socket factory.
diff --git a/java/org/apache/tomcat/util/net/AprEndpoint.java b/java/org/apache/tomcat/util/net/AprEndpoint.java
index bda77e543..f898b9245 100644
--- a/java/org/apache/tomcat/util/net/AprEndpoint.java
+++ b/java/org/apache/tomcat/util/net/AprEndpoint.java
@@ -379,9 +379,9 @@ public class AprEndpoint {
/**
* SSL engine.
*/
- protected String SSLEngine = "off";
- public String getSSLEngine() { return SSLEngine; }
- public void setSSLEngine(String SSLEngine) { this.SSLEngine = SSLEngine; }
+ protected boolean SSLEnabled = false;
+ public boolean isSSLEnabled() { return SSLEnabled; }
+ public void setSSLEnabled(boolean SSLEnabled) { this.SSLEnabled = SSLEnabled; }
/**
@@ -649,14 +649,8 @@ public class AprEndpoint {
Socket.optSet(serverSock, Socket.APR_TCP_DEFER_ACCEPT, 1);
// Initialize SSL if needed
- if (!"off".equalsIgnoreCase(SSLEngine)) {
- // Initialize SSL
- // FIXME: one per VM call ?
- if ("on".equalsIgnoreCase(SSLEngine)) {
- SSL.initialize(null);
- } else {
- SSL.initialize(SSLEngine);
- }
+ if (SSLEnabled) {
+
// SSL protocol
int value = SSL.SSL_PROTOCOL_ALL;
if ("SSLv2".equalsIgnoreCase(SSLProtocol)) {
diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java b/java/org/apache/tomcat/util/net/NioEndpoint.java
index fc611a0de..cccfbbafd 100644
--- a/java/org/apache/tomcat/util/net/NioEndpoint.java
+++ b/java/org/apache/tomcat/util/net/NioEndpoint.java
@@ -401,9 +401,9 @@ public class NioEndpoint {
/**
* SSL engine.
*/
- protected String SSLEngine = "off";
- public String getSSLEngine() { return SSLEngine;}
- public void setSSLEngine(String SSLEngine) {this.SSLEngine = SSLEngine;}
+ protected boolean SSLEnabled = false;
+ public boolean isSSLEnabled() { return SSLEnabled;}
+ public void setSSLEnabled(boolean SSLEnabled) {this.SSLEnabled = SSLEnabled;}
protected boolean secure = false;
public boolean getSecure() { return secure;}
@@ -509,7 +509,7 @@ public class NioEndpoint {
}
// Initialize SSL if needed
- if ("on".equalsIgnoreCase(getSSLEngine())) {
+ if (isSSLEnabled()) {
// Initialize SSL
char[] passphrase = getKeystorePass().toCharArray();
diff --git a/webapps/docs/apr.xml b/webapps/docs/apr.xml
index ff118874c..989c1b9c0 100644
--- a/webapps/docs/apr.xml
+++ b/webapps/docs/apr.xml
@@ -109,6 +109,22 @@
+
+
+
+
+ Name of the SSLEngine to use. off: Do not use SSL, on: Use SSL but no specific ENGINE.
+ The default value is on.
+ This initializes the native SSL engine, then enable the use of this engine in the connector
+ using the SSLEnabled attribute. Example:
+
+<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+
+
+
+
+
+
@@ -188,10 +204,10 @@
-
+
- Name of the SSLEngine to use. off: Do not use SSL, on: Use SSL but no specific ENGINE.
- The default value is off.
+ Enable SSL on the socket, default value is false. Set this value to true
+ to enable SSL handshake/encryption/decryption in the APR connector.
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 6e13b5d6e..8481b59bc 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -18,6 +18,9 @@
+ SSLEngine attribute added to the AprLifecycleListener(fhanik)
+
+
Add API for Comet IO handling (remm, fhanik)
@@ -38,7 +41,7 @@
- SSLEngine attribute required for SSL to be turned on, on all HTTP connectors(fhanik)
+ SSLEnabled attribute required for SSL to be turned on, on all HTTP connectors(fhanik)
diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml
index 9d5471b6e..ddbcaa08a 100644
--- a/webapps/docs/config/http.xml
+++ b/webapps/docs/config/http.xml
@@ -148,13 +148,13 @@
number specified here.
-
+
Use this attribute to enable SSL traffic on a connector.
To turn on SSL handshake/encryption/decryption on a connector
- set this value to on.
- The default value is off.
- When turning this value on you will want to set the
+ set this value to true.
+ The default value is false.
+ When turning this value true you will want to set the
scheme and the secure attributes as well
to pass the correct request.getScheme() and
request.isSecure() values to the servlets
diff --git a/webapps/docs/ssl-howto.xml b/webapps/docs/ssl-howto.xml
index 47ff1bc70..304218d2a 100644
--- a/webapps/docs/ssl-howto.xml
+++ b/webapps/docs/ssl-howto.xml
@@ -258,6 +258,23 @@ which contains further references for this issue.
+
If you are using APR, you have the option of configuring an alternative engine to openSSL.
+
+<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="someengine" />
+
+The default value is
+
+<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+
+So to use SSL under APR, make sure the SSLEngine attribute is set to something other than off.
+The default value is on and if you specify another value, it has to be a valid engine name.
+
+If you haven't compiled in SSL support into your Tomcat Native library, then you can turn this initialization off
+
+<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" />
+
+
+
The final step is to configure your secure socket in the
$CATALINA_HOME/conf/server.xml file, where
@@ -272,11 +289,72 @@ file installed with Tomcat. It will look something like this:
+ 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 autoload the APR connector. The APR connector uses different attributes for
+ SSL keys and certificates. An example of such configuration would be
+
+<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
+<!--
+<Connector
+ port="8443" minSpareThreads="5" maxSpareThreads="75"
+ enableLookups="true" disableUploadTimeout="true"
+ acceptCount="100" maxThreads="200"
+ scheme="https" secure="true" SSLEnabled="true"
+ SSLCertificateFile="/usr/local/ssl/server.crt"
+ SSLCertificateKeyFile="/usr/local/ssl/server.pem"
+ clientAuth="false" sslProtocol="TLS"/>
+-->
+
+
+
+
+ To avoid auto configuration you can define which connector to use by specifying a classname
+ in the protocol attribute.
+ To define a Java connector, regardless if the APR library is loaded or not do:
+
+<-- Define a blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 -->
+<!--
+<Connector protocol="org.apache.coyote.http11.Http11Protocol"
+ port="8443" minSpareThreads="5" maxSpareThreads="75"
+ enableLookups="true" disableUploadTimeout="true"
+ acceptCount="100" maxThreads="200"
+ scheme="https" secure="true" SSLEnabled="true"
+ keystoreFile="${user.home}/.keystore" keystorePass="changeit"
+ clientAuth="false" sslProtocol="TLS"/>
+-->
+<-- Define a non-blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 -->
+<!--
+<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
+ port="8443" minSpareThreads="5" maxSpareThreads="75"
+ enableLookups="true" disableUploadTimeout="true"
+ acceptCount="100" maxThreads="200"
+ scheme="https" secure="true" SSLEnabled="true"
keystoreFile="${user.home}/.keystore" keystorePass="changeit"
clientAuth="false" sslProtocol="TLS"/>
-->
+and to specify an APR connector
+
+<-- Define a APR SSL Coyote HTTP/1.1 Connector on port 8443 -->
+<!--
+<Connector protocol="org.apache.coyote.http11.Http11AprProtocol"
+ port="8443" minSpareThreads="5" maxSpareThreads="75"
+ enableLookups="true" disableUploadTimeout="true"
+ acceptCount="100" maxThreads="200"
+ scheme="https" secure="true" SSLEnabled="true"
+ SSLCertificateFile="/usr/local/ssl/server.crt"
+ SSLCertificateKeyFile="/usr/local/ssl/server.pem"
+ clientAuth="false" sslProtocol="TLS"/>
+-->
+
+
+
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
@@ -318,13 +396,13 @@ values, depending on how you configured your keystore earlier:
to request a client Certificate, but not fail if one isn't presented.
-
SSLEngine
+
SSLEnabled
Use this attribute to enable SSL traffic on a connector.
To turn on SSL handshake/encryption/decryption on a connector
- set this value to on.
- The default value is off.
- When turning this value on you will want to set the
+ set this value to true.
+ The default value is false.
+ When turning this value true you will want to set the
scheme and the secure attributes as well
to pass the correct request.getScheme() and
request.isSecure() values to the servlets
--
2.11.0