This is an automated email from the ASF dual-hosted git repository.

weichiu pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new c39e9fc  HADOOP-15169. "hadoop.ssl.enabled.protocols" should be 
considered in httpserver2. Contributed by Brahma Reddy Battula, Wei-Chiu Chuang.
c39e9fc is described below

commit c39e9fc9a3ce7bf6f627c003526fa903a69c2646
Author: Wei-Chiu Chuang <[email protected]>
AuthorDate: Tue Oct 15 13:55:23 2019 -0700

    HADOOP-15169. "hadoop.ssl.enabled.protocols" should be considered in 
httpserver2. Contributed by Brahma Reddy Battula, Wei-Chiu Chuang.
    
    Reviewed-by: Xiaoyu Yao <[email protected]>
    Co-authored-By: Brahma Reddy Battula <[email protected]>
---
 .../java/org/apache/hadoop/http/HttpServer2.java   |  34 +++++++
 .../org/apache/hadoop/http/TestSSLHttpServer.java  | 106 +++++++++++++++++++++
 2 files changed, 140 insertions(+)

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 04d5da1..74c8133 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
@@ -538,11 +538,45 @@ public final class HttpServer2 implements FilterContainer 
{
         LOG.info("Excluded Cipher List:" + excludeCiphers);
       }
 
+      setEnabledProtocols(sslContextFactory);
       conn.addFirstConnectionFactory(new 
SslConnectionFactory(sslContextFactory,
           HttpVersion.HTTP_1_1.asString()));
 
       return conn;
     }
