Author: rjung
Date: Tue May 26 15:37:39 2015
New Revision: 1681779

URL: http://svn.apache.org/r1681779
Log:
Supporting "+" and "-" syntax in SSL protocol
(OpenSSL) only.

This allows settings like "all-TLSv1" (or if you
prefer "all,-TLSv1"). The preferred way to add
protocols now is to use an explicit "+" prefix.
If you omit the "+" (except for the first token
in the list) you get a warning. The list is always
build starting with an empty list, even if the
first token has a "+" prefix.

This is similar to the mod_ssl behavior. It differs
in the handling of a token without "+" or "-":
mod_ssl would reset the list, we just add to the list,
both for compatibility reasons.

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
    tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java
    tomcat/trunk/webapps/docs/config/http.xml

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties?rev=1681779&r1=1681778&r2=1681779&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties Tue 
May 26 15:37:39 2015
@@ -115,4 +115,5 @@ socket.apr.write.error=Unexpected error
 socket.apr.closed=The socket [{0}] associated with this connection has been 
closed.
 
 sslHostConfig.certificateVerificationInvalid=The certificate verification 
value [{0}] is not recognised
-sslHostConfig.mismatch=The property [{0}] was set on the SSLHostConfig named 
[{1}] but this property is for connectors of type [{2}] by the SSLHostConfig is 
being used with a connector of type [{3}]
\ No newline at end of file
+sslHostConfig.mismatch=The property [{0}] was set on the SSLHostConfig named 
[{1}] but this property is for connectors of type [{2}] by the SSLHostConfig is 
being used with a connector of type [{3}]
+sslHostConfig.prefix_missing=The protocol [{0}] was added to the list of 
protocols on the SSLHostConfig named [{1}]. Check if a +/- prefix is missing.

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java?rev=1681779&r1=1681778&r2=1681779&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java Tue May 26 
15:37:39 2015
@@ -39,6 +39,14 @@ public class SSLHostConfig {
     private static final StringManager sm = 
StringManager.getManager(SSLHostConfig.class);
 
     protected static final String DEFAULT_SSL_HOST_NAME = "_default_";
+    protected static final Set<String> SSL_PROTO_ALL = new HashSet<>();
+
+    static {
+        SSL_PROTO_ALL.add(Constants.SSL_PROTO_SSLv2Hello);
+        SSL_PROTO_ALL.add(Constants.SSL_PROTO_TLSv1);
+        SSL_PROTO_ALL.add(Constants.SSL_PROTO_TLSv1_1);
+        SSL_PROTO_ALL.add(Constants.SSL_PROTO_TLSv1_2);
+    }
 
     private Type configType = null;
     private Map<Type,Set<String>> configuredProperties = new HashMap<>();
@@ -230,21 +238,50 @@ public class SSLHostConfig {
 
 
     public void setProtocols(String input) {
-        // OpenSSL and JSSE use the same names.
-        String[] values = input.split(",|\\+");
-
         protocols.clear();
 
-        for (String value: values) {
+        // List of protocol names, separated by ",", "+" or "-".
+        // Semantics is adding ("+") or removing ("-") from left
+        // to right, starting with an empty protocol set.
+        // Tokens are individual protocol names or "all" for a
+        // default set of suppported protocols.
+        // Separator "," is only kept for compatibility and has the
+        // same semantics as "+", except that it warns about a potentially
+        // missing "+" or "-".
+
+        // Split using a positive lookahead to keep the separator in
+        // the capture so we can check which case it is.
+        for (String value: input.split("(?=[-+,]")) {
             String trimmed = value.trim();
-            if (trimmed.length() > 0) {
-                if (input.trim().equalsIgnoreCase(Constants.SSL_PROTO_ALL)) {
-                    protocols.add(Constants.SSL_PROTO_SSLv2Hello);
-                    protocols.add(Constants.SSL_PROTO_TLSv1);
-                    protocols.add(Constants.SSL_PROTO_TLSv1_1);
-                    protocols.add(Constants.SSL_PROTO_TLSv1_2);
+            // Ignore token which only consists or prefix character
+            if (trimmed.length() > 1) {
+                if (trimmed.charAt(0) == '+') {
+                    trimmed = trimmed.substring(1).trim();
+                    if (trimmed.equalsIgnoreCase(Constants.SSL_PROTO_ALL)) {
+                        protocols.addAll(SSL_PROTO_ALL);
+                    } else {
+                        protocols.add(trimmed);
+                    }
+                } else if (trimmed.charAt(0) == '-') {
+                    trimmed = trimmed.substring(1).trim();
+                    if (trimmed.equalsIgnoreCase(Constants.SSL_PROTO_ALL)) {
+                        protocols.removeAll(SSL_PROTO_ALL);
+                    } else {
+                        protocols.remove(trimmed);
+                    }
                 } else {
-                    protocols.add(trimmed);
+                    if (trimmed.charAt(0) == ',') {
+                        trimmed = trimmed.substring(1).trim();
+                    }
+                    if (!protocols.isEmpty()) {
+                        log.warn(sm.getString("sslHostConfig.prefix_missing",
+                                 trimmed, getHostName()));
+                    }
+                    if (trimmed.equalsIgnoreCase(Constants.SSL_PROTO_ALL)) {
+                        protocols.addAll(SSL_PROTO_ALL);
+                    } else {
+                        protocols.add(trimmed);
+                    }
                 }
             }
         }

Modified: tomcat/trunk/webapps/docs/config/http.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1681779&r1=1681778&r2=1681779&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/http.xml (original)
+++ tomcat/trunk/webapps/docs/config/http.xml Tue May 26 15:37:39 2015
@@ -1218,18 +1218,23 @@
     </attribute>
 
     <attribute name="protocols" required="false">
+      <p>OpenSSL only, for JSSE use <code>sslProtocol</code>.</p>
       <p>The names of the protocols to support when communicating with clients.
-      This should be a comma separated list of any combination of the 
following:
+      This should be a list of any combination of the following:
       </p>
       <ul><li>SSLv2Hello</li><li>SSLv2</li><li>SSLv3</li><li>TLSv1</li>
           <li>TLSv1.1</li><li>TLSv1.2</li><li>all</li></ul>
+      <p>Each token in the list can be prefixed with a plus sign ("+")
+      or a minus sign ("-"). A plus sign adds the protocol, a minus sign
+      removes it form the current list. The list is built starting from
+      an empty list.</p>
+      <p>The token <code>all</code> is an alias for
+      <code>SSLv2Hello,TLSv1,TLSv1.1,TLSv1.2</code>.</p>
       <p>Note that <code>SSLv2Hello</code> will be ignored for OpenSSL based
       secure connectors. If more than one protocol is specified for an OpenSSL
-      based secure connector it will support <code>SSLv2Hello</code>. If a
+      based secure connector it will always support <code>SSLv2Hello</code>. 
If a
       single protocol is specified it will not support
       <code>SSLv2Hello</code>.</p>
-      <p>Note that <code>all</code> is an alias for
-      <code>SSLv2Hello,TLSv1,TLSv1.1,TLSv1.2</code>.</p>
       <p>Note that <code>SSLv2</code> and <code>SSLv3</code> are inherently
       unsafe.</p>
       <p>If not specified, the default value of <code>all</code> will be
@@ -1251,7 +1256,7 @@
     </attribute>
 
     <attribute name="sslProtocol" required="false">
-      <p>JSSE only.</p>
+      <p>JSSE only, for OpenSSL use <code>protocols</code>.</p>
       <p>The the SSL protocol(s) to use (a single value may enable multiple
       protocols - see the JVM documentation for details). If not specified, the
       default is <code>TLS</code>. The permitted values may be obtained from 
the



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to