OOZIE-2771 Allow retrieving keystore and truststore passwords from Hadoop 
Credential Provider (asasvari via abhishekbafna)

(cherry picked from commit f0c4f2daf61ca7c8b059d55be0465025b79f123e)

        
server/src/main/java/org/apache/oozie/server/SSLServerConnectorFactory.java


Project: http://git-wip-us.apache.org/repos/asf/oozie/repo
Commit: http://git-wip-us.apache.org/repos/asf/oozie/commit/6e5dccf7
Tree: http://git-wip-us.apache.org/repos/asf/oozie/tree/6e5dccf7
Diff: http://git-wip-us.apache.org/repos/asf/oozie/diff/6e5dccf7

Branch: refs/heads/branch-4.3
Commit: 6e5dccf75c8898320850e8386f45a169dacb9ad7
Parents: 3b24d9d
Author: abhisek bafna <[email protected]>
Authored: Wed Jan 25 12:24:38 2017 +0530
Committer: satishsaley <[email protected]>
Committed: Fri Dec 8 16:34:55 2017 -0800

----------------------------------------------------------------------
 release-log.txt                                 |   1 +
 .../oozie/server/SSLServerConnectorFactory.java | 167 +++++++++++++++++++
 2 files changed, 168 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/oozie/blob/6e5dccf7/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index e1026d6..147149e 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -1,5 +1,6 @@
 -- Oozie 4.3.1 release
 
+OOZIE-2771 Allow retrieving keystore and truststore passwords from Hadoop 
Credential Provider (asasvari via abhishekbafna)
 OOZIE-2748 NPE in LauncherMapper.printArgs() (pbacsko via rkanter)
 OOZIE-2654 Zookeeper dependent services should not depend on Connectionstate 
to be valid before cleaning up (venkatnrangan via abhishekbafna)
 OOZIE-2690 OOZIE NPE while executing kill() (abhishekbafna via 
jaydeepvishwakarma)

