use of org.apache.ozone.test.GenericTestUtils.LogCapturer in project ozone by apache.
the class TestSecureOzoneManager method testSecureOmInitFailures.
/**
* Test failure cases for secure OM initialization.
*/
@Test
public void testSecureOmInitFailures() throws Exception {
PrivateKey privateKey;
PublicKey publicKey;
LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
OMStorage omStorage = new OMStorage(conf);
omStorage.setClusterId(clusterId);
omStorage.setOmId(omId);
omLogs.clearOutput();
// Case 1: When keypair as well as certificate is missing. Initial keypair
// boot-up. Get certificate will fail when SCM is not running.
SecurityConfig securityConfig = new SecurityConfig(conf);
CertificateClient client = new OMCertificateClient(securityConfig, omStorage.getOmCertSerialId());
Assert.assertEquals(CertificateClient.InitResponse.GETCERT, client.init());
privateKey = client.getPrivateKey();
publicKey = client.getPublicKey();
Assert.assertNotNull(client.getPrivateKey());
Assert.assertNotNull(client.getPublicKey());
Assert.assertNull(client.getCertificate());
// Case 2: If key pair already exist than response should be RECOVER.
client = new OMCertificateClient(securityConfig, omStorage.getOmCertSerialId());
Assert.assertEquals(CertificateClient.InitResponse.RECOVER, client.init());
Assert.assertNotNull(client.getPrivateKey());
Assert.assertNotNull(client.getPublicKey());
Assert.assertNull(client.getCertificate());
// Case 3: When public key as well as certificate is missing.
client = new OMCertificateClient(securityConfig);
FileUtils.deleteQuietly(Paths.get(securityConfig.getKeyLocation(COMPONENT).toString(), securityConfig.getPublicKeyFileName()).toFile());
Assert.assertEquals(CertificateClient.InitResponse.FAILURE, client.init());
Assert.assertNotNull(client.getPrivateKey());
Assert.assertNull(client.getPublicKey());
Assert.assertNull(client.getCertificate());
// Case 4: When private key and certificate is missing.
client = new OMCertificateClient(securityConfig);
KeyCodec keyCodec = new KeyCodec(securityConfig, COMPONENT);
keyCodec.writePublicKey(publicKey);
FileUtils.deleteQuietly(Paths.get(securityConfig.getKeyLocation(COMPONENT).toString(), securityConfig.getPrivateKeyFileName()).toFile());
Assert.assertEquals(CertificateClient.InitResponse.FAILURE, client.init());
Assert.assertNull(client.getPrivateKey());
Assert.assertNotNull(client.getPublicKey());
Assert.assertNull(client.getCertificate());
// Case 5: When only certificate is present.
FileUtils.deleteQuietly(Paths.get(securityConfig.getKeyLocation(COMPONENT).toString(), securityConfig.getPublicKeyFileName()).toFile());
CertificateCodec certCodec = new CertificateCodec(securityConfig, COMPONENT);
X509Certificate x509Certificate = KeyStoreTestUtil.generateCertificate("CN=Test", new KeyPair(publicKey, privateKey), 10, securityConfig.getSignatureAlgo());
certCodec.writeCertificate(new X509CertificateHolder(x509Certificate.getEncoded()));
client = new OMCertificateClient(securityConfig, x509Certificate.getSerialNumber().toString());
omStorage.setOmCertSerialId(x509Certificate.getSerialNumber().toString());
Assert.assertEquals(CertificateClient.InitResponse.FAILURE, client.init());
Assert.assertNull(client.getPrivateKey());
Assert.assertNull(client.getPublicKey());
Assert.assertNotNull(client.getCertificate());
// Case 6: When private key and certificate is present.
client = new OMCertificateClient(securityConfig, x509Certificate.getSerialNumber().toString());
FileUtils.deleteQuietly(Paths.get(securityConfig.getKeyLocation(COMPONENT).toString(), securityConfig.getPublicKeyFileName()).toFile());
keyCodec.writePrivateKey(privateKey);
Assert.assertEquals(CertificateClient.InitResponse.SUCCESS, client.init());
Assert.assertNotNull(client.getPrivateKey());
Assert.assertNotNull(client.getPublicKey());
Assert.assertNotNull(client.getCertificate());
// Case 7 When keypair and certificate is present.
client = new OMCertificateClient(securityConfig, x509Certificate.getSerialNumber().toString());
Assert.assertEquals(CertificateClient.InitResponse.SUCCESS, client.init());
Assert.assertNotNull(client.getPrivateKey());
Assert.assertNotNull(client.getPublicKey());
Assert.assertNotNull(client.getCertificate());
}
use of org.apache.ozone.test.GenericTestUtils.LogCapturer in project ozone by apache.
the class TestSecureOzoneCluster method testDelegationTokenRenewal.
/**
* Tests delegation token renewal.
*/
@Test
public void testDelegationTokenRenewal() throws Exception {
GenericTestUtils.setLogLevel(LoggerFactory.getLogger(Server.class.getName()), INFO);
LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
// Setup secure OM for start.
OzoneConfiguration newConf = new OzoneConfiguration(conf);
int tokenMaxLifetime = 1000;
newConf.setLong(DELEGATION_TOKEN_MAX_LIFETIME_KEY, tokenMaxLifetime);
setupOm(newConf);
OzoneManager.setTestSecureOmFlag(true);
try {
om.setCertClient(new CertificateClientTestImpl(conf));
om.start();
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
// Get first OM client which will authenticate via Kerberos
omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), RandomStringUtils.randomAscii(5));
// Since client is already connected get a delegation token
Token<OzoneTokenIdentifier> token = omClient.getDelegationToken(new Text("om"));
// Check if token is of right kind and renewer is running om instance
assertNotNull(token);
assertEquals("OzoneToken", token.getKind().toString());
assertEquals(OmUtils.getOmRpcAddress(conf), token.getService().toString());
// Renew delegation token
long expiryTime = omClient.renewDelegationToken(token);
assertTrue(expiryTime > 0);
omLogs.clearOutput();
// Test failure of delegation renewal
// 1. When token maxExpiryTime exceeds
Thread.sleep(tokenMaxLifetime);
OMException ex = LambdaTestUtils.intercept(OMException.class, "TOKEN_EXPIRED", () -> omClient.renewDelegationToken(token));
assertEquals(TOKEN_EXPIRED, ex.getResult());
omLogs.clearOutput();
// 2. When renewer doesn't match (implicitly covers when renewer is
// null or empty )
Token<OzoneTokenIdentifier> token2 = omClient.getDelegationToken(new Text("randomService"));
assertNotNull(token2);
LambdaTestUtils.intercept(OMException.class, "Delegation token renewal failed", () -> omClient.renewDelegationToken(token2));
assertTrue(omLogs.getOutput().contains(" with non-matching " + "renewer randomService"));
omLogs.clearOutput();
// 3. Test tampered token
OzoneTokenIdentifier tokenId = OzoneTokenIdentifier.readProtoBuf(token.getIdentifier());
tokenId.setRenewer(new Text("om"));
tokenId.setMaxDate(System.currentTimeMillis() * 2);
Token<OzoneTokenIdentifier> tamperedToken = new Token<>(tokenId.getBytes(), token2.getPassword(), token2.getKind(), token2.getService());
LambdaTestUtils.intercept(OMException.class, "Delegation token renewal failed", () -> omClient.renewDelegationToken(tamperedToken));
assertTrue(omLogs.getOutput().contains("can't be found in " + "cache"));
omLogs.clearOutput();
} finally {
om.stop();
om.join();
}
}
use of org.apache.ozone.test.GenericTestUtils.LogCapturer in project ozone by apache.
the class TestSecureOzoneCluster method testSecureOmInitSuccess.
/**
* Test functionality to get SCM signed certificate for OM.
*/
@Test
public void testSecureOmInitSuccess() throws Exception {
LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
omLogs.clearOutput();
initSCM();
try {
scm = HddsTestUtils.getScmSimple(conf);
scm.start();
OMStorage omStore = new OMStorage(conf);
initializeOmStorage(omStore);
OzoneManager.setTestSecureOmFlag(true);
om = OzoneManager.createOm(conf);
assertNotNull(om.getCertificateClient());
assertNotNull(om.getCertificateClient().getPublicKey());
assertNotNull(om.getCertificateClient().getPrivateKey());
assertNotNull(om.getCertificateClient().getCertificate());
assertTrue(omLogs.getOutput().contains("Init response: GETCERT"));
assertTrue(omLogs.getOutput().contains("Successfully stored " + "SCM signed certificate"));
X509Certificate certificate = om.getCertificateClient().getCertificate();
validateCertificate(certificate);
String pemEncodedCACert = scm.getSecurityProtocolServer().getCACertificate();
X509Certificate caCert = CertificateCodec.getX509Cert(pemEncodedCACert);
X509Certificate caCertStored = om.getCertificateClient().getCertificate(caCert.getSerialNumber().toString());
assertEquals(caCert, caCertStored);
} finally {
if (scm != null) {
scm.stop();
}
if (om != null) {
om.stop();
}
IOUtils.closeQuietly(om);
}
}
use of org.apache.ozone.test.GenericTestUtils.LogCapturer in project ozone by apache.
the class TestSecureOzoneCluster method testAccessControlExceptionOnClient.
@Test
public void testAccessControlExceptionOnClient() throws Exception {
initSCM();
// Create a secure SCM instance as om client will connect to it
scm = HddsTestUtils.getScmSimple(conf);
LogCapturer logs = LogCapturer.captureLogs(OzoneManager.getLogger());
GenericTestUtils.setLogLevel(OzoneManager.getLogger(), INFO);
setupOm(conf);
try {
om.setCertClient(new CertificateClientTestImpl(conf));
om.start();
} catch (Exception ex) {
// Expects timeout failure from scmClient in om but om user login via
// kerberos should succeed.
assertTrue(logs.getOutput().contains("Ozone Manager login successful"));
}
UserGroupInformation ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(testUserPrincipal, testUserKeytab.getCanonicalPath());
ugi.setAuthenticationMethod(KERBEROS);
OzoneManagerProtocolClientSideTranslatorPB secureClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), ClientId.randomId().toString());
try {
secureClient.createVolume(new OmVolumeArgs.Builder().setVolume("vol1").setOwnerName("owner1").setAdminName("admin").build());
} catch (IOException ex) {
fail("Secure client should be able to create volume.");
}
ugi = UserGroupInformation.createUserForTesting("testuser1", new String[] { "test" });
OzoneManagerProtocolClientSideTranslatorPB unsecureClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), ClientId.randomId().toString());
String exMessage = "org.apache.hadoop.security.AccessControlException: " + "Client cannot authenticate via:[TOKEN, KERBEROS]";
logs = LogCapturer.captureLogs(Client.LOG);
LambdaTestUtils.intercept(IOException.class, exMessage, () -> unsecureClient.listAllVolumes(null, null, 0));
assertEquals("There should be no retry on AccessControlException", 1, StringUtils.countMatches(logs.getOutput(), exMessage));
}
use of org.apache.ozone.test.GenericTestUtils.LogCapturer in project ozone by apache.
the class TestDelegationToken method testDelegationToken.
/**
* Performs following tests for delegation token.
* 1. Get valid delegation token
* 2. Test successful token renewal.
* 3. Client can authenticate using token.
* 4. Delegation token renewal without Kerberos auth fails.
* 5. Test success of token cancellation.
* 5. Test failure of token cancellation.
*/
@Test
public void testDelegationToken() throws Exception {
// Capture logs for assertions
LogCapturer logs = LogCapturer.captureLogs(Server.AUDITLOG);
LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
GenericTestUtils.setLogLevel(LoggerFactory.getLogger(Server.class.getName()), INFO);
// Setup secure OM for start
setupOm(conf);
// These are two very important lines: ProtobufRpcEngine uses ClientCache
// which caches clients until no more references. Cache key is the
// SocketFactory which means that we use one Client instance for
// all the Hadoop RPC.
//
// Hadoop Client caches connections with a connection pool. Even if you
// close the client here, if you have ANY Hadoop RPC clients which uses the
// same Client, connections can be reused.
//
// Here we closed all the OTHER Hadoop RPC clients to have only the clients
// from this unit test.
//
// With this approach all the following client.close() calls trigger a
// Client.close (if there is no other open Hadoop RPC client) which triggers
// connection close for all the available connection.
//
// The following test tests the authorization of the new client calls, it
// requires a real connection close and connection open as the authorization
// is part the initial handhsake of Hadoop RPC.
om.getScmClient().getBlockClient().close();
om.getScmClient().getContainerClient().close();
try {
// Start OM
om.setCertClient(new CertificateClientTestImpl(conf));
om.start();
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
String username = ugi.getUserName();
// Get first OM client which will authenticate via Kerberos
omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), RandomStringUtils.randomAscii(5));
// Assert if auth was successful via Kerberos
assertFalse(logs.getOutput().contains("Auth successful for " + username + " (auth:KERBEROS)"));
// Case 1: Test successful delegation token.
Token<OzoneTokenIdentifier> token = omClient.getDelegationToken(new Text("om"));
// Case 2: Test successful token renewal.
long renewalTime = omClient.renewDelegationToken(token);
assertTrue(renewalTime > 0);
// Check if token is of right kind and renewer is running om instance
assertNotNull(token);
assertEquals("OzoneToken", token.getKind().toString());
assertEquals(OmUtils.getOmRpcAddress(conf), token.getService().toString());
omClient.close();
// Create a remote ugi and set its authentication method to Token
UserGroupInformation testUser = UserGroupInformation.createRemoteUser(TEST_USER);
testUser.addToken(token);
testUser.setAuthenticationMethod(AuthMethod.TOKEN);
UserGroupInformation.setLoginUser(testUser);
// Get Om client, this time authentication should happen via Token
testUser.doAs((PrivilegedExceptionAction<Void>) () -> {
omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, testUser, null), RandomStringUtils.randomAscii(5));
return null;
});
// Case 3: Test Client can authenticate using token.
assertFalse(logs.getOutput().contains("Auth successful for " + username + " (auth:TOKEN)"));
OzoneTestUtils.expectOmException(VOLUME_NOT_FOUND, () -> omClient.deleteVolume("vol1"));
assertTrue("Log file doesn't contain successful auth for user " + username, logs.getOutput().contains("Auth successful for " + username + " (auth:TOKEN)"));
// Case 4: Test failure of token renewal.
// Call to renewDelegationToken will fail but it will confirm that
// initial connection via DT succeeded
omLogs.clearOutput();
OMException ex = LambdaTestUtils.intercept(OMException.class, "INVALID_AUTH_METHOD", () -> omClient.renewDelegationToken(token));
assertEquals(INVALID_AUTH_METHOD, ex.getResult());
assertTrue(logs.getOutput().contains("Auth successful for " + username + " (auth:TOKEN)"));
omLogs.clearOutput();
// testUser.setAuthenticationMethod(AuthMethod.KERBEROS);
omClient.close();
UserGroupInformation.setLoginUser(ugi);
omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, ugi, null), RandomStringUtils.randomAscii(5));
// Case 5: Test success of token cancellation.
omClient.cancelDelegationToken(token);
omClient.close();
// Wait for client to timeout
Thread.sleep(CLIENT_TIMEOUT);
assertFalse(logs.getOutput().contains("Auth failed for"));
// Case 6: Test failure of token cancellation.
// Get Om client, this time authentication using Token will fail as
// token is not in cache anymore.
omClient = new OzoneManagerProtocolClientSideTranslatorPB(OmTransportFactory.create(conf, testUser, null), RandomStringUtils.randomAscii(5));
ex = LambdaTestUtils.intercept(OMException.class, "Cancel delegation token failed", () -> omClient.cancelDelegationToken(token));
assertEquals(TOKEN_ERROR_OTHER, ex.getResult());
assertTrue(logs.getOutput().contains("Auth failed for"));
} finally {
om.stop();
om.join();
}
}
Aggregations