+
+    private void setEnabledProtocols(SslContextFactory sslContextFactory) {
+      String enabledProtocols = conf.get(SSLFactory.SSL_ENABLED_PROTOCOLS_KEY,
+          SSLFactory.SSL_ENABLED_PROTOCOLS_DEFAULT);
+      if (!enabledProtocols.equals(SSLFactory.SSL_ENABLED_PROTOCOLS_DEFAULT)) {
+        // Jetty 9.2.4.v20141103 and above excludes certain protocols by
+        // default. Remove the user enabled protocols from the exclude list,
+        // and add them into the include list.
+        String[] jettyExcludedProtocols =
+            sslContextFactory.getExcludeProtocols();
+        String[] enabledProtocolsArray =
+            StringUtils.getTrimmedStrings(enabledProtocols);
+        List<String> enabledProtocolsList =
+            Arrays.asList(enabledProtocolsArray);
+
+        List<String> resetExcludedProtocols = new ArrayList<>();
+        for (String jettyExcludedProtocol: jettyExcludedProtocols) {
+          if (!enabledProtocolsList.contains(jettyExcludedProtocol)) {
+            resetExcludedProtocols.add(jettyExcludedProtocol);
+          } else {
+            LOG.debug("Removed {} from exclude protocol list",
+                jettyExcludedProtocol);
+          }
+        }
+
+        sslContextFactory.setExcludeProtocols(
+            resetExcludedProtocols.toArray(new String[0]));
+        LOG.info("Reset exclude protocol list: {}", resetExcludedProtocols);
+
+        sslContextFactory.setIncludeProtocols(enabledProtocolsArray);
+        LOG.info("Enabled protocols: {}", enabledProtocols);
+      }
+    }
   }
 
   private HttpServer2(final Builder b) throws IOException {
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 3f6ee7b..5f7a264 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
@@ -98,6 +98,8 @@ public class TestSSLHttpServer extends 
HttpServerFunctionalTest {
       + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA,\t\n "
       + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
 
+  private static final String INCLUDED_PROTOCOLS = "SSLv2Hello,TLSv1.1";
+
   @BeforeClass
   public static void setup() throws Exception {
     turnOnSSLDebugLogging();
@@ -128,6 +130,8 @@ public class TestSSLHttpServer extends 
HttpServerFunctionalTest {
 
   private static void setupServer(Configuration conf, Configuration sslConf)
       throws IOException, URISyntaxException {
+    conf.set(SSLFactory.SSL_ENABLED_PROTOCOLS_KEY, INCLUDED_PROTOCOLS);
+    sslConf.set(SSLFactory.SSL_ENABLED_PROTOCOLS_KEY, INCLUDED_PROTOCOLS);
     server = new HttpServer2.Builder().setName("test")
         .addEndpoint(new URI("https://localhost";)).setConf(conf)
         .keyPassword(
@@ -214,6 +218,22 @@ public class TestSSLHttpServer extends 
HttpServerFunctionalTest {
     return conn;
   }
 
+  private HttpsURLConnection
+      getConnectionWithPreferredProtocolSSLSocketFactory(URL url,
+      String protocols) throws IOException, GeneralSecurityException {
+    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
+    SSLSocketFactory sslSocketFactory = clientSslFactory
+        .createSSLSocketFactory();
+    LOG.info("Creating " +
+        PreferredProtocolSSLSocketFactory.class.getCanonicalName() +
+        " with protocols: " + protocols);
+    PreferredProtocolSSLSocketFactory cipherSSLSocketFactory
+        = new PreferredProtocolSSLSocketFactory(sslSocketFactory,
+        StringUtils.getTrimmedStrings(protocols));
+    conn.setSSLSocketFactory(cipherSSLSocketFactory);
+    return conn;
+  }
+
   @Test
   public void testEcho() throws Exception {
     assertEquals("a:b\nc:d\n",
@@ -269,6 +289,18 @@ public class TestSSLHttpServer extends 
HttpServerFunctionalTest {
     }
   }
 
+  @Test
+  public void testIncludedProtocols() throws Exception {
+    URL url = new URL(baseUrl, SERVLET_PATH_ECHO + "?a=b&c=d");
+    HttpsURLConnection conn =
+        getConnectionWithPreferredProtocolSSLSocketFactory(url,
+        INCLUDED_PROTOCOLS);
+    assertFalse("included protocol list is empty",
+        INCLUDED_PROTOCOLS.isEmpty());
+
+    readFromConnection(conn);
+  }
+
   /** Test that verified that additionally included cipher
    * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is only available cipher for working
    * TLS connection from client to server disabled for all other common 
ciphers.
@@ -370,4 +402,78 @@ public class TestSSLHttpServer extends 
HttpServerFunctionalTest {
       }
     }
   }
+
+  private class PreferredProtocolSSLSocketFactory extends SSLSocketFactory {
+    private final SSLSocketFactory delegateSocketFactory;
+    private final String[] enabledProtocols;
+
+    PreferredProtocolSSLSocketFactory(SSLSocketFactory sslSocketFactory,
+        String[] enabledProtocols) {
+      delegateSocketFactory = sslSocketFactory;
+      if (null != enabledProtocols && enabledProtocols.length > 0) {
+        this.enabledProtocols = enabledProtocols;
+      } else {
+        this.enabledProtocols = null;
+      }
+    }
+
+    @Override
+    public String[] getDefaultCipherSuites() {
+      return delegateSocketFactory.getDefaultCipherSuites();
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+      return delegateSocketFactory.getSupportedCipherSuites();
+    }
+
+    @Override
+    public Socket createSocket(Socket socket, String string, int i, boolean 
bln)
+        throws IOException {
+      SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(
+          socket, string, i, bln);
+      setEnabledProtocols(sslSocket);
+      return sslSocket;
+    }
+
+    @Override
+    public Socket createSocket(String string, int i) throws IOException {
+      SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(
+          string, i);
+      setEnabledProtocols(sslSocket);
+      return sslSocket;
+    }
+
+    @Override
+    public Socket createSocket(String string, int i, InetAddress ia, int i1)
+        throws IOException {
+      SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(
+          string, i, ia, i1);
+      setEnabledProtocols(sslSocket);
+      return sslSocket;
+    }
+
+    @Override
+    public Socket createSocket(InetAddress ia, int i) throws IOException {
+      SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(ia,
+          i);
+      setEnabledProtocols(sslSocket);
+      return sslSocket;
+    }
+
+    @Override
+    public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1)
+        throws IOException {
+      SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(ia,
+          i, ia1, i1);
+      setEnabledProtocols(sslSocket);
+      return sslSocket;
+    }
+
+    private void setEnabledProtocols(SSLSocket sslSocket) {
+      if (null != enabledProtocols) {
+        sslSocket.setEnabledProtocols(enabledProtocols);
+      }
+    }
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to