Author: tucu
Date: Tue Aug 5 21:31:03 2014
New Revision: 1616009
URL: http://svn.apache.org/r1616009
Log:
HADOOP-10933. FileBasedKeyStoresFactory Should use Configuration.getPassword
for SSL Passwords. (lmccay via tucu)
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt?rev=1616009&r1=1616008&r2=1616009&view=diff
==============================================================================
---
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
(original)
+++
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
Tue Aug 5 21:31:03 2014
@@ -103,6 +103,9 @@ Release 2.6.0 - UNRELEASED
HADOOP-10927. Fix CredentialShell help behavior and error codes.
(Josh Elser via wang)
+ HADOOP-10933. FileBasedKeyStoresFactory Should use
Configuration.getPassword
+ for SSL Passwords. (lmccay via tucu)
+
Release 2.5.0 - UNRELEASED
INCOMPATIBLE CHANGES
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java?rev=1616009&r1=1616008&r2=1616009&view=diff
==============================================================================
---
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java
(original)
+++
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java
Tue Aug 5 21:31:03 2014
@@ -150,7 +150,7 @@ public class FileBasedKeyStoresFactory i
}
String passwordProperty =
resolvePropertyName(mode, SSL_KEYSTORE_PASSWORD_TPL_KEY);
- String keystorePassword = conf.get(passwordProperty, "");
+ String keystorePassword = getPassword(conf, passwordProperty, "");
if (keystorePassword.isEmpty()) {
throw new GeneralSecurityException("The property '" + passwordProperty
+
"' has not been set in the ssl configuration file.");
@@ -160,7 +160,8 @@ public class FileBasedKeyStoresFactory i
// Key password defaults to the same value as store password for
// compatibility with legacy configurations that did not use a separate
// configuration property for key password.
- keystoreKeyPassword = conf.get(keyPasswordProperty, keystorePassword);
+ keystoreKeyPassword = getPassword(
+ conf, keyPasswordProperty, keystorePassword);
LOG.debug(mode.toString() + " KeyStore: " + keystoreLocation);
InputStream is = new FileInputStream(keystoreLocation);
@@ -191,7 +192,7 @@ public class FileBasedKeyStoresFactory i
if (!truststoreLocation.isEmpty()) {
String passwordProperty = resolvePropertyName(mode,
SSL_TRUSTSTORE_PASSWORD_TPL_KEY);
- String truststorePassword = conf.get(passwordProperty, "");
+ String truststorePassword = getPassword(conf, passwordProperty, "");
if (truststorePassword.isEmpty()) {
throw new GeneralSecurityException("The property '" + passwordProperty
+
"' has not been set in the ssl configuration file.");
@@ -217,6 +218,21 @@ public class FileBasedKeyStoresFactory i
}
}
+ String getPassword(Configuration conf, String alias, String defaultPass) {
+ String password = defaultPass;
+ try {
+ char[] passchars = conf.getPassword(alias);
+ if (passchars != null) {
+ password = new String(passchars);
+ }
+ }
+ catch (IOException ioe) {
+ LOG.warn("Exception while trying to get password for alias " + alias +
+ ": " + ioe.getMessage());
+ }
+ return password;
+ }
+
/**
* Releases any resources being used.
*/
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java?rev=1616009&r1=1616008&r2=1616009&view=diff
==============================================================================
---
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
(original)
+++
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
Tue Aug 5 21:31:03 2014
@@ -19,6 +19,10 @@
package org.apache.hadoop.security.ssl;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.alias.CredentialProvider;
+import org.apache.hadoop.security.alias.CredentialProviderFactory;
+import org.apache.hadoop.security.alias.JavaKeyStoreProvider;
+
import sun.security.x509.AlgorithmId;
import sun.security.x509.CertificateAlgorithmId;
import sun.security.x509.CertificateIssuerName;
@@ -382,4 +386,41 @@ public class KeyStoreTestUtil {
writer.close();
}
}
+
+ public static void provisionPasswordsToCredentialProvider() throws Exception
{
+ File testDir = new File(System.getProperty("test.build.data",
+ "target/test-dir"));
+
+ Configuration conf = new Configuration();
+ final String ourUrl =
+ JavaKeyStoreProvider.SCHEME_NAME + "://file/" + testDir + "/test.jks";
+
+ File file = new File(testDir, "test.jks");
+ file.delete();
+ conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, ourUrl);
+
+ CredentialProvider provider =
+ CredentialProviderFactory.getProviders(conf).get(0);
+ char[] keypass = {'k', 'e', 'y', 'p', 'a', 's', 's'};
+ char[] storepass = {'s', 't', 'o', 'r', 'e', 'p', 'a', 's', 's'};
+
+ // create new aliases
+ try {
+ provider.createCredentialEntry(
+ FileBasedKeyStoresFactory.resolvePropertyName(SSLFactory.Mode.SERVER,
+ FileBasedKeyStoresFactory.SSL_KEYSTORE_PASSWORD_TPL_KEY),
+ storepass);
+
+ provider.createCredentialEntry(
+ FileBasedKeyStoresFactory.resolvePropertyName(SSLFactory.Mode.SERVER,
+ FileBasedKeyStoresFactory.SSL_KEYSTORE_KEYPASSWORD_TPL_KEY),
+ keypass);
+
+ // write out so that it can be found in checks
+ provider.flush();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
}
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java?rev=1616009&r1=1616008&r2=1616009&view=diff
==============================================================================
---
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java
(original)
+++
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java
Tue Aug 5 21:31:03 2014
@@ -17,8 +17,14 @@
*/
package org.apache.hadoop.security.ssl;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileUtil;
+import org.apache.hadoop.security.alias.CredentialProvider;
+import org.apache.hadoop.security.alias.CredentialProviderFactory;
+import org.apache.hadoop.security.alias.JavaKeyStoreProvider;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -211,6 +217,13 @@ public class TestSSLFactory {
"password", "password", null);
}
+ @Test
+ public void testServerCredProviderPasswords() throws Exception {
+ KeyStoreTestUtil.provisionPasswordsToCredentialProvider();
+ checkSSLFactoryInitWithPasswords(SSLFactory.Mode.SERVER,
+ "storepass", "keypass", null, null, true);
+ }
+
/**
* Checks that SSLFactory initialization is successful with the given
* arguments. This is a helper method for writing test cases that cover
@@ -218,7 +231,7 @@ public class TestSSLFactory {
* It takes care of bootstrapping a keystore, a truststore, and SSL client or
* server configuration. Then, it initializes an SSLFactory. If no
exception
* is thrown, then initialization was successful.
- *
+ *
* @param mode SSLFactory.Mode mode to test
* @param password String store password to set on keystore
* @param keyPassword String key password to set on keystore
@@ -231,6 +244,34 @@ public class TestSSLFactory {
private void checkSSLFactoryInitWithPasswords(SSLFactory.Mode mode,
String password, String keyPassword, String confPassword,
String confKeyPassword) throws Exception {
+ checkSSLFactoryInitWithPasswords(mode, password, keyPassword,
+ confPassword, confKeyPassword, false);
+ }
+
+ /**
+ * Checks that SSLFactory initialization is successful with the given
+ * arguments. This is a helper method for writing test cases that cover
+ * different combinations of settings for the store password and key
password.
+ * It takes care of bootstrapping a keystore, a truststore, and SSL client or
+ * server configuration. Then, it initializes an SSLFactory. If no
exception
+ * is thrown, then initialization was successful.
+ *
+ * @param mode SSLFactory.Mode mode to test
+ * @param password String store password to set on keystore
+ * @param keyPassword String key password to set on keystore
+ * @param confPassword String store password to set in SSL config file, or
null
+ * to avoid setting in SSL config file
+ * @param confKeyPassword String key password to set in SSL config file, or
+ * null to avoid setting in SSL config file
+ * @param useCredProvider boolean to indicate whether passwords should be set
+ * into the config or not. When set to true nulls are set and aliases are
+ * expected to be resolved through credential provider API through the
+ * Configuration.getPassword method
+ * @throws Exception for any error
+ */
+ private void checkSSLFactoryInitWithPasswords(SSLFactory.Mode mode,
+ String password, String keyPassword, String confPassword,
+ String confKeyPassword, boolean useCredProvider) throws Exception {
String keystore = new File(KEYSTORES_DIR,
"keystore.jks").getAbsolutePath();
String truststore = new File(KEYSTORES_DIR, "truststore.jks")
.getAbsolutePath();
@@ -249,10 +290,25 @@ public class TestSSLFactory {
// Create SSL configuration file, for either server or client.
final String sslConfFileName;
final Configuration sslConf;
+
+ // if the passwords are provisioned in a cred provider then don't set them
+ // in the configuration properly - expect them to be resolved through the
+ // provider
+ if (useCredProvider) {
+ confPassword = null;
+ confKeyPassword = null;
+ }
if (mode == SSLFactory.Mode.SERVER) {
sslConfFileName = "ssl-server.xml";
sslConf = KeyStoreTestUtil.createServerSSLConfig(keystore, confPassword,
confKeyPassword, truststore);
+ if (useCredProvider) {
+ File testDir = new File(System.getProperty("test.build.data",
+ "target/test-dir"));
+ final String ourUrl =
+ JavaKeyStoreProvider.SCHEME_NAME + "://file/" + testDir +
"/test.jks";
+ sslConf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH,
ourUrl);
+ }
} else {
sslConfFileName = "ssl-client.xml";
sslConf = KeyStoreTestUtil.createClientSSLConfig(keystore, confPassword,