You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by wa...@apache.org on 2014/08/07 22:26:54 UTC
svn commit: r1616589 - in
/hadoop/common/branches/fs-encryption/hadoop-common-project: hadoop-auth/
hadoop-auth/dev-support/
hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/
hadoop-auth/src/main/java/org/apache/hadoop/securit...
Author: wang
Date: Thu Aug 7 20:26:52 2014
New Revision: 1616589
URL: http://svn.apache.org/r1616589
Log:
Merge from trunk to branch.
Added:
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/dev-support/
- copied from r1616586, hadoop/common/trunk/hadoop-common-project/hadoop-auth/dev-support/
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/RandomSignerSecretProvider.java
- copied unchanged from r1616586, hadoop/common/trunk/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/RandomSignerSecretProvider.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/RolloverSignerSecretProvider.java
- copied unchanged from r1616586, hadoop/common/trunk/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/RolloverSignerSecretProvider.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/SignerSecretProvider.java
- copied unchanged from r1616586, hadoop/common/trunk/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/SignerSecretProvider.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/StringSignerSecretProvider.java
- copied unchanged from r1616586, hadoop/common/trunk/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/StringSignerSecretProvider.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestRandomSignerSecretProvider.java
- copied unchanged from r1616586, hadoop/common/trunk/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestRandomSignerSecretProvider.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestRolloverSignerSecretProvider.java
- copied unchanged from r1616586, hadoop/common/trunk/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestRolloverSignerSecretProvider.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestStringSignerSecretProvider.java
- copied unchanged from r1616586, hadoop/common/trunk/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestStringSignerSecretProvider.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJMXServlet.java
- copied unchanged from r1616586, hadoop/common/trunk/hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJMXServlet.java
Modified:
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/pom.xml
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/Signer.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationFilter.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestSigner.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES.txt (contents, props changed)
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/ (props changed)
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/jmx/JMXJsonServlet.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/site/apt/CommandsManual.apt.vm
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProviderFactory.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMapping.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-kms/src/main/webapp/WEB-INF/web.xml
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/pom.xml
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/pom.xml?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/pom.xml (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/pom.xml Thu Aug 7 20:26:52 2014
@@ -150,6 +150,13 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <excludeFilterFile>${basedir}/dev-support/findbugsExcludeFile.xml</excludeFilterFile>
+ </configuration>
+ </plugin>
</plugins>
</build>
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java Thu Aug 7 20:26:52 2014
@@ -19,6 +19,9 @@ import org.apache.hadoop.security.authen
import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.hadoop.security.authentication.util.Signer;
import org.apache.hadoop.security.authentication.util.SignerException;
+import org.apache.hadoop.security.authentication.util.RandomSignerSecretProvider;
+import org.apache.hadoop.security.authentication.util.SignerSecretProvider;
+import org.apache.hadoop.security.authentication.util.StringSignerSecretProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -107,11 +110,28 @@ public class AuthenticationFilter implem
*/
public static final String COOKIE_PATH = "cookie.path";
- private static final Random RAN = new Random();
+ /**
+ * Constant for the configuration property that indicates the name of the
+ * SignerSecretProvider class to use. If not specified, SIGNATURE_SECRET
+ * will be used or a random secret.
+ */
+ public static final String SIGNER_SECRET_PROVIDER_CLASS =
+ "signer.secret.provider";
+
+ /**
+ * Constant for the attribute that can be used for providing a custom
+ * object that subclasses the SignerSecretProvider. Note that this should be
+ * set in the ServletContext and the class should already be initialized.
+ * If not specified, SIGNER_SECRET_PROVIDER_CLASS will be used.
+ */
+ public static final String SIGNATURE_PROVIDER_ATTRIBUTE =
+ "org.apache.hadoop.security.authentication.util.SignerSecretProvider";
private Signer signer;
+ private SignerSecretProvider secretProvider;
private AuthenticationHandler authHandler;
private boolean randomSecret;
+ private boolean customSecretProvider;
private long validity;
private String cookieDomain;
private String cookiePath;
@@ -159,14 +179,46 @@ public class AuthenticationFilter implem
} catch (IllegalAccessException ex) {
throw new ServletException(ex);
}
- String signatureSecret = config.getProperty(configPrefix + SIGNATURE_SECRET);
- if (signatureSecret == null) {
- signatureSecret = Long.toString(RAN.nextLong());
- randomSecret = true;
- LOG.warn("'signature.secret' configuration not set, using a random value as secret");
+
+ validity = Long.parseLong(config.getProperty(AUTH_TOKEN_VALIDITY, "36000"))
+ * 1000; //10 hours
+ secretProvider = (SignerSecretProvider) filterConfig.getServletContext().
+ getAttribute(SIGNATURE_PROVIDER_ATTRIBUTE);
+ if (secretProvider == null) {
+ String signerSecretProviderClassName =
+ config.getProperty(configPrefix + SIGNER_SECRET_PROVIDER_CLASS, null);
+ if (signerSecretProviderClassName == null) {
+ String signatureSecret =
+ config.getProperty(configPrefix + SIGNATURE_SECRET, null);
+ if (signatureSecret != null) {
+ secretProvider = new StringSignerSecretProvider(signatureSecret);
+ } else {
+ secretProvider = new RandomSignerSecretProvider();
+ randomSecret = true;
+ }
+ } else {
+ try {
+ Class<?> klass = Thread.currentThread().getContextClassLoader().
+ loadClass(signerSecretProviderClassName);
+ secretProvider = (SignerSecretProvider) klass.newInstance();
+ customSecretProvider = true;
+ } catch (ClassNotFoundException ex) {
+ throw new ServletException(ex);
+ } catch (InstantiationException ex) {
+ throw new ServletException(ex);
+ } catch (IllegalAccessException ex) {
+ throw new ServletException(ex);
+ }
+ }
+ try {
+ secretProvider.init(config, validity);
+ } catch (Exception ex) {
+ throw new ServletException(ex);
+ }
+ } else {
+ customSecretProvider = true;
}
- signer = new Signer(signatureSecret.getBytes());
- validity = Long.parseLong(config.getProperty(AUTH_TOKEN_VALIDITY, "36000")) * 1000; //10 hours
+ signer = new Signer(secretProvider);
cookieDomain = config.getProperty(COOKIE_DOMAIN, null);
cookiePath = config.getProperty(COOKIE_PATH, null);
@@ -191,6 +243,15 @@ public class AuthenticationFilter implem
}
/**
+ * Returns if a custom implementation of a SignerSecretProvider is being used.
+ *
+ * @return if a custom implementation of a SignerSecretProvider is being used.
+ */
+ protected boolean isCustomSignerSecretProvider() {
+ return customSecretProvider;
+ }
+
+ /**
* Returns the validity time of the generated tokens.
*
* @return the validity time of the generated tokens, in seconds.
@@ -228,6 +289,9 @@ public class AuthenticationFilter implem
authHandler.destroy();
authHandler = null;
}
+ if (secretProvider != null) {
+ secretProvider.destroy();
+ }
}
/**
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/Signer.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/Signer.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/Signer.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/Signer.java Thu Aug 7 20:26:52 2014
@@ -24,18 +24,19 @@ import java.security.NoSuchAlgorithmExce
public class Signer {
private static final String SIGNATURE = "&s=";
- private byte[] secret;
+ private SignerSecretProvider secretProvider;
/**
- * Creates a Signer instance using the specified secret.
+ * Creates a Signer instance using the specified SignerSecretProvider. The
+ * SignerSecretProvider should already be initialized.
*
- * @param secret secret to use for creating the digest.
+ * @param secretProvider The SignerSecretProvider to use
*/
- public Signer(byte[] secret) {
- if (secret == null) {
- throw new IllegalArgumentException("secret cannot be NULL");
+ public Signer(SignerSecretProvider secretProvider) {
+ if (secretProvider == null) {
+ throw new IllegalArgumentException("secretProvider cannot be NULL");
}
- this.secret = secret.clone();
+ this.secretProvider = secretProvider;
}
/**
@@ -47,11 +48,12 @@ public class Signer {
*
* @return the signed string.
*/
- public String sign(String str) {
+ public synchronized String sign(String str) {
if (str == null || str.length() == 0) {
throw new IllegalArgumentException("NULL or empty string to sign");
}
- String signature = computeSignature(str);
+ byte[] secret = secretProvider.getCurrentSecret();
+ String signature = computeSignature(secret, str);
return str + SIGNATURE + signature;
}
@@ -71,21 +73,19 @@ public class Signer {
}
String originalSignature = signedStr.substring(index + SIGNATURE.length());
String rawValue = signedStr.substring(0, index);
- String currentSignature = computeSignature(rawValue);
- if (!originalSignature.equals(currentSignature)) {
- throw new SignerException("Invalid signature");
- }
+ checkSignatures(rawValue, originalSignature);
return rawValue;
}
/**
* Returns then signature of a string.
*
+ * @param secret The secret to use
* @param str string to sign.
*
* @return the signature for the string.
*/
- protected String computeSignature(String str) {
+ protected String computeSignature(byte[] secret, String str) {
try {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(str.getBytes());
@@ -97,4 +97,22 @@ public class Signer {
}
}
+ protected void checkSignatures(String rawValue, String originalSignature)
+ throws SignerException {
+ boolean isValid = false;
+ byte[][] secrets = secretProvider.getAllSecrets();
+ for (int i = 0; i < secrets.length; i++) {
+ byte[] secret = secrets[i];
+ if (secret != null) {
+ String currentSignature = computeSignature(secret, rawValue);
+ if (originalSignature.equals(currentSignature)) {
+ isValid = true;
+ break;
+ }
+ }
+ }
+ if (!isValid) {
+ throw new SignerException("Invalid signature");
+ }
+ }
}
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationFilter.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationFilter.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationFilter.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationFilter.java Thu Aug 7 20:26:52 2014
@@ -23,6 +23,7 @@ import java.util.Vector;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -33,6 +34,8 @@ import javax.servlet.http.HttpServletRes
import org.apache.hadoop.security.authentication.client.AuthenticatedURL;
import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.hadoop.security.authentication.util.Signer;
+import org.apache.hadoop.security.authentication.util.SignerSecretProvider;
+import org.apache.hadoop.security.authentication.util.StringSignerSecretProvider;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
@@ -157,9 +160,14 @@ public class TestAuthenticationFilter {
Mockito.when(config.getInitParameterNames()).thenReturn(
new Vector<String>(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.AUTH_TOKEN_VALIDITY)).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
Assert.assertEquals(PseudoAuthenticationHandler.class, filter.getAuthenticationHandler().getClass());
Assert.assertTrue(filter.isRandomSecret());
+ Assert.assertFalse(filter.isCustomSignerSecretProvider());
Assert.assertNull(filter.getCookieDomain());
Assert.assertNull(filter.getCookiePath());
Assert.assertEquals(TOKEN_VALIDITY_SEC, filter.getValidity());
@@ -167,6 +175,26 @@ public class TestAuthenticationFilter {
filter.destroy();
}
+ // string secret
+ filter = new AuthenticationFilter();
+ try {
+ FilterConfig config = Mockito.mock(FilterConfig.class);
+ Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn("simple");
+ Mockito.when(config.getInitParameter(AuthenticationFilter.SIGNATURE_SECRET)).thenReturn("secret");
+ Mockito.when(config.getInitParameterNames()).thenReturn(
+ new Vector<String>(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
+ AuthenticationFilter.SIGNATURE_SECRET)).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
+ filter.init(config);
+ Assert.assertFalse(filter.isRandomSecret());
+ Assert.assertFalse(filter.isCustomSignerSecretProvider());
+ } finally {
+ filter.destroy();
+ }
+
// custom secret
filter = new AuthenticationFilter();
try {
@@ -176,8 +204,26 @@ public class TestAuthenticationFilter {
Mockito.when(config.getInitParameterNames()).thenReturn(
new Vector<String>(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.SIGNATURE_SECRET)).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(
+ new SignerSecretProvider() {
+ @Override
+ public void init(Properties config, long tokenValidity) {
+ }
+ @Override
+ public byte[] getCurrentSecret() {
+ return null;
+ }
+ @Override
+ public byte[][] getAllSecrets() {
+ return null;
+ }
+ });
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
Assert.assertFalse(filter.isRandomSecret());
+ Assert.assertTrue(filter.isCustomSignerSecretProvider());
} finally {
filter.destroy();
}
@@ -193,6 +239,10 @@ public class TestAuthenticationFilter {
new Vector<String>(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.COOKIE_DOMAIN,
AuthenticationFilter.COOKIE_PATH)).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
Assert.assertEquals(".foo.com", filter.getCookieDomain());
Assert.assertEquals("/bar", filter.getCookiePath());
@@ -213,6 +263,10 @@ public class TestAuthenticationFilter {
new Vector<String>(
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
Assert.assertTrue(DummyAuthenticationHandler.init);
} finally {
@@ -248,6 +302,10 @@ public class TestAuthenticationFilter {
Mockito.when(config.getInitParameterNames()).thenReturn(
new Vector<String>(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.AUTH_TOKEN_VALIDITY)).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
Assert.assertEquals(PseudoAuthenticationHandler.class,
@@ -270,6 +328,10 @@ public class TestAuthenticationFilter {
new Vector<String>(
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
@@ -297,11 +359,15 @@ public class TestAuthenticationFilter {
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.SIGNATURE_SECRET,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
AuthenticationToken token = new AuthenticationToken("u", "p", DummyAuthenticationHandler.TYPE);
token.setExpires(System.currentTimeMillis() + TOKEN_VALIDITY_SEC);
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
String tokenSigned = signer.sign(token.toString());
Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
@@ -330,12 +396,16 @@ public class TestAuthenticationFilter {
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.SIGNATURE_SECRET,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
AuthenticationToken token =
new AuthenticationToken("u", "p", DummyAuthenticationHandler.TYPE);
token.setExpires(System.currentTimeMillis() - TOKEN_VALIDITY_SEC);
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
String tokenSigned = signer.sign(token.toString());
Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
@@ -371,11 +441,15 @@ public class TestAuthenticationFilter {
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.SIGNATURE_SECRET,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
AuthenticationToken token = new AuthenticationToken("u", "p", "invalidtype");
token.setExpires(System.currentTimeMillis() + TOKEN_VALIDITY_SEC);
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
String tokenSigned = signer.sign(token.toString());
Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
@@ -409,6 +483,10 @@ public class TestAuthenticationFilter {
new Vector<String>(
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
@@ -458,6 +536,10 @@ public class TestAuthenticationFilter {
AuthenticationFilter.AUTH_TOKEN_VALIDITY,
AuthenticationFilter.SIGNATURE_SECRET, "management.operation" +
".return", "expired.token")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
if (withDomainPath) {
Mockito.when(config.getInitParameter(AuthenticationFilter
@@ -511,7 +593,7 @@ public class TestAuthenticationFilter {
Mockito.verify(chain).doFilter(Mockito.any(ServletRequest.class),
Mockito.any(ServletResponse.class));
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
String value = signer.verifyAndExtract(v);
AuthenticationToken token = AuthenticationToken.parse(value);
assertThat(token.getExpires(), not(0L));
@@ -578,6 +660,10 @@ public class TestAuthenticationFilter {
new Vector<String>(
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
@@ -585,7 +671,7 @@ public class TestAuthenticationFilter {
AuthenticationToken token = new AuthenticationToken("u", "p", "t");
token.setExpires(System.currentTimeMillis() + TOKEN_VALIDITY_SEC);
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
String tokenSigned = signer.sign(token.toString());
Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
@@ -628,6 +714,10 @@ public class TestAuthenticationFilter {
new Vector<String>(
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
@@ -691,6 +781,10 @@ public class TestAuthenticationFilter {
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.SIGNATURE_SECRET,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
@@ -698,7 +792,7 @@ public class TestAuthenticationFilter {
AuthenticationToken token = new AuthenticationToken("u", "p", DummyAuthenticationHandler.TYPE);
token.setExpires(System.currentTimeMillis() - TOKEN_VALIDITY_SEC);
- Signer signer = new Signer(secret.getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider(secret));
String tokenSigned = signer.sign(token.toString());
Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
@@ -758,6 +852,10 @@ public class TestAuthenticationFilter {
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
AuthenticationFilter.SIGNATURE_SECRET,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
@@ -765,7 +863,7 @@ public class TestAuthenticationFilter {
AuthenticationToken token = new AuthenticationToken("u", "p", "invalidtype");
token.setExpires(System.currentTimeMillis() + TOKEN_VALIDITY_SEC);
- Signer signer = new Signer(secret.getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider(secret));
String tokenSigned = signer.sign(token.toString());
Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
@@ -793,6 +891,10 @@ public class TestAuthenticationFilter {
new Vector<String>(
Arrays.asList(AuthenticationFilter.AUTH_TYPE,
"management.operation.return")).elements());
+ ServletContext context = Mockito.mock(ServletContext.class);
+ Mockito.when(context.getAttribute(
+ AuthenticationFilter.SIGNATURE_PROVIDER_ATTRIBUTE)).thenReturn(null);
+ Mockito.when(config.getServletContext()).thenReturn(context);
filter.init(config);
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
@@ -812,7 +914,7 @@ public class TestAuthenticationFilter {
AuthenticationToken token = new AuthenticationToken("u", "p", "t");
token.setExpires(System.currentTimeMillis() + TOKEN_VALIDITY_SEC);
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
String tokenSigned = signer.sign(token.toString());
Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
Mockito.when(request.getCookies()).thenReturn(new Cookie[]{cookie});
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestSigner.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestSigner.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestSigner.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestSigner.java Thu Aug 7 20:26:52 2014
@@ -13,24 +13,15 @@
*/
package org.apache.hadoop.security.authentication.util;
+import java.util.Properties;
import org.junit.Assert;
import org.junit.Test;
public class TestSigner {
@Test
- public void testNoSecret() throws Exception {
- try {
- new Signer(null);
- Assert.fail();
- }
- catch (IllegalArgumentException ex) {
- }
- }
-
- @Test
public void testNullAndEmptyString() throws Exception {
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
try {
signer.sign(null);
Assert.fail();
@@ -51,17 +42,17 @@ public class TestSigner {
@Test
public void testSignature() throws Exception {
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
String s1 = signer.sign("ok");
String s2 = signer.sign("ok");
String s3 = signer.sign("wrong");
Assert.assertEquals(s1, s2);
- Assert.assertNotSame(s1, s3);
+ Assert.assertNotEquals(s1, s3);
}
@Test
public void testVerify() throws Exception {
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
String t = "test";
String s = signer.sign(t);
String e = signer.verifyAndExtract(s);
@@ -70,7 +61,7 @@ public class TestSigner {
@Test
public void testInvalidSignedText() throws Exception {
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
try {
signer.verifyAndExtract("test");
Assert.fail();
@@ -83,7 +74,7 @@ public class TestSigner {
@Test
public void testTampering() throws Exception {
- Signer signer = new Signer("secret".getBytes());
+ Signer signer = new Signer(new StringSignerSecretProvider("secret"));
String t = "test";
String s = signer.sign(t);
s += "x";
@@ -96,4 +87,66 @@ public class TestSigner {
Assert.fail();
}
}
+
+ @Test
+ public void testMultipleSecrets() throws Exception {
+ TestSignerSecretProvider secretProvider = new TestSignerSecretProvider();
+ Signer signer = new Signer(secretProvider);
+ secretProvider.setCurrentSecret("secretB");
+ String t1 = "test";
+ String s1 = signer.sign(t1);
+ String e1 = signer.verifyAndExtract(s1);
+ Assert.assertEquals(t1, e1);
+ secretProvider.setPreviousSecret("secretA");
+ String t2 = "test";
+ String s2 = signer.sign(t2);
+ String e2 = signer.verifyAndExtract(s2);
+ Assert.assertEquals(t2, e2);
+ Assert.assertEquals(s1, s2); //check is using current secret for signing
+ secretProvider.setCurrentSecret("secretC");
+ secretProvider.setPreviousSecret("secretB");
+ String t3 = "test";
+ String s3 = signer.sign(t3);
+ String e3 = signer.verifyAndExtract(s3);
+ Assert.assertEquals(t3, e3);
+ Assert.assertNotEquals(s1, s3); //check not using current secret for signing
+ String e1b = signer.verifyAndExtract(s1);
+ Assert.assertEquals(t1, e1b); // previous secret still valid
+ secretProvider.setCurrentSecret("secretD");
+ secretProvider.setPreviousSecret("secretC");
+ try {
+ signer.verifyAndExtract(s1); // previous secret no longer valid
+ Assert.fail();
+ } catch (SignerException ex) {
+ // Expected
+ }
+ }
+
+ class TestSignerSecretProvider extends SignerSecretProvider {
+
+ private byte[] currentSecret;
+ private byte[] previousSecret;
+
+ @Override
+ public void init(Properties config, long tokenValidity) {
+ }
+
+ @Override
+ public byte[] getCurrentSecret() {
+ return currentSecret;
+ }
+
+ @Override
+ public byte[][] getAllSecrets() {
+ return new byte[][]{currentSecret, previousSecret};
+ }
+
+ public void setCurrentSecret(String secretStr) {
+ currentSecret = secretStr.getBytes();
+ }
+
+ public void setPreviousSecret(String previousSecretStr) {
+ previousSecret = previousSecretStr.getBytes();
+ }
+ }
}
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES.txt?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES.txt (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES.txt Thu Aug 7 20:26:52 2014
@@ -418,6 +418,9 @@ Trunk (Unreleased)
HADOOP-10925. Compilation fails in native link0 function on Windows.
(cnauroth)
+ HADOOP-10939. Fix TestKeyProviderFactory testcases to use default 128 bit
+ length keys. (Arun Suresh via wang)
+
OPTIMIZATIONS
HADOOP-7761. Improve the performance of raw comparisons. (todd)
@@ -484,6 +487,9 @@ Release 2.6.0 - UNRELEASED
HADOOP-10903. Enhance hadoop classpath command to expand wildcards or write
classpath into jar manifest. (cnauroth)
+ HADOOP-10791. AuthenticationFilter should support externalizing the
+ secret for signing and provide rotation support. (rkanter via tucu)
+
OPTIMIZATIONS
BUG FIXES
@@ -527,6 +533,18 @@ Release 2.6.0 - UNRELEASED
HADOOP-10937. Need to set version name correctly before decrypting EEK.
(Arun Suresh via wang)
+ HADOOP-10918. JMXJsonServlet fails when used within Tomcat. (tucu)
+
+ HADOOP-10933. FileBasedKeyStoresFactory Should use Configuration.getPassword
+ for SSL Passwords. (lmccay via tucu)
+
+ HADOOP-10759. Remove hardcoded JAVA_HEAP_MAX. (Sam Liu via Eric Yang)
+
+ HADOOP-10905. LdapGroupsMapping Should use configuration.getPassword for SSL
+ and LDAP Passwords. (lmccay via brandonli)
+
+ HADOOP-10931 compile error on tools/hadoop-openstack (xukun via stevel)
+
Release 2.5.0 - UNRELEASED
INCOMPATIBLE CHANGES
@@ -667,8 +685,6 @@ Release 2.5.0 - UNRELEASED
BUG FIXES
- HADOOP-10759. Remove hardcoded JAVA_HEAP_MAX. (Sam Liu via Eric Yang)
-
HADOOP-10378. Typo in help printed by hdfs dfs -help.
(Mit Desai via suresh)
Propchange: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES.txt
------------------------------------------------------------------------------
Merged /hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt:r1616481
Merged /hadoop/common/trunk/hadoop-common-project/hadoop-common/CHANGES.txt:r1615851-1616586
Propchange: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/
------------------------------------------------------------------------------
Merged /hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java:r1615851-1616586
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java Thu Aug 7 20:26:52 2014
@@ -1005,7 +1005,7 @@ public final class HttpServer2 implement
String remoteUser = request.getRemoteUser();
if (remoteUser == null) {
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
+ response.sendError(HttpServletResponse.SC_FORBIDDEN,
"Unauthenticated users are not " +
"authorized to access this page.");
return false;
@@ -1013,7 +1013,7 @@ public final class HttpServer2 implement
if (servletContext.getAttribute(ADMINS_ACL) != null &&
!userHasAdministratorAccess(servletContext, remoteUser)) {
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User "
+ response.sendError(HttpServletResponse.SC_FORBIDDEN, "User "
+ remoteUser + " is unauthorized to access this page.");
return false;
}
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/jmx/JMXJsonServlet.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/jmx/JMXJsonServlet.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/jmx/JMXJsonServlet.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/jmx/JMXJsonServlet.java Thu Aug 7 20:26:52 2014
@@ -143,6 +143,12 @@ public class JMXJsonServlet extends Http
jsonFactory = new JsonFactory();
}
+ protected boolean isInstrumentationAccessAllowed(HttpServletRequest request,
+ HttpServletResponse response) throws IOException {
+ return HttpServer2.isInstrumentationAccessAllowed(getServletContext(),
+ request, response);
+ }
+
/**
* Process a GET request for the specified resource.
*
@@ -154,8 +160,7 @@ public class JMXJsonServlet extends Http
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
try {
- if (!HttpServer2.isInstrumentationAccessAllowed(getServletContext(),
- request, response)) {
+ if (!isInstrumentationAccessAllowed(request, response)) {
return;
}
JsonGenerator jg = null;
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java Thu Aug 7 20:26:52 2014
@@ -312,15 +312,15 @@ public class LdapGroupsMapping
useSsl = conf.getBoolean(LDAP_USE_SSL_KEY, LDAP_USE_SSL_DEFAULT);
keystore = conf.get(LDAP_KEYSTORE_KEY, LDAP_KEYSTORE_DEFAULT);
- keystorePass =
- conf.get(LDAP_KEYSTORE_PASSWORD_KEY, LDAP_KEYSTORE_PASSWORD_DEFAULT);
+ keystorePass = getPassword(conf, LDAP_KEYSTORE_PASSWORD_KEY,
+ LDAP_KEYSTORE_PASSWORD_DEFAULT);
if (keystorePass.isEmpty()) {
keystorePass = extractPassword(conf.get(LDAP_KEYSTORE_PASSWORD_FILE_KEY,
LDAP_KEYSTORE_PASSWORD_FILE_DEFAULT));
}
bindUser = conf.get(BIND_USER_KEY, BIND_USER_DEFAULT);
- bindPassword = conf.get(BIND_PASSWORD_KEY, BIND_PASSWORD_DEFAULT);
+ bindPassword = getPassword(conf, BIND_PASSWORD_KEY, BIND_PASSWORD_DEFAULT);
if (bindPassword.isEmpty()) {
bindPassword = extractPassword(
conf.get(BIND_PASSWORD_FILE_KEY, BIND_PASSWORD_FILE_DEFAULT));
@@ -341,7 +341,25 @@ public class LdapGroupsMapping
this.conf = conf;
}
-
+
+ String getPassword(Configuration conf, String alias, String defaultPass) {
+ String password = null;
+ try {
+ char[] passchars = conf.getPassword(alias);
+ if (passchars != null) {
+ password = new String(passchars);
+ }
+ else {
+ password = defaultPass;
+ }
+ }
+ catch (IOException ioe) {
+ LOG.warn("Exception while trying to password for alias " + alias + ": "
+ + ioe.getMessage());
+ }
+ return password;
+ }
+
String extractPassword(String pwFile) {
if (pwFile.isEmpty()) {
// If there is no password file defined, we'll assume that we should do
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/FileBasedKeyStoresFactory.java Thu Aug 7 20:26:52 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/fs-encryption/hadoop-common-project/hadoop-common/src/site/apt/CommandsManual.apt.vm
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/site/apt/CommandsManual.apt.vm?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/site/apt/CommandsManual.apt.vm (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/site/apt/CommandsManual.apt.vm Thu Aug 7 20:26:52 2014
@@ -114,57 +114,18 @@ User Commands
* <<<fs>>>
- Usage: <<<hadoop fs [GENERIC_OPTIONS] [COMMAND_OPTIONS]>>>
-
- Deprecated, use <<<hdfs dfs>>> instead.
-
- Runs a generic filesystem user client.
-
- The various COMMAND_OPTIONS can be found at File System Shell Guide.
+ Deprecated, use {{{../hadoop-hdfs/HDFSCommands.html#dfs}<<<hdfs dfs>>>}}
+ instead.
* <<<fsck>>>
- Runs a HDFS filesystem checking utility.
- See {{{../hadoop-hdfs/HdfsUserGuide.html#fsck}fsck}} for more info.
-
- Usage: <<<hadoop fsck [GENERIC_OPTIONS] <path> [-move | -delete | -openforwrite] [-files [-blocks [-locations | -racks]]] [-showprogress]>>>
-
-*------------------+---------------------------------------------+
-|| COMMAND_OPTION || Description
-*------------------+---------------------------------------------+
-| <path> | Start checking from this path.
-*------------------+---------------------------------------------+
-| -move | Move corrupted files to /lost+found
-*------------------+---------------------------------------------+
-| -delete | Delete corrupted files.
-*------------------+---------------------------------------------+
-| -openforwrite | Print out files opened for write.
-*------------------+---------------------------------------------+
-| -files | Print out files being checked.
-*------------------+---------------------------------------------+
-| -blocks | Print out block report.
-*------------------+---------------------------------------------+
-| -locations | Print out locations for every block.
-*------------------+---------------------------------------------+
-| -racks | Print out network topology for data-node locations.
-*------------------+---------------------------------------------+
-| -showprogress | Print out show progress in output. Default is OFF (no progress).
-*------------------+---------------------------------------------+
+ Deprecated, use {{{../hadoop-hdfs/HDFSCommands.html#fsck}<<<hdfs fsck>>>}}
+ instead.
* <<<fetchdt>>>
- Gets Delegation Token from a NameNode.
- See {{{../hadoop-hdfs/HdfsUserGuide.html#fetchdt}fetchdt}} for more info.
-
- Usage: <<<hadoop fetchdt [GENERIC_OPTIONS] [--webservice <namenode_http_addr>] <path> >>>
-
-*------------------------------+---------------------------------------------+
-|| COMMAND_OPTION || Description
-*------------------------------+---------------------------------------------+
-| <fileName> | File name to store the token into.
-*------------------------------+---------------------------------------------+
-| --webservice <https_address> | use http protocol instead of RPC
-*------------------------------+---------------------------------------------+
+ Deprecated, use {{{../hadoop-hdfs/HDFSCommands.html#fetchdt}
+ <<<hdfs fetchdt>>>}} instead.
* <<<jar>>>
@@ -321,23 +282,8 @@ Administration Commands
* <<<balancer>>>
- Runs a cluster balancing utility. An administrator can simply press Ctrl-C
- to stop the rebalancing process. See
- {{{../hadoop-hdfs/HdfsUserGuide.html#Balancer}Balancer}} for more details.
-
- Usage: <<<hadoop balancer [-threshold <threshold>] [-policy <policy>]>>>
-
-*------------------------+-----------------------------------------------------------+
-|| COMMAND_OPTION | Description
-*------------------------+-----------------------------------------------------------+
-| -threshold <threshold> | Percentage of disk capacity. This overwrites the
- | default threshold.
-*------------------------+-----------------------------------------------------------+
-| -policy <policy> | <<<datanode>>> (default): Cluster is balanced if each datanode is balanced. \
- | <<<blockpool>>>: Cluster is balanced if each block pool in each datanode is balanced.
-*------------------------+-----------------------------------------------------------+
-
- Note that the <<<blockpool>>> policy is more strict than the <<<datanode>>> policy.
+ Deprecated, use {{{../hadoop-hdfs/HDFSCommands.html#balancer}
+ <<<hdfs balancer>>>}} instead.
* <<<daemonlog>>>
@@ -360,84 +306,13 @@ Administration Commands
* <<<datanode>>>
- Runs a HDFS datanode.
-
- Usage: <<<hadoop datanode [-rollback]>>>
-
-*-----------------+-----------------------------------------------------------+
-|| COMMAND_OPTION || Description
-*-----------------+-----------------------------------------------------------+
-| -rollback | Rollsback the datanode to the previous version. This should
- | be used after stopping the datanode and distributing the old
- | hadoop version.
-*-----------------+-----------------------------------------------------------+
+ Deprecated, use {{{../hadoop-hdfs/HDFSCommands.html#datanode}
+ <<<hdfs datanode>>>}} instead.
* <<<dfsadmin>>>
- Runs a HDFS dfsadmin client.
-
- Usage: <<<hadoop dfsadmin [GENERIC_OPTIONS] [-report] [-safemode enter | leave | get | wait] [-refreshNodes] [-finalizeUpgrade] [-upgradeProgress status | details | force] [-metasave filename] [-setQuota <quota> <dirname>...<dirname>] [-clrQuota <dirname>...<dirname>] [-restoreFailedStorage true|false|check] [-help [cmd]]>>>
-
-*-----------------+-----------------------------------------------------------+
-|| COMMAND_OPTION || Description
-*-----------------+-----------------------------------------------------------+
-| -report | Reports basic filesystem information and statistics.
-*-----------------+-----------------------------------------------------------+
-| -safemode enter / leave / get / wait | Safe mode maintenance command. Safe
- | mode is a Namenode state in which it \
- | 1. does not accept changes to the name space (read-only) \
- | 2. does not replicate or delete blocks. \
- | Safe mode is entered automatically at Namenode startup, and
- | leaves safe mode automatically when the configured minimum
- | percentage of blocks satisfies the minimum replication
- | condition. Safe mode can also be entered manually, but then
- | it can only be turned off manually as well.
-*-----------------+-----------------------------------------------------------+
-| -refreshNodes | Re-read the hosts and exclude files to update the set of
- | Datanodes that are allowed to connect to the Namenode and
- | those that should be decommissioned or recommissioned.
-*-----------------+-----------------------------------------------------------+
-| -finalizeUpgrade| Finalize upgrade of HDFS. Datanodes delete their previous
- | version working directories, followed by Namenode doing the
- | same. This completes the upgrade process.
-*-----------------+-----------------------------------------------------------+
-| -upgradeProgress status / details / force | Request current distributed
- | upgrade status, a detailed status or force the upgrade to
- | proceed.
-*-----------------+-----------------------------------------------------------+
-| -metasave filename | Save Namenode's primary data structures to <filename> in
- | the directory specified by hadoop.log.dir property.
- | <filename> is overwritten if it exists.
- | <filename> will contain one line for each of the following\
- | 1. Datanodes heart beating with Namenode\
- | 2. Blocks waiting to be replicated\
- | 3. Blocks currrently being replicated\
- | 4. Blocks waiting to be deleted\
-*-----------------+-----------------------------------------------------------+
-| -setQuota <quota> <dirname>...<dirname> | Set the quota <quota> for each
- | directory <dirname>. The directory quota is a long integer
- | that puts a hard limit on the number of names in the
- | directory tree. Best effort for the directory, with faults
- | reported if \
- | 1. N is not a positive integer, or \
- | 2. user is not an administrator, or \
- | 3. the directory does not exist or is a file, or \
- | 4. the directory would immediately exceed the new quota. \
-*-----------------+-----------------------------------------------------------+
-| -clrQuota <dirname>...<dirname> | Clear the quota for each directory
- | <dirname>. Best effort for the directory. with fault
- | reported if \
- | 1. the directory does not exist or is a file, or \
- | 2. user is not an administrator. It does not fault if the
- | directory has no quota.
-*-----------------+-----------------------------------------------------------+
-| -restoreFailedStorage true / false / check | This option will turn on/off automatic attempt to restore failed storage replicas.
- | If a failed storage becomes available again the system will attempt to restore
- | edits and/or fsimage during checkpoint. 'check' option will return current setting.
-*-----------------+-----------------------------------------------------------+
-| -help [cmd] | Displays help for the given command or all commands if none
- | is specified.
-*-----------------+-----------------------------------------------------------+
+ Deprecated, use {{{../hadoop-hdfs/HDFSCommands.html#dfsadmin}
+ <<<hdfs dfsadmin>>>}} instead.
* <<<mradmin>>>
@@ -470,51 +345,13 @@ Administration Commands
* <<<namenode>>>
- Runs the namenode. More info about the upgrade, rollback and finalize is
- at {{{../hadoop-hdfs/HdfsUserGuide.html#Upgrade_and_Rollback}Upgrade Rollback}}.
-
- Usage: <<<hadoop namenode [-format] | [-upgrade] | [-rollback] | [-finalize] | [-importCheckpoint]>>>
-
-*--------------------+-----------------------------------------------------------+
-|| COMMAND_OPTION || Description
-*--------------------+-----------------------------------------------------------+
-| -format | Formats the namenode. It starts the namenode, formats
- | it and then shut it down.
-*--------------------+-----------------------------------------------------------+
-| -upgrade | Namenode should be started with upgrade option after
- | the distribution of new hadoop version.
-*--------------------+-----------------------------------------------------------+
-| -rollback | Rollsback the namenode to the previous version. This
- | should be used after stopping the cluster and
- | distributing the old hadoop version.
-*--------------------+-----------------------------------------------------------+
-| -finalize | Finalize will remove the previous state of the files
- | system. Recent upgrade will become permanent. Rollback
- | option will not be available anymore. After finalization
- | it shuts the namenode down.
-*--------------------+-----------------------------------------------------------+
-| -importCheckpoint | Loads image from a checkpoint directory and save it
- | into the current one. Checkpoint dir is read from
- | property fs.checkpoint.dir
-*--------------------+-----------------------------------------------------------+
+ Deprecated, use {{{../hadoop-hdfs/HDFSCommands.html#namenode}
+ <<<hdfs namenode>>>}} instead.
* <<<secondarynamenode>>>
- Runs the HDFS secondary namenode.
- See {{{../hadoop-hdfs/HdfsUserGuide.html#Secondary_NameNode}Secondary Namenode}}
- for more info.
-
- Usage: <<<hadoop secondarynamenode [-checkpoint [force]] | [-geteditsize]>>>
-
-*----------------------+-----------------------------------------------------------+
-|| COMMAND_OPTION || Description
-*----------------------+-----------------------------------------------------------+
-| -checkpoint [-force] | Checkpoints the Secondary namenode if EditLog size
- | >= fs.checkpoint.size. If <<<-force>>> is used,
- | checkpoint irrespective of EditLog size.
-*----------------------+-----------------------------------------------------------+
-| -geteditsize | Prints the EditLog size.
-*----------------------+-----------------------------------------------------------+
+ Deprecated, use {{{../hadoop-hdfs/HDFSCommands.html#secondarynamenode}
+ <<<hdfs secondarynamenode>>>}} instead.
* <<<tasktracker>>>
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProviderFactory.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProviderFactory.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProviderFactory.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/key/TestKeyProviderFactory.java Thu Aug 7 20:26:52 2014
@@ -100,9 +100,9 @@ public class TestKeyProviderFactory {
static void checkSpecificProvider(Configuration conf,
String ourUrl) throws Exception {
KeyProvider provider = KeyProviderFactory.getProviders(conf).get(0);
- byte[] key1 = new byte[32];
- byte[] key2 = new byte[32];
- byte[] key3 = new byte[32];
+ byte[] key1 = new byte[16];
+ byte[] key2 = new byte[16];
+ byte[] key3 = new byte[16];
for(int i =0; i < key1.length; ++i) {
key1[i] = (byte) i;
key2[i] = (byte) (i * 2);
@@ -146,7 +146,7 @@ public class TestKeyProviderFactory {
KeyProvider.options(conf).setBitLength(8));
assertTrue("should throw", false);
} catch (IOException e) {
- assertEquals("Wrong key length. Required 8, but got 256", e.getMessage());
+ assertEquals("Wrong key length. Required 8, but got 128", e.getMessage());
}
provider.createKey("key4", new byte[]{1},
KeyProvider.options(conf).setBitLength(8));
@@ -162,7 +162,7 @@ public class TestKeyProviderFactory {
provider.rollNewVersion("key4", key1);
assertTrue("should throw", false);
} catch (IOException e) {
- assertEquals("Wrong key length. Required 8, but got 256", e.getMessage());
+ assertEquals("Wrong key length. Required 8, but got 128", e.getMessage());
}
try {
provider.rollNewVersion("no-such-key", key1);
@@ -228,7 +228,7 @@ public class TestKeyProviderFactory {
public void checkPermissionRetention(Configuration conf, String ourUrl, Path path) throws Exception {
KeyProvider provider = KeyProviderFactory.getProviders(conf).get(0);
// let's add a new key and flush and check that permissions are still set to 777
- byte[] key = new byte[32];
+ byte[] key = new byte[16];
for(int i =0; i < key.length; ++i) {
key[i] = (byte) i;
}
@@ -261,7 +261,7 @@ public class TestKeyProviderFactory {
conf.set(JavaKeyStoreProvider.KEYSTORE_PASSWORD_FILE_KEY,
"javakeystoreprovider.password");
KeyProvider provider = KeyProviderFactory.getProviders(conf).get(0);
- provider.createKey("key3", new byte[32], KeyProvider.options(conf));
+ provider.createKey("key3", new byte[16], KeyProvider.options(conf));
provider.flush();
} catch (Exception ex) {
Assert.fail("could not create keystore with password file");
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java Thu Aug 7 20:26:52 2014
@@ -414,7 +414,7 @@ public class TestHttpServer extends Http
assertEquals(HttpURLConnection.HTTP_OK, getHttpStatusCode(serverURL
+ servlet, user));
}
- assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, getHttpStatusCode(
+ assertEquals(HttpURLConnection.HTTP_FORBIDDEN, getHttpStatusCode(
serverURL + servlet, "userE"));
}
myServer.stop();
@@ -474,7 +474,7 @@ public class TestHttpServer extends Http
response = Mockito.mock(HttpServletResponse.class);
conf.setBoolean(CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION, true);
Assert.assertFalse(HttpServer2.hasAdministratorAccess(context, request, response));
- Mockito.verify(response).sendError(Mockito.eq(HttpServletResponse.SC_UNAUTHORIZED), Mockito.anyString());
+ Mockito.verify(response).sendError(Mockito.eq(HttpServletResponse.SC_FORBIDDEN), Mockito.anyString());
//authorization ON & user NOT NULL & ACLs NULL
response = Mockito.mock(HttpServletResponse.class);
@@ -487,7 +487,7 @@ public class TestHttpServer extends Http
Mockito.when(acls.isUserAllowed(Mockito.<UserGroupInformation>any())).thenReturn(false);
Mockito.when(context.getAttribute(HttpServer2.ADMINS_ACL)).thenReturn(acls);
Assert.assertFalse(HttpServer2.hasAdministratorAccess(context, request, response));
- Mockito.verify(response).sendError(Mockito.eq(HttpServletResponse.SC_UNAUTHORIZED), Mockito.anyString());
+ Mockito.verify(response).sendError(Mockito.eq(HttpServletResponse.SC_FORBIDDEN), Mockito.anyString());
//authorization ON & user NOT NULL & ACLs NOT NULL & user in in ACLs
response = Mockito.mock(HttpServletResponse.class);
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMapping.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMapping.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMapping.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMapping.java Thu Aug 7 20:26:52 2014
@@ -17,6 +17,8 @@
*/
package org.apache.hadoop.security;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
import java.io.File;
@@ -38,6 +40,9 @@ import javax.naming.directory.SearchCont
import javax.naming.directory.SearchResult;
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 org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -154,4 +159,57 @@ public class TestLdapGroupsMapping {
Assert.assertEquals("hadoop",
mapping.extractPassword(secretFile.getPath()));
}
+
+ @Test
+ public void testConfGetPassword() 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[] bindpass = {'b', 'i', 'n', 'd', 'p', 'a', 's', 's'};
+ char[] storepass = {'s', 't', 'o', 'r', 'e', 'p', 'a', 's', 's'};
+
+ // ensure that we get nulls when the key isn't there
+ assertEquals(null, provider.getCredentialEntry(
+ LdapGroupsMapping.BIND_PASSWORD_KEY));
+ assertEquals(null, provider.getCredentialEntry
+ (LdapGroupsMapping.LDAP_KEYSTORE_PASSWORD_KEY));
+
+ // create new aliases
+ try {
+ provider.createCredentialEntry(
+ LdapGroupsMapping.BIND_PASSWORD_KEY, bindpass);
+
+ provider.createCredentialEntry(
+ LdapGroupsMapping.LDAP_KEYSTORE_PASSWORD_KEY, storepass);
+ provider.flush();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ }
+ // make sure we get back the right key
+ assertArrayEquals(bindpass, provider.getCredentialEntry(
+ LdapGroupsMapping.BIND_PASSWORD_KEY).getCredential());
+ assertArrayEquals(storepass, provider.getCredentialEntry(
+ LdapGroupsMapping.LDAP_KEYSTORE_PASSWORD_KEY).getCredential());
+
+ LdapGroupsMapping mapping = new LdapGroupsMapping();
+ Assert.assertEquals("bindpass",
+ mapping.getPassword(conf, LdapGroupsMapping.BIND_PASSWORD_KEY, ""));
+ Assert.assertEquals("storepass",
+ mapping.getPassword(conf, LdapGroupsMapping.LDAP_KEYSTORE_PASSWORD_KEY,
+ ""));
+ // let's make sure that a password that doesn't exist returns an
+ // empty string as currently expected and used to trigger a call to
+ // extract password
+ Assert.assertEquals("", mapping.getPassword(conf,"invalid-alias", ""));
+ }
}
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/KeyStoreTestUtil.java Thu Aug 7 20:26:52 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/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/ssl/TestSSLFactory.java Thu Aug 7 20:26:52 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,
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-kms/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-kms/src/main/webapp/WEB-INF/web.xml?rev=1616589&r1=1616588&r2=1616589&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-kms/src/main/webapp/WEB-INF/web.xml (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-kms/src/main/webapp/WEB-INF/web.xml Thu Aug 7 20:26:52 2014
@@ -42,7 +42,7 @@
<servlet>
<servlet-name>jmx-servlet</servlet-name>
- <servlet-class>org.apache.hadoop.jmx.JMXJsonServlet</servlet-class>
+ <servlet-class>org.apache.hadoop.crypto.key.kms.server.KMSJMXServlet</servlet-class>
</servlet>
<servlet-mapping>