From 9ccb849eb69f05bccc3435306ec4bde104e411bf Mon Sep 17 00:00:00 2001 From: John Zhuge Date: Fri, 21 Apr 2017 02:10:33 -0700 Subject: [PATCH] HADOOP-14341. Support multi-line value for ssl.server.exclude.cipher.list. Contributed by John Zhuge. --- .../apache/hadoop/conf/ConfigRedactor.java | 4 +++- .../org/apache/hadoop/http/HttpServer2.java | 4 +++- .../hadoop/security/ssl/SSLFactory.java | 13 +++++------- .../org/apache/hadoop/util/StringUtils.java | 9 ++++---- .../apache/hadoop/http/TestSSLHttpServer.java | 21 ++++++++++--------- .../hadoop/security/ssl/TestSSLFactory.java | 10 +++++---- 6 files changed, 33 insertions(+), 28 deletions(-) diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/conf/ConfigRedactor.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/conf/ConfigRedactor.java index 90b260e34fd..5b2d1449f9c 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/conf/ConfigRedactor.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/conf/ConfigRedactor.java @@ -25,6 +25,8 @@ import java.util.regex.Pattern; import static org.apache.hadoop.fs.CommonConfigurationKeys.*; +import org.apache.hadoop.util.StringUtils; + /** * Tool for redacting sensitive information when displaying config parameters. * @@ -43,7 +45,7 @@ public class ConfigRedactor { HADOOP_SECURITY_SENSITIVE_CONFIG_KEYS, HADOOP_SECURITY_SENSITIVE_CONFIG_KEYS_DEFAULT); List sensitiveRegexes = - Arrays.asList(sensitiveRegexList.trim().split("[,\\s]+")); + Arrays.asList(StringUtils.getTrimmedStrings(sensitiveRegexList)); compiledPatterns = new ArrayList(); for (String regex : sensitiveRegexes) { Pattern p = Pattern.compile(regex); diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java index 25a40373482..bd10f93c801 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java @@ -73,6 +73,7 @@ import org.apache.hadoop.security.authorize.AccessControlList; import org.apache.hadoop.security.ssl.SSLFactory; import org.apache.hadoop.util.ReflectionUtils; import org.apache.hadoop.util.Shell; +import org.apache.hadoop.util.StringUtils; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; @@ -471,7 +472,8 @@ public final class HttpServer2 implements FilterContainer { sslContextFactory.setTrustStorePassword(trustStorePassword); } if(null != excludeCiphers && !excludeCiphers.isEmpty()) { - sslContextFactory.setExcludeCipherSuites(excludeCiphers.split(",")); + sslContextFactory.setExcludeCipherSuites( + StringUtils.getTrimmedStrings(excludeCiphers)); LOG.info("Excluded Cipher List:" + excludeCiphers); } diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/SSLFactory.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/SSLFactory.java index 07eafabb4ae..1c504882cb3 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/SSLFactory.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/SSLFactory.java @@ -39,7 +39,6 @@ import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; /** @@ -140,13 +139,11 @@ public class SSLFactory implements ConnectionConfigurator { enabledProtocols = conf.getStrings(SSL_ENABLED_PROTOCOLS_KEY, SSL_ENABLED_PROTOCOLS_DEFAULT); - String excludeCiphersConf = - sslConf.get(SSL_SERVER_EXCLUDE_CIPHER_LIST, ""); - if (excludeCiphersConf.isEmpty()) { - excludeCiphers = new LinkedList(); - } else { - LOG.debug("will exclude cipher suites: {}", excludeCiphersConf); - excludeCiphers = Arrays.asList(excludeCiphersConf.split(",")); + excludeCiphers = Arrays.asList( + sslConf.getTrimmedStrings(SSL_SERVER_EXCLUDE_CIPHER_LIST)); + if (LOG.isDebugEnabled()) { + LOG.debug("will exclude cipher suites: {}", + StringUtils.join(",", excludeCiphers)); } } diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/StringUtils.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/StringUtils.java index e773806c651..151761238a9 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/StringUtils.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/StringUtils.java @@ -440,10 +440,11 @@ public class StringUtils { } /** - * Splits a comma separated value String, trimming leading and - * trailing whitespace on each value. + * Splits a comma or newline separated value String, trimming + * leading and trailing whitespace on each value. * - * @param str a comma separated String with values, may be null + * @param str a comma or newline separated String with values, + * may be null * @return an array of String values, empty array if null String * input */ @@ -452,7 +453,7 @@ public class StringUtils { return emptyStringArray; } - return str.trim().split("\\s*,\\s*"); + return str.trim().split("\\s*[,\n]\\s*"); } final public static String[] emptyStringArray = {}; diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestSSLHttpServer.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestSSLHttpServer.java index 6eea70975f3..30aca57eefe 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestSSLHttpServer.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestSSLHttpServer.java @@ -41,6 +41,7 @@ import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.security.ssl.KeyStoreTestUtil; import org.apache.hadoop.security.ssl.SSLFactory; import org.apache.hadoop.test.GenericTestUtils; +import org.apache.hadoop.util.StringUtils; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -62,21 +63,21 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest { private static String sslConfDir; private static SSLFactory clientSslFactory; private static final String excludeCiphers = "TLS_ECDHE_RSA_WITH_RC4_128_SHA," - + "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA," + + "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, \n" + "SSL_RSA_WITH_DES_CBC_SHA," - + "SSL_DHE_RSA_WITH_DES_CBC_SHA," - + "SSL_RSA_EXPORT_WITH_RC4_40_MD5," + + "SSL_DHE_RSA_WITH_DES_CBC_SHA, " + + "SSL_RSA_EXPORT_WITH_RC4_40_MD5,\t \n" + "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA," - + "SSL_RSA_WITH_RC4_128_MD5"; + + "SSL_RSA_WITH_RC4_128_MD5 \t"; private static final String oneEnabledCiphers = excludeCiphers + ",TLS_RSA_WITH_AES_128_CBC_SHA"; private static final String exclusiveEnabledCiphers - = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + = "\tTLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, \n" + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + "TLS_RSA_WITH_AES_128_CBC_SHA," - + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, " + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA," - + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA," + + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA,\t\n " + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; @BeforeClass @@ -169,7 +170,7 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest { SSLSocketFactory sslSocketF = clientSslFactory.createSSLSocketFactory(); PrefferedCipherSSLSocketFactory testPreferredCipherSSLSocketF = new PrefferedCipherSSLSocketFactory(sslSocketF, - excludeCiphers.split(",")); + StringUtils.getTrimmedStrings(excludeCiphers)); conn.setSSLSocketFactory(testPreferredCipherSSLSocketF); assertFalse("excludedCipher list is empty", excludeCiphers.isEmpty()); try { @@ -193,7 +194,7 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest { SSLSocketFactory sslSocketF = clientSslFactory.createSSLSocketFactory(); PrefferedCipherSSLSocketFactory testPreferredCipherSSLSocketF = new PrefferedCipherSSLSocketFactory(sslSocketF, - oneEnabledCiphers.split(",")); + StringUtils.getTrimmedStrings(oneEnabledCiphers)); conn.setSSLSocketFactory(testPreferredCipherSSLSocketF); assertFalse("excludedCipher list is empty", oneEnabledCiphers.isEmpty()); try { @@ -219,7 +220,7 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest { SSLSocketFactory sslSocketF = clientSslFactory.createSSLSocketFactory(); PrefferedCipherSSLSocketFactory testPreferredCipherSSLSocketF = new PrefferedCipherSSLSocketFactory(sslSocketF, - exclusiveEnabledCiphers.split(",")); + StringUtils.getTrimmedStrings(exclusiveEnabledCiphers)); conn.setSSLSocketFactory(testPreferredCipherSSLSocketF); assertFalse("excludedCipher list is empty", exclusiveEnabledCiphers.isEmpty()); diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java index f0c502ebe12..5369c9d8d5e 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java @@ -25,6 +25,7 @@ import org.apache.hadoop.fs.Path; import org.apache.hadoop.security.alias.CredentialProviderFactory; import org.apache.hadoop.security.alias.JavaKeyStoreProvider; import org.apache.hadoop.test.GenericTestUtils; +import org.apache.hadoop.util.StringUtils; import org.apache.log4j.Level; import org.junit.After; import org.junit.Assert; @@ -57,10 +58,10 @@ public class TestSSLFactory { new File(BASEDIR).getAbsolutePath(); private String sslConfsDir; private static final String excludeCiphers = "TLS_ECDHE_RSA_WITH_RC4_128_SHA," - + "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA," + + "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, \n" + "SSL_RSA_WITH_DES_CBC_SHA," - + "SSL_DHE_RSA_WITH_DES_CBC_SHA," - + "SSL_RSA_EXPORT_WITH_RC4_40_MD5," + + "SSL_DHE_RSA_WITH_DES_CBC_SHA, " + + "SSL_RSA_EXPORT_WITH_RC4_40_MD5,\t \n" + "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA," + "SSL_RSA_WITH_RC4_128_MD5"; @@ -190,7 +191,8 @@ public class TestSSLFactory { SSLEngine serverSSLEngine = serverSSLFactory.createSSLEngine(); SSLEngine clientSSLEngine = clientSSLFactory.createSSLEngine(); // client selects cipher suites excluded by server - clientSSLEngine.setEnabledCipherSuites(excludeCiphers.split(",")); + clientSSLEngine.setEnabledCipherSuites( + StringUtils.getTrimmedStrings(excludeCiphers)); // use the same buffer size for server and client. SSLSession session = clientSSLEngine.getSession();