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