HADOOP-12962. KMS key names are incorrectly encoded when creating key. Contributed by Xiao Chen.

This commit is contained in:
Andrew Wang 2016-03-25 15:28:53 -07:00
parent e8fc81f9c8
commit d4df7849a5
2 changed files with 49 additions and 7 deletions

View File

@ -41,10 +41,10 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.LinkedList;
@ -89,9 +89,9 @@ public class KMS {
keyVersion.getVersionName(), null);
}
private static URI getKeyURI(String name) throws URISyntaxException {
return new URI(KMSRESTConstants.SERVICE_VERSION + "/" +
KMSRESTConstants.KEY_RESOURCE + "/" + name);
private static URI getKeyURI(String domain, String keyName) {
return UriBuilder.fromPath("{a}/{b}/{c}")
.build(domain, KMSRESTConstants.KEY_RESOURCE, keyName);
}
@POST
@ -151,9 +151,9 @@ public class KMS {
String requestURL = KMSMDCFilter.getURL();
int idx = requestURL.lastIndexOf(KMSRESTConstants.KEYS_RESOURCE);
requestURL = requestURL.substring(0, idx);
String keyURL = requestURL + KMSRESTConstants.KEY_RESOURCE + "/" + name;
return Response.created(getKeyURI(name)).type(MediaType.APPLICATION_JSON).
header("Location", keyURL).entity(json).build();
return Response.created(getKeyURI(KMSRESTConstants.SERVICE_VERSION, name))
.type(MediaType.APPLICATION_JSON)
.header("Location", getKeyURI(requestURL, name)).entity(json).build();
}
@DELETE

View File

@ -39,11 +39,15 @@ import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.AuthorizationException;
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.test.GenericTestUtils;
import org.apache.log4j.Level;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.login.AppConfigurationEntry;
@ -69,12 +73,14 @@ import java.util.UUID;
import java.util.concurrent.Callable;
public class TestKMS {
private static final Logger LOG = LoggerFactory.getLogger(TestKMS.class);
@Before
public void cleanUp() {
// resetting kerberos security
Configuration conf = new Configuration();
UserGroupInformation.setConfiguration(conf);
GenericTestUtils.setLogLevel(LOG, Level.INFO);
}
public static File getTestDir() throws Exception {
@ -380,6 +386,42 @@ public class TestKMS {
testStartStop(true, true);
}
@Test(timeout = 30000)
public void testSpecialKeyNames() throws Exception {
final String specialKey = "key %^[\n{]}|\"<>\\";
Configuration conf = new Configuration();
conf.set("hadoop.security.authentication", "kerberos");
UserGroupInformation.setConfiguration(conf);
File confDir = getTestDir();
conf = createBaseKMSConf(confDir);
conf.set(KeyAuthorizationKeyProvider.KEY_ACL + specialKey + ".ALL", "*");
writeConf(confDir, conf);
runServer(null, null, confDir, new KMSCallable<Void>() {
@Override
public Void call() throws Exception {
Configuration conf = new Configuration();
URI uri = createKMSUri(getKMSUrl());
KeyProvider kp = createProvider(uri, conf);
Assert.assertTrue(kp.getKeys().isEmpty());
Assert.assertEquals(0, kp.getKeysMetadata().length);
KeyProvider.Options options = new KeyProvider.Options(conf);
options.setCipher("AES/CTR/NoPadding");
options.setBitLength(128);
options.setDescription("l1");
LOG.info("Creating key with name '{}'", specialKey);
KeyProvider.KeyVersion kv0 = kp.createKey(specialKey, options);
Assert.assertNotNull(kv0);
Assert.assertEquals(specialKey, kv0.getName());
Assert.assertNotNull(kv0.getVersionName());
Assert.assertNotNull(kv0.getMaterial());
return null;
}
});
}
@Test
public void testKMSProvider() throws Exception {
Configuration conf = new Configuration();