http://git-wip-us.apache.org/repos/asf/oozie/blob/6e5dccf7/server/src/main/java/org/apache/oozie/server/SSLServerConnectorFactory.java
----------------------------------------------------------------------
diff --git 
a/server/src/main/java/org/apache/oozie/server/SSLServerConnectorFactory.java 
b/server/src/main/java/org/apache/oozie/server/SSLServerConnectorFactory.java
new file mode 100644
index 0000000..a7253d7
--- /dev/null
+++ 
b/server/src/main/java/org/apache/oozie/server/SSLServerConnectorFactory.java
@@ -0,0 +1,167 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.oozie.server;
+
+
+import com.google.common.base.Preconditions;
+import com.google.inject.Inject;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.oozie.service.ConfigurationService;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+
+/**
+ * Factory that is used to configure SSL settings for the Oozie server.
+ */
+class SSLServerConnectorFactory {
+    private static final Logger LOG = 
LoggerFactory.getLogger(SSLServerConnectorFactory.class);
+    public static final String OOZIE_HTTPS_TRUSTSTORE_FILE = 
"oozie.https.truststore.file";
+    public static final String OOZIE_HTTPS_TRUSTSTORE_PASS = 
"oozie.https.truststore.pass";
+    public static final String OOZIE_HTTPS_KEYSTORE_PASS = 
"oozie.https.keystore.pass";
+    public static final String OOZIE_HTTPS_KEYSTORE_FILE = 
"oozie.https.keystore.file";
+    public static final String OOZIE_HTTPS_EXCLUDE_PROTOCOLS = 
"oozie.https.exclude.protocols";
+    public static final String OOZIE_HTTPS_INCLUDE_PROTOCOLS = 
"oozie.https.include.protocols";
+    public static final String OOZIE_HTTPS_INCLUDE_CIPHER_SUITES = 
"oozie.https.include.cipher.suites";
+    public static final String OOZIE_HTTPS_EXCLUDE_CIPHER_SUITES = 
"oozie.https.exclude.cipher.suites";
+
+    private SslContextFactory sslContextFactory;
+    private Configuration conf;
+
+    @Inject
+    public SSLServerConnectorFactory(final SslContextFactory 
sslContextFactory) {
+        this.sslContextFactory = Preconditions.checkNotNull(sslContextFactory, 
 "sslContextFactory is null");
+    }
+
+    /**
+     *  Construct a ServerConnector object with SSL settings
+     *
+     *  @param oozieHttpsPort Oozie HTTPS port
+     *  @param conf Oozie configuration
+     *  @param server jetty Server which the connector is attached to
+     *
+     *  @return ServerConnector
+    */
+    public ServerConnector createSecureServerConnector(int oozieHttpsPort, 
Configuration conf, Server server) {
+        this.conf = Preconditions.checkNotNull(conf, "conf is null");
+        Preconditions.checkNotNull(server, "server is null");
+        Preconditions.checkState(oozieHttpsPort >= 1 && oozieHttpsPort <= 
65535,
+                String.format("Invalid port number specified: \'%d\'. It 
should be between 1 and 65535.", oozieHttpsPort));
+
+        setIncludeProtocols();
+        setExcludeProtocols();
+
+        setIncludeCipherSuites();
+        setExludeCipherSuites();
+
+        setTrustStorePath();
+        setTrustStorePass();
+
+        setKeyStoreFile();
+        setKeystorePass();
+
+        HttpConfiguration httpsConfiguration = getHttpsConfiguration();
+        ServerConnector secureServerConnector = new ServerConnector(server,
+                new SslConnectionFactory(sslContextFactory, 
HttpVersion.HTTP_1_1.asString()),
+                new HttpConnectionFactory(httpsConfiguration));
+
+        secureServerConnector.setPort(oozieHttpsPort);
+
+        LOG.info(String.format("Secure server connector created, listenning on 
port %d", oozieHttpsPort));
+        return secureServerConnector;
+    }
+
+    private void setExludeCipherSuites() {
+        String excludeCipherList = conf.get(OOZIE_HTTPS_EXCLUDE_CIPHER_SUITES);
+        String[] excludeCipherSuites = excludeCipherList.split(",");
+        sslContextFactory.setExcludeCipherSuites(excludeCipherSuites);
+
+        LOG.info(String.format("SSL context - excluding cipher suites: %s", 
Arrays.toString(excludeCipherSuites)));
+    }
+
+    private void setIncludeCipherSuites() {
+        String includeCipherList = conf.get(OOZIE_HTTPS_INCLUDE_CIPHER_SUITES);
+        if (includeCipherList == null || includeCipherList.isEmpty()) {
+            return;
+        }
+
+        String[] includeCipherSuites = includeCipherList.split(",");
+        sslContextFactory.setIncludeCipherSuites(includeCipherSuites);
+
+        LOG.info(String.format("SSL context - including cipher suites: %s", 
Arrays.toString(includeCipherSuites)));
+    }
+
+    private void setIncludeProtocols() {
+        String enabledProtocolsList = conf.get(OOZIE_HTTPS_INCLUDE_PROTOCOLS);
+        String[] enabledProtocols = enabledProtocolsList.split(",");
+        sslContextFactory.setIncludeProtocols(enabledProtocols);
+
+        LOG.info(String.format("SSL context - including protocols: %s", 
Arrays.toString(enabledProtocols)));
+    }
+
+    private void setExcludeProtocols() {
+        String excludedProtocolsList = conf.get(OOZIE_HTTPS_EXCLUDE_PROTOCOLS);
+        if (excludedProtocolsList == null || excludedProtocolsList.isEmpty()) {
+            return;
+        }
+        String[] excludedProtocols = excludedProtocolsList.split(",");
+        sslContextFactory.setExcludeProtocols(excludedProtocols);
+        LOG.info(String.format("SSL context - excluding protocols: %s", 
Arrays.toString(excludedProtocols)));
+    }
+
+    private void setTrustStorePath() {
+        String trustStorePath = conf.get(OOZIE_HTTPS_TRUSTSTORE_FILE);
+        Preconditions.checkNotNull(trustStorePath, "trustStorePath is null");
+        sslContextFactory.setTrustStorePath(trustStorePath);
+    }
+
+    private void setTrustStorePass() {
+        String trustStorePass = ConfigurationService.getPassword(conf, 
OOZIE_HTTPS_TRUSTSTORE_PASS).trim();
+        Preconditions.checkNotNull(trustStorePass, "setTrustStorePass is 
null");
+        sslContextFactory.setTrustStorePassword(trustStorePass);
+    }
+
+    private void setKeystorePass() {
+        String keystorePass = ConfigurationService.getPassword(conf, 
OOZIE_HTTPS_KEYSTORE_PASS).trim();
+        Preconditions.checkNotNull(keystorePass, "keystorePass is null");
+        sslContextFactory.setKeyManagerPassword(keystorePass);
+    }
+
+    private void setKeyStoreFile() {
+        String keystoreFile = conf.get(OOZIE_HTTPS_KEYSTORE_FILE);
+        Preconditions.checkNotNull(keystoreFile, "keystoreFile is null");
+        sslContextFactory.setKeyStorePath(keystoreFile);
+    }
+
+    private HttpConfiguration getHttpsConfiguration() {
+        HttpConfiguration https = new 
HttpConfigurationWrapper(conf).getDefaultHttpConfiguration();
+        https.setSecureScheme("https");
+        https.addCustomizer(new SecureRequestCustomizer());
+        return https;
+    }
+}

Reply via email to