From: fhanik Date: Thu, 19 Oct 2006 16:45:45 +0000 (+0000) Subject: SSLEngine is an attribute of the APR lifecycle listener to initialize the native... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=0cad225c48cdf5d29520c65a0e23e044e60d7c6d;p=tomcat7.0 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 --- 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:

port="8443" minSpareThreads="5" maxSpareThreads="75" enableLookups="true" disableUploadTimeout="true" acceptCount="100" maxThreads="200" - scheme="https" secure="true" SSLEngine="on" + scheme="https" secure="true" SSLEnabled="true" + keystoreFile="${user.home}/.keystore" keystorePass="changeit" + clientAuth="false" sslProtocol="TLS"/> +--> + +

+ 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