This is an automated email from the ASF dual-hosted git repository.
zhangduo pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2 by this push:
new c2dff398d31 HBASE-27279 Make SslHandler work with
SaslWrapHandler/SaslUnwrapHandler (#4705)
c2dff398d31 is described below
commit c2dff398d316dea23c67a467f761ec92204e92cc
Author: Duo Zhang <[email protected]>
AuthorDate: Tue Aug 16 21:05:42 2022 +0800
HBASE-27279 Make SslHandler work with SaslWrapHandler/SaslUnwrapHandler
(#4705)
Signed-off-by: Bryan Beaudreault <[email protected]>
Reviewed-by: Andor Molnár <[email protected]>
(cherry picked from commit 2b9d36869ffe765256d4a7b6a74b95a8200678df)
Conflicts:
hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSecureIPC.java
hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestTlsWithKerberos.java
---
.../hadoop/hbase/security/HBaseKerberosUtils.java | 9 +
.../hadoop/hbase/ipc/NettyRpcConnection.java | 3 +-
.../hbase/security/NettyHBaseSaslRpcClient.java | 8 +-
.../security/NettyHBaseSaslRpcClientHandler.java | 4 +-
.../hbase/ipc/NettyHBaseSaslRpcServerHandler.java | 6 +-
.../apache/hadoop/hbase/ipc/NettyRpcServer.java | 5 +-
.../hbase/ipc/NettyRpcServerPreambleHandler.java | 2 +-
.../hadoop/hbase/ipc/NettyServerRpcConnection.java | 10 +-
...stSecureIPC.java => AbstractTestSecureIPC.java} | 101 ++----
...xt.java => AbstractTestTlsRejectPlainText.java} | 52 ++-
.../security/TestNettyTlsIPCRejectPlainText.java | 121 +------
...IPCRejectPlainText.java => TestSaslTlsIPC.java} | 104 +++---
.../security/TestSaslTlsIPCRejectPlainText.java | 87 +++++
.../hadoop/hbase/security/TestSecureIPC.java | 372 +--------------------
.../hadoop/hbase/security/TestTlsWithKerberos.java | 219 ------------
15 files changed, 213 insertions(+), 890 deletions(-)
diff --git
a/hbase-asyncfs/src/test/java/org/apache/hadoop/hbase/security/HBaseKerberosUtils.java
b/hbase-asyncfs/src/test/java/org/apache/hadoop/hbase/security/HBaseKerberosUtils.java
index af5154b9460..48656329df2 100644
---
a/hbase-asyncfs/src/test/java/org/apache/hadoop/hbase/security/HBaseKerberosUtils.java
+++
b/hbase-asyncfs/src/test/java/org/apache/hadoop/hbase/security/HBaseKerberosUtils.java
@@ -188,4 +188,13 @@ public final class HBaseKerberosUtils {
UserGroupInformation.loginUserFromKeytabAndReturnUGI(principal,
keyTabFileLocation);
return ugi;
}
+
+ public static UserGroupInformation loginKerberosPrincipal(String krbKeytab,
String krbPrincipal)
+ throws Exception {
+ Configuration conf = new Configuration();
+ conf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION,
"kerberos");
+ UserGroupInformation.setConfiguration(conf);
+ UserGroupInformation.loginUserFromKeytab(krbPrincipal, krbKeytab);
+ return UserGroupInformation.getLoginUser();
+ }
}
diff --git
a/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcConnection.java
b/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcConnection.java
index 31e38fd2c05..1938e2d7bf9 100644
---
a/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcConnection.java
+++
b/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcConnection.java
@@ -222,7 +222,8 @@ class NettyRpcConnection extends RpcConnection {
return;
}
ch.pipeline().addBefore(BufferCallBeforeInitHandler.NAME, null, new
SaslChallengeDecoder())
- .addBefore(BufferCallBeforeInitHandler.NAME, null, saslHandler);
+ .addBefore(BufferCallBeforeInitHandler.NAME,
NettyHBaseSaslRpcClientHandler.HANDLER_NAME,
+ saslHandler);
NettyFutureUtils.addListener(saslPromise, new FutureListener<Boolean>() {
@Override
diff --git
a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClient.java
b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClient.java
index ede12258ad1..fe5481a10b2 100644
---
a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClient.java
+++
b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClient.java
@@ -45,16 +45,16 @@ public class NettyHBaseSaslRpcClient extends
AbstractHBaseSaslRpcClient {
super(conf, provider, token, serverAddr, securityInfo, fallbackAllowed,
rpcProtection);
}
- public void setupSaslHandler(ChannelPipeline p) {
+ public void setupSaslHandler(ChannelPipeline p, String addAfter) {
String qop = (String) saslClient.getNegotiatedProperty(Sasl.QOP);
LOG.trace("SASL client context established. Negotiated QoP {}", qop);
if (qop == null || "auth".equalsIgnoreCase(qop)) {
return;
}
// add wrap and unwrap handlers to pipeline.
- p.addFirst(new SaslWrapHandler(saslClient::wrap),
- new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4),
- new SaslUnwrapHandler(saslClient::unwrap));
+ p.addAfter(addAfter, null, new SaslUnwrapHandler(saslClient::unwrap))
+ .addAfter(addAfter, null, new
LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4))
+ .addAfter(addAfter, null, new SaslWrapHandler(saslClient::wrap));
}
public String getSaslQOP() {
diff --git
a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.java
b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.java
index 20b299fba67..32856da18b5 100644
---
a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.java
+++
b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.java
@@ -47,6 +47,8 @@ public class NettyHBaseSaslRpcClientHandler extends
SimpleChannelInboundHandler<
private static final Logger LOG =
LoggerFactory.getLogger(NettyHBaseSaslRpcClientHandler.class);
+ public static final String HANDLER_NAME = "SaslRpcClientHandler";
+
private final Promise<Boolean> saslPromise;
private final UserGroupInformation ugi;
@@ -86,7 +88,7 @@ public class NettyHBaseSaslRpcClientHandler extends
SimpleChannelInboundHandler<
}
ChannelPipeline p = ctx.pipeline();
- saslRpcClient.setupSaslHandler(p);
+ saslRpcClient.setupSaslHandler(p, HANDLER_NAME);
p.remove(SaslChallengeDecoder.class);
p.remove(this);
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyHBaseSaslRpcServerHandler.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyHBaseSaslRpcServerHandler.java
index e36e0b44c74..387318888a0 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyHBaseSaslRpcServerHandler.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyHBaseSaslRpcServerHandler.java
@@ -89,11 +89,11 @@ class NettyHBaseSaslRpcServerHandler extends
SimpleChannelInboundHandler<ByteBuf
boolean useWrap = qop != null && !"auth".equalsIgnoreCase(qop);
ChannelPipeline p = ctx.pipeline();
if (useWrap) {
- p.addFirst(new SaslWrapHandler(saslServer::wrap));
- p.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0,
4),
+ p.addBefore(DECODER_NAME, null, new
SaslWrapHandler(saslServer::wrap)).addLast(
+ new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4),
new SaslUnwrapHandler(saslServer::unwrap));
}
- conn.setupDecoder();
+ conn.setupHandler();
p.remove(this);
p.remove(DECODER_NAME);
}
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcServer.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcServer.java
index 1eb96c4890c..0a298833865 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcServer.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcServer.java
@@ -124,9 +124,8 @@ public class NettyRpcServer extends RpcServer {
if (conf.getBoolean(HBASE_SERVER_NETTY_TLS_ENABLED, false)) {
initSSL(pipeline,
conf.getBoolean(HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT, true));
}
- pipeline.addLast(NettyRpcServerPreambleHandler.DECODER_NAME,
preambleDecoder);
- pipeline.addLast(createNettyRpcServerPreambleHandler(),
- new NettyRpcServerResponseEncoder(metrics));
+ pipeline.addLast(NettyRpcServerPreambleHandler.DECODER_NAME,
preambleDecoder)
+ .addLast(createNettyRpcServerPreambleHandler());
}
});
try {
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcServerPreambleHandler.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcServerPreambleHandler.java
index 15a95bc9b09..ca25dea17fe 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcServerPreambleHandler.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcServerPreambleHandler.java
@@ -61,7 +61,7 @@ class NettyRpcServerPreambleHandler extends
SimpleChannelInboundHandler<ByteBuf>
p.addLast(NettyHBaseSaslRpcServerHandler.DECODER_NAME, decoder);
p.addLast(new NettyHBaseSaslRpcServerHandler(rpcServer, conn));
} else {
- conn.setupDecoder();
+ conn.setupHandler();
}
// add first and then remove, so the single decode decoder will pass the
remaining bytes to the
// handler above.
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyServerRpcConnection.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyServerRpcConnection.java
index 60db16d77e0..54c105802c5 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyServerRpcConnection.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyServerRpcConnection.java
@@ -33,7 +33,6 @@ import
org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescrip
import org.apache.hbase.thirdparty.com.google.protobuf.Message;
import org.apache.hbase.thirdparty.io.netty.buffer.ByteBuf;
import org.apache.hbase.thirdparty.io.netty.channel.Channel;
-import org.apache.hbase.thirdparty.io.netty.channel.ChannelPipeline;
import
org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader;
@@ -70,10 +69,11 @@ class NettyServerRpcConnection extends ServerRpcConnection {
this.remotePort = inetSocketAddress.getPort();
}
- void setupDecoder() {
- ChannelPipeline p = channel.pipeline();
- p.addLast("frameDecoder", new
NettyRpcFrameDecoder(rpcServer.maxRequestSize, this));
- p.addLast("decoder", new NettyRpcServerRequestDecoder(rpcServer.metrics,
this));
+ void setupHandler() {
+ channel.pipeline()
+ .addLast("frameDecoder", new
NettyRpcFrameDecoder(rpcServer.maxRequestSize, this))
+ .addLast("decoder", new NettyRpcServerRequestDecoder(rpcServer.metrics,
this))
+ .addLast("encoder", new
NettyRpcServerResponseEncoder(rpcServer.metrics));
}
void process(ByteBuf buf) throws IOException, InterruptedException {
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSecureIPC.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/AbstractTestSecureIPC.java
similarity index 80%
copy from
hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSecureIPC.java
copy to
hbase-server/src/test/java/org/apache/hadoop/hbase/security/AbstractTestSecureIPC.java
index a96eec6a47e..a5bca1a0ccf 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSecureIPC.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/AbstractTestSecureIPC.java
@@ -21,6 +21,7 @@ import static
org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.SERVICE;
import static
org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.newBlockingStub;
import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.getKeytabFileForTesting;
import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.getPrincipalForTesting;
+import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.loginKerberosPrincipal;
import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.setSecuredConfiguration;
import static
org.apache.hadoop.hbase.security.provider.SaslClientAuthenticationProviders.SELECTOR_KEY;
import static org.junit.Assert.assertEquals;
@@ -35,51 +36,31 @@ import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import java.util.Map;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.CommonConfigurationKeys;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
-import org.apache.hadoop.hbase.ipc.BlockingRpcClient;
import org.apache.hadoop.hbase.ipc.FifoRpcScheduler;
-import org.apache.hadoop.hbase.ipc.NettyRpcClient;
-import org.apache.hadoop.hbase.ipc.NettyRpcServer;
import org.apache.hadoop.hbase.ipc.RpcClient;
import org.apache.hadoop.hbase.ipc.RpcClientFactory;
import org.apache.hadoop.hbase.ipc.RpcServer;
import org.apache.hadoop.hbase.ipc.RpcServerFactory;
import org.apache.hadoop.hbase.ipc.RpcServerInterface;
-import org.apache.hadoop.hbase.ipc.SimpleRpcServer;
import
org.apache.hadoop.hbase.security.provider.AuthenticationProviderSelector;
import org.apache.hadoop.hbase.security.provider.BuiltInProviderSelector;
import org.apache.hadoop.hbase.security.provider.SaslAuthMethod;
import
org.apache.hadoop.hbase.security.provider.SaslClientAuthenticationProvider;
-import org.apache.hadoop.hbase.testclassification.LargeTests;
-import org.apache.hadoop.hbase.testclassification.SecurityTests;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.minikdc.MiniKdc;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.TokenIdentifier;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
import org.mockito.Mockito;
import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
@@ -89,52 +70,24 @@ import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestProtos;
import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface;
import
org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.UserInformation;
-@RunWith(Parameterized.class)
-@Category({ SecurityTests.class, LargeTests.class })
-public class TestSecureIPC {
+public class AbstractTestSecureIPC {
- @ClassRule
- public static final HBaseClassTestRule CLASS_RULE =
- HBaseClassTestRule.forClass(TestSecureIPC.class);
+ protected static final HBaseTestingUtility TEST_UTIL = new
HBaseTestingUtility();
- private static final HBaseTestingUtility TEST_UTIL = new
HBaseTestingUtility();
-
- private static final File KEYTAB_FILE =
+ protected static final File KEYTAB_FILE =
new File(TEST_UTIL.getDataTestDir("keytab").toUri().getPath());
- private static MiniKdc KDC;
- private static String HOST = "localhost";
- private static String PRINCIPAL;
-
- private String krbKeytab;
- private String krbPrincipal;
- private UserGroupInformation ugi;
- private Configuration clientConf;
- private Configuration serverConf;
-
- @Parameters(name = "{index}: rpcClientImpl={0}, rpcServerImpl={1}")
- public static Collection<Object[]> parameters() {
- List<Object[]> params = new ArrayList<>();
- List<String> rpcClientImpls =
- Arrays.asList(BlockingRpcClient.class.getName(),
NettyRpcClient.class.getName());
- List<String> rpcServerImpls =
- Arrays.asList(SimpleRpcServer.class.getName(),
NettyRpcServer.class.getName());
- for (String rpcClientImpl : rpcClientImpls) {
- for (String rpcServerImpl : rpcServerImpls) {
- params.add(new Object[] { rpcClientImpl, rpcServerImpl });
- }
- }
- return params;
- }
+ protected static MiniKdc KDC;
+ protected static String HOST = "localhost";
+ protected static String PRINCIPAL;
- @Parameter(0)
- public String rpcClientImpl;
+ protected String krbKeytab;
+ protected String krbPrincipal;
+ protected UserGroupInformation ugi;
+ protected Configuration clientConf;
+ protected Configuration serverConf;
- @Parameter(1)
- public String rpcServerImpl;
-
- @BeforeClass
- public static void setUp() throws Exception {
+ protected static void initKDCAndConf() throws Exception {
KDC = TEST_UTIL.setupMiniKdc(KEYTAB_FILE);
PRINCIPAL = "hbase/" + HOST;
KDC.createPrincipal(KEYTAB_FILE, PRINCIPAL);
@@ -144,25 +97,20 @@ public class TestSecureIPC {
TEST_UTIL.getConfiguration().setInt("hbase.security.relogin.maxretries",
1);
}
- @AfterClass
- public static void tearDown() throws IOException {
+ protected static void stopKDC() throws InterruptedException {
if (KDC != null) {
KDC.stop();
}
- TEST_UTIL.cleanupTestDir();
}
- @Before
- public void setUpTest() throws Exception {
+ protected final void setUpPrincipalAndConf() throws Exception {
krbKeytab = getKeytabFileForTesting();
krbPrincipal = getPrincipalForTesting();
ugi = loginKerberosPrincipal(krbKeytab, krbPrincipal);
clientConf = new Configuration(TEST_UTIL.getConfiguration());
setSecuredConfiguration(clientConf);
- clientConf.set(RpcClientFactory.CUSTOM_RPC_CLIENT_IMPL_CONF_KEY,
rpcClientImpl);
serverConf = new Configuration(TEST_UTIL.getConfiguration());
setSecuredConfiguration(serverConf);
- serverConf.set(RpcServerFactory.CUSTOM_RPC_SERVER_IMPL_CONF_KEY,
rpcServerImpl);
}
@Test
@@ -178,7 +126,7 @@ public class TestSecureIPC {
}
@Test
- public void testRpcCallWithEnabledKerberosSaslAuth_CanonicalHostname()
throws Exception {
+ public void testRpcCallWithEnabledKerberosSaslAuthCanonicalHostname() throws
Exception {
UserGroupInformation ugi2 = UserGroupInformation.getCurrentUser();
// check that the login user is okay:
@@ -195,7 +143,7 @@ public class TestSecureIPC {
}
@Test
- public void testRpcCallWithEnabledKerberosSaslAuth_NoCanonicalHostname()
throws Exception {
+ public void testRpcCallWithEnabledKerberosSaslAuthNoCanonicalHostname()
throws Exception {
UserGroupInformation ugi2 = UserGroupInformation.getCurrentUser();
// check that the login user is okay:
@@ -310,7 +258,7 @@ public class TestSecureIPC {
}
/**
- * Test various combinations of Server and Client qops. n
+ * Test various combinations of Server and Client qops.
*/
@Test
public void testSaslWithCommonQop() throws Exception {
@@ -338,7 +286,7 @@ public class TestSecureIPC {
}
/**
- * Test sasl encryption with Crypto AES. n
+ * Test sasl encryption with Crypto AES.
*/
@Test
public void testSaslWithCryptoAES() throws Exception {
@@ -366,20 +314,11 @@ public class TestSecureIPC {
}
}
- void setCryptoAES(String clientCryptoAES, String serverCryptoAES) {
+ private void setCryptoAES(String clientCryptoAES, String serverCryptoAES) {
clientConf.set("hbase.rpc.crypto.encryption.aes.enabled", clientCryptoAES);
serverConf.set("hbase.rpc.crypto.encryption.aes.enabled", serverCryptoAES);
}
- private UserGroupInformation loginKerberosPrincipal(String krbKeytab, String
krbPrincipal)
- throws Exception {
- Configuration cnf = new Configuration();
- cnf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION,
"kerberos");
- UserGroupInformation.setConfiguration(cnf);
- UserGroupInformation.loginUserFromKeytab(krbPrincipal, krbKeytab);
- return UserGroupInformation.getLoginUser();
- }
-
/**
* Sets up a RPC Server and a Client. Does a RPC checks the result. If an
exception is thrown from
* the stub, this function will throw root cause of that exception.
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/AbstractTestTlsRejectPlainText.java
similarity index 79%
copy from
hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
copy to
hbase-server/src/test/java/org/apache/hadoop/hbase/security/AbstractTestTlsRejectPlainText.java
index d8b51610a31..c6ecccaea34 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/AbstractTestTlsRejectPlainText.java
@@ -18,7 +18,6 @@
package org.apache.hadoop.hbase.security;
import static org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.SERVICE;
-import static
org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.newBlockingStub;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertThrows;
@@ -31,7 +30,6 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;
import org.apache.hadoop.hbase.io.crypto.tls.KeyStoreFileType;
@@ -43,18 +41,13 @@ import org.apache.hadoop.hbase.ipc.FifoRpcScheduler;
import org.apache.hadoop.hbase.ipc.NettyRpcClient;
import org.apache.hadoop.hbase.ipc.NettyRpcServer;
import org.apache.hadoop.hbase.ipc.RpcClient;
+import org.apache.hadoop.hbase.ipc.RpcClientFactory;
import org.apache.hadoop.hbase.ipc.RpcServer;
-import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.apache.hadoop.hbase.testclassification.RPCTests;
+import org.apache.hadoop.hbase.ipc.RpcServerFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.After;
-import org.junit.AfterClass;
import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
@@ -64,19 +57,13 @@ import
org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestProtos.EchoRequestProto;
import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface;
-@RunWith(Parameterized.class)
-@Category({ RPCTests.class, MediumTests.class })
-public class TestNettyTlsIPCRejectPlainText {
+public abstract class AbstractTestTlsRejectPlainText {
- @ClassRule
- public static final HBaseClassTestRule CLASS_RULE =
- HBaseClassTestRule.forClass(TestNettyTlsIPCRejectPlainText.class);
+ protected static HBaseCommonTestingUtility UTIL;
- private static final HBaseCommonTestingUtility UTIL = new
HBaseCommonTestingUtility();
+ protected static File DIR;
- private static File DIR;
-
- private static X509TestContextProvider PROVIDER;
+ protected static X509TestContextProvider PROVIDER;
@Parameterized.Parameter(0)
public X509KeyType caKeyType;
@@ -89,9 +76,9 @@ public class TestNettyTlsIPCRejectPlainText {
private X509TestContext x509TestContext;
- private RpcServer rpcServer;
+ protected RpcServer rpcServer;
- private RpcClient rpcClient;
+ protected RpcClient rpcClient;
@Parameterized.Parameters(name = "{index}: caKeyType={0}, certKeyType={1},
keyPassword={2}")
public static List<Object[]> data() {
@@ -106,27 +93,30 @@ public class TestNettyTlsIPCRejectPlainText {
return params;
}
- @BeforeClass
- public static void setUpBeforeClass() throws IOException {
+ protected static void initialize() throws IOException {
Security.addProvider(new BouncyCastleProvider());
- DIR = new
File(UTIL.getDataTestDir(TestNettyTlsIPC.class.getSimpleName()).toString())
- .getCanonicalFile();
+ DIR =
+ new
File(UTIL.getDataTestDir(AbstractTestTlsRejectPlainText.class.getSimpleName()).toString())
+ .getCanonicalFile();
FileUtils.forceMkdir(DIR);
Configuration conf = UTIL.getConfiguration();
+ conf.setClass(RpcClientFactory.CUSTOM_RPC_CLIENT_IMPL_CONF_KEY,
NettyRpcClient.class,
+ RpcClient.class);
+ conf.setClass(RpcServerFactory.CUSTOM_RPC_SERVER_IMPL_CONF_KEY,
NettyRpcServer.class,
+ RpcServer.class);
conf.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_ENABLED, true);
conf.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT, false);
conf.setBoolean(X509Util.HBASE_CLIENT_NETTY_TLS_ENABLED, false);
PROVIDER = new X509TestContextProvider(conf, DIR);
}
- @AfterClass
- public static void tearDownAfterClass() {
+ protected static void cleanUp() {
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
UTIL.cleanupTestDir();
}
@Before
- public void setUp() throws IOException {
+ public void setUp() throws Exception {
x509TestContext = PROVIDER.get(caKeyType, certKeyType, keyPassword);
x509TestContext.setConfigurations(KeyStoreFileType.JKS,
KeyStoreFileType.JKS);
Configuration conf = UTIL.getConfiguration();
@@ -153,9 +143,11 @@ public class TestNettyTlsIPCRejectPlainText {
Security.setProperty("com.sun.security.enableCRLDP",
Boolean.FALSE.toString());
}
+ protected abstract BlockingInterface createStub() throws Exception;
+
@Test
- public void testReject() throws IOException, ServiceException {
- BlockingInterface stub = newBlockingStub(rpcClient,
rpcServer.getListenerAddress());
+ public void testReject() throws Exception {
+ BlockingInterface stub = createStub();
ServiceException se = assertThrows(ServiceException.class,
() -> stub.echo(null, EchoRequestProto.newBuilder().setMessage("hello
world").build()));
assertThat(se.getCause(), instanceOf(ConnectionClosedException.class));
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
index d8b51610a31..fcb14aa85e8 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
@@ -17,147 +17,42 @@
*/
package org.apache.hadoop.hbase.security;
-import static org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.SERVICE;
-import static
org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.newBlockingStub;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.junit.Assert.assertThrows;
-
-import java.io.File;
import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.security.Security;
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.io.FileUtils;
-import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
-import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;
-import org.apache.hadoop.hbase.io.crypto.tls.KeyStoreFileType;
-import org.apache.hadoop.hbase.io.crypto.tls.X509KeyType;
-import org.apache.hadoop.hbase.io.crypto.tls.X509TestContext;
-import org.apache.hadoop.hbase.io.crypto.tls.X509TestContextProvider;
-import org.apache.hadoop.hbase.io.crypto.tls.X509Util;
-import org.apache.hadoop.hbase.ipc.FifoRpcScheduler;
-import org.apache.hadoop.hbase.ipc.NettyRpcClient;
-import org.apache.hadoop.hbase.ipc.NettyRpcServer;
-import org.apache.hadoop.hbase.ipc.RpcClient;
-import org.apache.hadoop.hbase.ipc.RpcServer;
+import org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RPCTests;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.junit.After;
import org.junit.AfterClass;
-import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
-import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
-import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
-import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
-import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
-
-import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestProtos.EchoRequestProto;
import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface;
@RunWith(Parameterized.class)
@Category({ RPCTests.class, MediumTests.class })
-public class TestNettyTlsIPCRejectPlainText {
+public class TestNettyTlsIPCRejectPlainText extends
AbstractTestTlsRejectPlainText {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestNettyTlsIPCRejectPlainText.class);
- private static final HBaseCommonTestingUtility UTIL = new
HBaseCommonTestingUtility();
-
- private static File DIR;
-
- private static X509TestContextProvider PROVIDER;
-
- @Parameterized.Parameter(0)
- public X509KeyType caKeyType;
-
- @Parameterized.Parameter(1)
- public X509KeyType certKeyType;
-
- @Parameterized.Parameter(2)
- public String keyPassword;
-
- private X509TestContext x509TestContext;
-
- private RpcServer rpcServer;
-
- private RpcClient rpcClient;
-
- @Parameterized.Parameters(name = "{index}: caKeyType={0}, certKeyType={1},
keyPassword={2}")
- public static List<Object[]> data() {
- List<Object[]> params = new ArrayList<>();
- for (X509KeyType caKeyType : X509KeyType.values()) {
- for (X509KeyType certKeyType : X509KeyType.values()) {
- for (String keyPassword : new String[] { "", "pa$$w0rd" }) {
- params.add(new Object[] { caKeyType, certKeyType, keyPassword });
- }
- }
- }
- return params;
- }
-
@BeforeClass
public static void setUpBeforeClass() throws IOException {
- Security.addProvider(new BouncyCastleProvider());
- DIR = new
File(UTIL.getDataTestDir(TestNettyTlsIPC.class.getSimpleName()).toString())
- .getCanonicalFile();
- FileUtils.forceMkdir(DIR);
- Configuration conf = UTIL.getConfiguration();
- conf.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_ENABLED, true);
- conf.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT, false);
- conf.setBoolean(X509Util.HBASE_CLIENT_NETTY_TLS_ENABLED, false);
- PROVIDER = new X509TestContextProvider(conf, DIR);
+ UTIL = new HBaseCommonTestingUtility();
+ initialize();
}
@AfterClass
public static void tearDownAfterClass() {
- Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
- UTIL.cleanupTestDir();
- }
-
- @Before
- public void setUp() throws IOException {
- x509TestContext = PROVIDER.get(caKeyType, certKeyType, keyPassword);
- x509TestContext.setConfigurations(KeyStoreFileType.JKS,
KeyStoreFileType.JKS);
- Configuration conf = UTIL.getConfiguration();
- rpcServer = new NettyRpcServer(null, "testRpcServer",
- Lists.newArrayList(new RpcServer.BlockingServiceAndInterface(SERVICE,
null)),
- new InetSocketAddress("localhost", 0), conf, new FifoRpcScheduler(conf,
1), true);
- rpcServer.start();
- rpcClient = new NettyRpcClient(conf);
- }
-
- @After
- public void tearDown() throws IOException {
- if (rpcServer != null) {
- rpcServer.stop();
- }
- Closeables.close(rpcClient, true);
- x509TestContext.clearConfigurations();
- x509TestContext.getConf().unset(X509Util.TLS_CONFIG_OCSP);
- x509TestContext.getConf().unset(X509Util.TLS_CONFIG_CLR);
- x509TestContext.getConf().unset(X509Util.TLS_CONFIG_PROTOCOL);
- System.clearProperty("com.sun.net.ssl.checkRevocation");
- System.clearProperty("com.sun.security.enableCRLDP");
- Security.setProperty("ocsp.enable", Boolean.FALSE.toString());
- Security.setProperty("com.sun.security.enableCRLDP",
Boolean.FALSE.toString());
+ cleanUp();
}
- @Test
- public void testReject() throws IOException, ServiceException {
- BlockingInterface stub = newBlockingStub(rpcClient,
rpcServer.getListenerAddress());
- ServiceException se = assertThrows(ServiceException.class,
- () -> stub.echo(null, EchoRequestProto.newBuilder().setMessage("hello
world").build()));
- assertThat(se.getCause(), instanceOf(ConnectionClosedException.class));
+ @Override
+ protected BlockingInterface createStub() throws Exception {
+ return TestProtobufRpcServiceImpl.newBlockingStub(rpcClient,
rpcServer.getListenerAddress());
}
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSaslTlsIPC.java
similarity index 55%
copy from
hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
copy to
hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSaslTlsIPC.java
index d8b51610a31..3d48af5074c 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestNettyTlsIPCRejectPlainText.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSaslTlsIPC.java
@@ -17,64 +17,43 @@
*/
package org.apache.hadoop.hbase.security;
-import static org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.SERVICE;
-import static
org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.newBlockingStub;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.junit.Assert.assertThrows;
-
import java.io.File;
-import java.io.IOException;
-import java.net.InetSocketAddress;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseClassTestRule;
-import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
-import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;
import org.apache.hadoop.hbase.io.crypto.tls.KeyStoreFileType;
import org.apache.hadoop.hbase.io.crypto.tls.X509KeyType;
import org.apache.hadoop.hbase.io.crypto.tls.X509TestContext;
import org.apache.hadoop.hbase.io.crypto.tls.X509TestContextProvider;
import org.apache.hadoop.hbase.io.crypto.tls.X509Util;
-import org.apache.hadoop.hbase.ipc.FifoRpcScheduler;
import org.apache.hadoop.hbase.ipc.NettyRpcClient;
import org.apache.hadoop.hbase.ipc.NettyRpcServer;
import org.apache.hadoop.hbase.ipc.RpcClient;
+import org.apache.hadoop.hbase.ipc.RpcClientFactory;
import org.apache.hadoop.hbase.ipc.RpcServer;
-import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.apache.hadoop.hbase.testclassification.RPCTests;
+import org.apache.hadoop.hbase.ipc.RpcServerFactory;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.hbase.testclassification.SecurityTests;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
-import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
-import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
-import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
-import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
-
-import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestProtos.EchoRequestProto;
-import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface;
-
@RunWith(Parameterized.class)
-@Category({ RPCTests.class, MediumTests.class })
-public class TestNettyTlsIPCRejectPlainText {
+@Category({ SecurityTests.class, LargeTests.class })
+public class TestSaslTlsIPC extends AbstractTestSecureIPC {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
- HBaseClassTestRule.forClass(TestNettyTlsIPCRejectPlainText.class);
-
- private static final HBaseCommonTestingUtility UTIL = new
HBaseCommonTestingUtility();
-
- private static File DIR;
+ HBaseClassTestRule.forClass(TestSaslTlsIPC.class);
private static X509TestContextProvider PROVIDER;
@@ -87,19 +66,28 @@ public class TestNettyTlsIPCRejectPlainText {
@Parameterized.Parameter(2)
public String keyPassword;
- private X509TestContext x509TestContext;
+ @Parameterized.Parameter(3)
+ public boolean acceptPlainText;
- private RpcServer rpcServer;
+ @Parameterized.Parameter(4)
+ public boolean clientTlsEnabled;
- private RpcClient rpcClient;
+ private X509TestContext x509TestContext;
- @Parameterized.Parameters(name = "{index}: caKeyType={0}, certKeyType={1},
keyPassword={2}")
+ @Parameterized.Parameters(
+ name = "{index}: caKeyType={0}, certKeyType={1}, keyPassword={2},
acceptPlainText={3},"
+ + " clientTlsEnabled={4}")
public static List<Object[]> data() {
List<Object[]> params = new ArrayList<>();
for (X509KeyType caKeyType : X509KeyType.values()) {
for (X509KeyType certKeyType : X509KeyType.values()) {
for (String keyPassword : new String[] { "", "pa$$w0rd" }) {
- params.add(new Object[] { caKeyType, certKeyType, keyPassword });
+ // do not accept plain text
+ params.add(new Object[] { caKeyType, certKeyType, keyPassword,
false, true });
+ // support plain text and client enables tls
+ params.add(new Object[] { caKeyType, certKeyType, keyPassword, true,
true });
+ // support plain text and client disables tls
+ params.add(new Object[] { caKeyType, certKeyType, keyPassword, true,
false });
}
}
}
@@ -107,42 +95,42 @@ public class TestNettyTlsIPCRejectPlainText {
}
@BeforeClass
- public static void setUpBeforeClass() throws IOException {
+ public static void setUpBeforeClass() throws Exception {
Security.addProvider(new BouncyCastleProvider());
- DIR = new
File(UTIL.getDataTestDir(TestNettyTlsIPC.class.getSimpleName()).toString())
+ File dir = new
File(TEST_UTIL.getDataTestDir(TestNettyTlsIPC.class.getSimpleName()).toString())
.getCanonicalFile();
- FileUtils.forceMkdir(DIR);
- Configuration conf = UTIL.getConfiguration();
+ FileUtils.forceMkdir(dir);
+ initKDCAndConf();
+ Configuration conf = TEST_UTIL.getConfiguration();
+ // server must enable tls
conf.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_ENABLED, true);
- conf.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT, false);
- conf.setBoolean(X509Util.HBASE_CLIENT_NETTY_TLS_ENABLED, false);
- PROVIDER = new X509TestContextProvider(conf, DIR);
+ // only netty support tls
+ conf.setClass(RpcClientFactory.CUSTOM_RPC_CLIENT_IMPL_CONF_KEY,
NettyRpcClient.class,
+ RpcClient.class);
+ conf.setClass(RpcServerFactory.CUSTOM_RPC_SERVER_IMPL_CONF_KEY,
NettyRpcServer.class,
+ RpcServer.class);
+ PROVIDER = new X509TestContextProvider(conf, dir);
}
@AfterClass
- public static void tearDownAfterClass() {
+ public static void tearDownAfterClass() throws InterruptedException {
+ stopKDC();
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
- UTIL.cleanupTestDir();
+ TEST_UTIL.cleanupTestDir();
}
@Before
- public void setUp() throws IOException {
+ public void setUp() throws Exception {
x509TestContext = PROVIDER.get(caKeyType, certKeyType, keyPassword);
x509TestContext.setConfigurations(KeyStoreFileType.JKS,
KeyStoreFileType.JKS);
- Configuration conf = UTIL.getConfiguration();
- rpcServer = new NettyRpcServer(null, "testRpcServer",
- Lists.newArrayList(new RpcServer.BlockingServiceAndInterface(SERVICE,
null)),
- new InetSocketAddress("localhost", 0), conf, new FifoRpcScheduler(conf,
1), true);
- rpcServer.start();
- rpcClient = new NettyRpcClient(conf);
+ Configuration conf = TEST_UTIL.getConfiguration();
+ conf.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT,
acceptPlainText);
+ conf.setBoolean(X509Util.HBASE_CLIENT_NETTY_TLS_ENABLED, clientTlsEnabled);
+ setUpPrincipalAndConf();
}
@After
- public void tearDown() throws IOException {
- if (rpcServer != null) {
- rpcServer.stop();
- }
- Closeables.close(rpcClient, true);
+ public void tearDown() {
x509TestContext.clearConfigurations();
x509TestContext.getConf().unset(X509Util.TLS_CONFIG_OCSP);
x509TestContext.getConf().unset(X509Util.TLS_CONFIG_CLR);
@@ -152,12 +140,4 @@ public class TestNettyTlsIPCRejectPlainText {
Security.setProperty("ocsp.enable", Boolean.FALSE.toString());
Security.setProperty("com.sun.security.enableCRLDP",
Boolean.FALSE.toString());
}
-
- @Test
- public void testReject() throws IOException, ServiceException {
- BlockingInterface stub = newBlockingStub(rpcClient,
rpcServer.getListenerAddress());
- ServiceException se = assertThrows(ServiceException.class,
- () -> stub.echo(null, EchoRequestProto.newBuilder().setMessage("hello
world").build()));
- assertThat(se.getCause(), instanceOf(ConnectionClosedException.class));
- }
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSaslTlsIPCRejectPlainText.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSaslTlsIPCRejectPlainText.java
new file mode 100644
index 00000000000..0b54e9a6512
--- /dev/null
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSaslTlsIPCRejectPlainText.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.security;
+
+import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.loginKerberosPrincipal;
+import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.setSecuredConfiguration;
+
+import java.io.File;
+import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.apache.hadoop.hbase.testclassification.SecurityTests;
+import org.apache.hadoop.minikdc.MiniKdc;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mockito;
+
+import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface;
+
+@RunWith(Parameterized.class)
+@Category({ SecurityTests.class, MediumTests.class })
+public class TestSaslTlsIPCRejectPlainText extends
AbstractTestTlsRejectPlainText {
+
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+ HBaseClassTestRule.forClass(TestSaslTlsIPCRejectPlainText.class);
+
+ private static File KEYTAB_FILE;
+
+ private static MiniKdc KDC;
+ private static String HOST = "localhost";
+ private static String PRINCIPAL;
+ private static UserGroupInformation UGI;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ HBaseTestingUtility util = new HBaseTestingUtility();
+ UTIL = util;
+ initialize();
+ KEYTAB_FILE = new File(util.getDataTestDir("keytab").toUri().getPath());
+ KDC = util.setupMiniKdc(KEYTAB_FILE);
+ PRINCIPAL = "hbase/" + HOST;
+ KDC.createPrincipal(KEYTAB_FILE, PRINCIPAL);
+ HBaseKerberosUtils.setPrincipalForTesting(PRINCIPAL + "@" +
KDC.getRealm());
+ UGI = loginKerberosPrincipal(KEYTAB_FILE.getCanonicalPath(), PRINCIPAL);
+ setSecuredConfiguration(util.getConfiguration());
+ SecurityInfo securityInfoMock = Mockito.mock(SecurityInfo.class);
+ Mockito.when(securityInfoMock.getServerPrincipal())
+ .thenReturn(HBaseKerberosUtils.KRB_PRINCIPAL);
+ SecurityInfo.addInfo("TestProtobufRpcProto", securityInfoMock);
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() {
+ if (KDC != null) {
+ KDC.stop();
+ }
+ cleanUp();
+ }
+
+ @Override
+ protected BlockingInterface createStub() throws Exception {
+ return TestProtobufRpcServiceImpl.newBlockingStub(rpcClient,
rpcServer.getListenerAddress(),
+ User.create(UGI));
+ }
+}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSecureIPC.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSecureIPC.java
index a96eec6a47e..991c3a936cb 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSecureIPC.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSecureIPC.java
@@ -17,101 +17,37 @@
*/
package org.apache.hadoop.hbase.security;
-import static org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.SERVICE;
-import static
org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.newBlockingStub;
-import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.getKeytabFileForTesting;
-import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.getPrincipalForTesting;
-import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.setSecuredConfiguration;
-import static
org.apache.hadoop.hbase.security.provider.SaslClientAuthenticationProviders.SELECTOR_KEY;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
-import java.util.Map;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.CommonConfigurationKeys;
import org.apache.hadoop.hbase.HBaseClassTestRule;
-import org.apache.hadoop.hbase.HBaseTestingUtility;
-import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.ipc.BlockingRpcClient;
-import org.apache.hadoop.hbase.ipc.FifoRpcScheduler;
import org.apache.hadoop.hbase.ipc.NettyRpcClient;
import org.apache.hadoop.hbase.ipc.NettyRpcServer;
-import org.apache.hadoop.hbase.ipc.RpcClient;
import org.apache.hadoop.hbase.ipc.RpcClientFactory;
-import org.apache.hadoop.hbase.ipc.RpcServer;
import org.apache.hadoop.hbase.ipc.RpcServerFactory;
-import org.apache.hadoop.hbase.ipc.RpcServerInterface;
import org.apache.hadoop.hbase.ipc.SimpleRpcServer;
-import
org.apache.hadoop.hbase.security.provider.AuthenticationProviderSelector;
-import org.apache.hadoop.hbase.security.provider.BuiltInProviderSelector;
-import org.apache.hadoop.hbase.security.provider.SaslAuthMethod;
-import
org.apache.hadoop.hbase.security.provider.SaslClientAuthenticationProvider;
import org.apache.hadoop.hbase.testclassification.LargeTests;
import org.apache.hadoop.hbase.testclassification.SecurityTests;
-import org.apache.hadoop.hbase.util.Pair;
-import org.apache.hadoop.minikdc.MiniKdc;
-import org.apache.hadoop.security.UserGroupInformation;
-import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
-import org.apache.hadoop.security.token.Token;
-import org.apache.hadoop.security.token.TokenIdentifier;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
-import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
-import org.mockito.Mockito;
-
-import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
-import org.apache.hbase.thirdparty.com.google.protobuf.BlockingService;
-
-import org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestProtos;
-import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface;
-import
org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.UserInformation;
@RunWith(Parameterized.class)
@Category({ SecurityTests.class, LargeTests.class })
-public class TestSecureIPC {
+public class TestSecureIPC extends AbstractTestSecureIPC {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestSecureIPC.class);
- private static final HBaseTestingUtility TEST_UTIL = new
HBaseTestingUtility();
-
- private static final File KEYTAB_FILE =
- new File(TEST_UTIL.getDataTestDir("keytab").toUri().getPath());
-
- private static MiniKdc KDC;
- private static String HOST = "localhost";
- private static String PRINCIPAL;
-
- private String krbKeytab;
- private String krbPrincipal;
- private UserGroupInformation ugi;
- private Configuration clientConf;
- private Configuration serverConf;
-
@Parameters(name = "{index}: rpcClientImpl={0}, rpcServerImpl={1}")
public static Collection<Object[]> parameters() {
List<Object[]> params = new ArrayList<>();
@@ -135,317 +71,19 @@ public class TestSecureIPC {
@BeforeClass
public static void setUp() throws Exception {
- KDC = TEST_UTIL.setupMiniKdc(KEYTAB_FILE);
- PRINCIPAL = "hbase/" + HOST;
- KDC.createPrincipal(KEYTAB_FILE, PRINCIPAL);
- HBaseKerberosUtils.setPrincipalForTesting(PRINCIPAL + "@" +
KDC.getRealm());
- // set a smaller timeout and retry to speed up tests
- TEST_UTIL.getConfiguration().setInt(RpcClient.SOCKET_TIMEOUT_READ, 2000);
- TEST_UTIL.getConfiguration().setInt("hbase.security.relogin.maxretries",
1);
+ initKDCAndConf();
}
@AfterClass
- public static void tearDown() throws IOException {
- if (KDC != null) {
- KDC.stop();
- }
+ public static void tearDown() throws Exception {
+ stopKDC();
TEST_UTIL.cleanupTestDir();
}
@Before
public void setUpTest() throws Exception {
- krbKeytab = getKeytabFileForTesting();
- krbPrincipal = getPrincipalForTesting();
- ugi = loginKerberosPrincipal(krbKeytab, krbPrincipal);
- clientConf = new Configuration(TEST_UTIL.getConfiguration());
- setSecuredConfiguration(clientConf);
+ setUpPrincipalAndConf();
clientConf.set(RpcClientFactory.CUSTOM_RPC_CLIENT_IMPL_CONF_KEY,
rpcClientImpl);
- serverConf = new Configuration(TEST_UTIL.getConfiguration());
- setSecuredConfiguration(serverConf);
serverConf.set(RpcServerFactory.CUSTOM_RPC_SERVER_IMPL_CONF_KEY,
rpcServerImpl);
}
-
- @Test
- public void testRpcCallWithEnabledKerberosSaslAuth() throws Exception {
- UserGroupInformation ugi2 = UserGroupInformation.getCurrentUser();
-
- // check that the login user is okay:
- assertSame(ugi2, ugi);
- assertEquals(AuthenticationMethod.KERBEROS, ugi.getAuthenticationMethod());
- assertEquals(krbPrincipal, ugi.getUserName());
-
- callRpcService(User.create(ugi2));
- }
-
- @Test
- public void testRpcCallWithEnabledKerberosSaslAuth_CanonicalHostname()
throws Exception {
- UserGroupInformation ugi2 = UserGroupInformation.getCurrentUser();
-
- // check that the login user is okay:
- assertSame(ugi2, ugi);
- assertEquals(AuthenticationMethod.KERBEROS, ugi.getAuthenticationMethod());
- assertEquals(krbPrincipal, ugi.getUserName());
-
- enableCanonicalHostnameTesting(clientConf, "localhost");
- clientConf.setBoolean(
-
SecurityConstants.UNSAFE_HBASE_CLIENT_KERBEROS_HOSTNAME_DISABLE_REVERSEDNS,
false);
- clientConf.set(HBaseKerberosUtils.KRB_PRINCIPAL, "hbase/_HOST@" +
KDC.getRealm());
-
- callRpcService(User.create(ugi2));
- }
-
- @Test
- public void testRpcCallWithEnabledKerberosSaslAuth_NoCanonicalHostname()
throws Exception {
- UserGroupInformation ugi2 = UserGroupInformation.getCurrentUser();
-
- // check that the login user is okay:
- assertSame(ugi2, ugi);
- assertEquals(AuthenticationMethod.KERBEROS, ugi.getAuthenticationMethod());
- assertEquals(krbPrincipal, ugi.getUserName());
-
- enableCanonicalHostnameTesting(clientConf, "127.0.0.1");
- clientConf
-
.setBoolean(SecurityConstants.UNSAFE_HBASE_CLIENT_KERBEROS_HOSTNAME_DISABLE_REVERSEDNS,
true);
- clientConf.set(HBaseKerberosUtils.KRB_PRINCIPAL, "hbase/_HOST@" +
KDC.getRealm());
-
- callRpcService(User.create(ugi2));
- }
-
- private static void enableCanonicalHostnameTesting(Configuration conf,
String canonicalHostname) {
- conf.setClass(SELECTOR_KEY,
CanonicalHostnameTestingAuthenticationProviderSelector.class,
- AuthenticationProviderSelector.class);
-
conf.set(CanonicalHostnameTestingAuthenticationProviderSelector.CANONICAL_HOST_NAME_KEY,
- canonicalHostname);
- }
-
- public static class CanonicalHostnameTestingAuthenticationProviderSelector
- extends BuiltInProviderSelector {
- private static final String CANONICAL_HOST_NAME_KEY =
-
"CanonicalHostnameTestingAuthenticationProviderSelector.canonicalHostName";
-
- @Override
- public Pair<SaslClientAuthenticationProvider, Token<? extends
TokenIdentifier>>
- selectProvider(String clusterId, User user) {
- final Pair<SaslClientAuthenticationProvider, Token<? extends
TokenIdentifier>> pair =
- super.selectProvider(clusterId, user);
- pair.setFirst(createCanonicalHostNameTestingProvider(pair.getFirst()));
- return pair;
- }
-
- SaslClientAuthenticationProvider
- createCanonicalHostNameTestingProvider(SaslClientAuthenticationProvider
delegate) {
- return new SaslClientAuthenticationProvider() {
- @Override
- public SaslClient createClient(Configuration conf, InetAddress
serverAddr,
- SecurityInfo securityInfo, Token<? extends TokenIdentifier> token,
- boolean fallbackAllowed, Map<String, String> saslProps) throws
IOException {
- final String s = conf.get(CANONICAL_HOST_NAME_KEY);
- if (s != null) {
- try {
- final Field canonicalHostName =
- InetAddress.class.getDeclaredField("canonicalHostName");
- canonicalHostName.setAccessible(true);
- canonicalHostName.set(serverAddr, s);
- } catch (NoSuchFieldException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-
- return delegate.createClient(conf, serverAddr, securityInfo, token,
fallbackAllowed,
- saslProps);
- }
-
- @Override
- public UserInformation getUserInfo(User user) {
- return delegate.getUserInfo(user);
- }
-
- @Override
- public UserGroupInformation getRealUser(User ugi) {
- return delegate.getRealUser(ugi);
- }
-
- @Override
- public boolean canRetry() {
- return delegate.canRetry();
- }
-
- @Override
- public void relogin() throws IOException {
- delegate.relogin();
- }
-
- @Override
- public SaslAuthMethod getSaslAuthMethod() {
- return delegate.getSaslAuthMethod();
- }
-
- @Override
- public String getTokenKind() {
- return delegate.getTokenKind();
- }
- };
- }
- }
-
- @Test
- public void testRpcFallbackToSimpleAuth() throws Exception {
- String clientUsername = "testuser";
- UserGroupInformation clientUgi =
- UserGroupInformation.createUserForTesting(clientUsername, new String[] {
clientUsername });
-
- // check that the client user is insecure
- assertNotSame(ugi, clientUgi);
- assertEquals(AuthenticationMethod.SIMPLE,
clientUgi.getAuthenticationMethod());
- assertEquals(clientUsername, clientUgi.getUserName());
-
- clientConf.set(User.HBASE_SECURITY_CONF_KEY, "simple");
- serverConf.setBoolean(RpcServer.FALLBACK_TO_INSECURE_CLIENT_AUTH, true);
- callRpcService(User.create(clientUgi));
- }
-
- private void setRpcProtection(String clientProtection, String
serverProtection) {
- clientConf.set("hbase.rpc.protection", clientProtection);
- serverConf.set("hbase.rpc.protection", serverProtection);
- }
-
- /**
- * Test various combinations of Server and Client qops. n
- */
- @Test
- public void testSaslWithCommonQop() throws Exception {
- setRpcProtection("privacy,authentication", "authentication");
- callRpcService(User.create(ugi));
-
- setRpcProtection("authentication", "privacy,authentication");
- callRpcService(User.create(ugi));
-
- setRpcProtection("integrity,authentication", "privacy,authentication");
- callRpcService(User.create(ugi));
-
- setRpcProtection("integrity,authentication", "integrity,authentication");
- callRpcService(User.create(ugi));
-
- setRpcProtection("privacy,authentication", "privacy,authentication");
- callRpcService(User.create(ugi));
- }
-
- @Test
- public void testSaslNoCommonQop() throws Exception {
- setRpcProtection("integrity", "privacy");
- SaslException se = assertThrows(SaslException.class, () ->
callRpcService(User.create(ugi)));
- assertEquals("No common protection layer between client and server",
se.getMessage());
- }
-
- /**
- * Test sasl encryption with Crypto AES. n
- */
- @Test
- public void testSaslWithCryptoAES() throws Exception {
- setRpcProtection("privacy", "privacy");
- setCryptoAES("true", "true");
- callRpcService(User.create(ugi));
- }
-
- /**
- * Test various combinations of Server and Client configuration for Crypto
AES. n
- */
- @Test
- public void testDifferentConfWithCryptoAES() throws Exception {
- setRpcProtection("privacy", "privacy");
-
- setCryptoAES("false", "true");
- callRpcService(User.create(ugi));
-
- setCryptoAES("true", "false");
- try {
- callRpcService(User.create(ugi));
- fail("The exception should be thrown out for the rpc timeout.");
- } catch (Exception e) {
- // ignore the expected exception
- }
- }
-
- void setCryptoAES(String clientCryptoAES, String serverCryptoAES) {
- clientConf.set("hbase.rpc.crypto.encryption.aes.enabled", clientCryptoAES);
- serverConf.set("hbase.rpc.crypto.encryption.aes.enabled", serverCryptoAES);
- }
-
- private UserGroupInformation loginKerberosPrincipal(String krbKeytab, String
krbPrincipal)
- throws Exception {
- Configuration cnf = new Configuration();
- cnf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION,
"kerberos");
- UserGroupInformation.setConfiguration(cnf);
- UserGroupInformation.loginUserFromKeytab(krbPrincipal, krbKeytab);
- return UserGroupInformation.getLoginUser();
- }
-
- /**
- * Sets up a RPC Server and a Client. Does a RPC checks the result. If an
exception is thrown from
- * the stub, this function will throw root cause of that exception.
- */
- private void callRpcService(User clientUser) throws Exception {
- SecurityInfo securityInfoMock = Mockito.mock(SecurityInfo.class);
- Mockito.when(securityInfoMock.getServerPrincipal())
- .thenReturn(HBaseKerberosUtils.KRB_PRINCIPAL);
- SecurityInfo.addInfo("TestProtobufRpcProto", securityInfoMock);
-
- InetSocketAddress isa = new InetSocketAddress(HOST, 0);
-
- RpcServerInterface rpcServer = RpcServerFactory.createRpcServer(null,
"AbstractTestSecureIPC",
- Lists
- .newArrayList(new
RpcServer.BlockingServiceAndInterface((BlockingService) SERVICE, null)),
- isa, serverConf, new FifoRpcScheduler(serverConf, 1));
- rpcServer.start();
- try (RpcClient rpcClient =
- RpcClientFactory.createClient(clientConf,
HConstants.DEFAULT_CLUSTER_ID.toString())) {
- BlockingInterface stub =
- newBlockingStub(rpcClient, rpcServer.getListenerAddress(), clientUser);
- TestThread th1 = new TestThread(stub);
- final Throwable exception[] = new Throwable[1];
- Collections.synchronizedList(new ArrayList<Throwable>());
- Thread.UncaughtExceptionHandler exceptionHandler = new
Thread.UncaughtExceptionHandler() {
- @Override
- public void uncaughtException(Thread th, Throwable ex) {
- exception[0] = ex;
- }
- };
- th1.setUncaughtExceptionHandler(exceptionHandler);
- th1.start();
- th1.join();
- if (exception[0] != null) {
- // throw root cause.
- while (exception[0].getCause() != null) {
- exception[0] = exception[0].getCause();
- }
- throw (Exception) exception[0];
- }
- } finally {
- rpcServer.stop();
- }
- }
-
- public static class TestThread extends Thread {
- private final BlockingInterface stub;
-
- public TestThread(BlockingInterface stub) {
- this.stub = stub;
- }
-
- @Override
- public void run() {
- try {
- int[] messageSize = new int[] { 100, 1000, 10000 };
- for (int i = 0; i < messageSize.length; i++) {
- String input = RandomStringUtils.random(messageSize[i]);
- String result =
- stub.echo(null,
TestProtos.EchoRequestProto.newBuilder().setMessage(input).build())
- .getMessage();
- assertEquals(input, result);
- }
- } catch
(org.apache.hbase.thirdparty.com.google.protobuf.ServiceException e) {
- throw new RuntimeException(e);
- }
- }
- }
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestTlsWithKerberos.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestTlsWithKerberos.java
deleted file mode 100644
index c974755f577..00000000000
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestTlsWithKerberos.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.hbase.security;
-
-import static
org.apache.hadoop.hbase.io.crypto.tls.X509Util.HBASE_CLIENT_NETTY_TLS_ENABLED;
-import static
org.apache.hadoop.hbase.io.crypto.tls.X509Util.HBASE_SERVER_NETTY_TLS_ENABLED;
-import static
org.apache.hadoop.hbase.io.crypto.tls.X509Util.HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT;
-import static org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.SERVICE;
-import static
org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.newBlockingStub;
-import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.getKeytabFileForTesting;
-import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.getPrincipalForTesting;
-import static
org.apache.hadoop.hbase.security.HBaseKerberosUtils.setSecuredConfiguration;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.security.Security;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.concurrent.atomic.AtomicReference;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.CommonConfigurationKeys;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
-import org.apache.hadoop.hbase.HBaseConfiguration;
-import org.apache.hadoop.hbase.HBaseTestingUtility;
-import org.apache.hadoop.hbase.HConstants;
-import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;
-import org.apache.hadoop.hbase.io.crypto.tls.KeyStoreFileType;
-import org.apache.hadoop.hbase.io.crypto.tls.X509KeyType;
-import org.apache.hadoop.hbase.io.crypto.tls.X509TestContext;
-import org.apache.hadoop.hbase.ipc.FifoRpcScheduler;
-import org.apache.hadoop.hbase.ipc.NettyRpcClient;
-import org.apache.hadoop.hbase.ipc.NettyRpcServer;
-import org.apache.hadoop.hbase.ipc.RpcClient;
-import org.apache.hadoop.hbase.ipc.RpcClientFactory;
-import org.apache.hadoop.hbase.ipc.RpcServer;
-import org.apache.hadoop.hbase.ipc.RpcServerFactory;
-import org.apache.hadoop.hbase.ipc.RpcServerInterface;
-import org.apache.hadoop.hbase.testclassification.LargeTests;
-import org.apache.hadoop.hbase.testclassification.SecurityTests;
-import org.apache.hadoop.minikdc.MiniKdc;
-import org.apache.hadoop.security.UserGroupInformation;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.mockito.Mockito;
-
-import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
-import org.apache.hbase.thirdparty.com.google.protobuf.BlockingService;
-
-import
org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestRpcServiceProtos;
-
-@Category({ SecurityTests.class, LargeTests.class })
-public class TestTlsWithKerberos {
-
- @ClassRule
- public static final HBaseClassTestRule CLASS_RULE =
- HBaseClassTestRule.forClass(TestTlsWithKerberos.class);
-
- private static final HBaseTestingUtility TEST_UTIL = new
HBaseTestingUtility();
-
- private static final File KEYTAB_FILE =
- new File(TEST_UTIL.getDataTestDir("keytab").toUri().getPath());
-
- private static MiniKdc KDC;
- private static final String HOST = "localhost";
- private static String PRINCIPAL;
- private static final String RPC_CLIENT_IMPL = NettyRpcClient.class.getName();
- private static final String RPC_SERVER_IMPL = NettyRpcServer.class.getName();
-
- private String krbKeytab;
- private String krbPrincipal;
- private UserGroupInformation ugi;
- private Configuration clientConf;
- private Configuration serverConf;
- private static X509TestContext x509TestContext;
-
- @BeforeClass
- public static void setUp() throws Exception {
- Security.addProvider(new BouncyCastleProvider());
- KDC = TEST_UTIL.setupMiniKdc(KEYTAB_FILE);
- PRINCIPAL = "hbase/" + HOST;
- KDC.createPrincipal(KEYTAB_FILE, PRINCIPAL);
- HBaseKerberosUtils.setPrincipalForTesting(PRINCIPAL + "@" +
KDC.getRealm());
- x509TestContext = X509TestContext.newBuilder()
- .setTempDir(new File(TEST_UTIL.getDataTestDir().toUri().getPath()))
- .setKeyStorePassword("Pa$$word").setKeyStoreKeyType(X509KeyType.RSA)
-
.setTrustStoreKeyType(X509KeyType.RSA).setTrustStorePassword("Pa$$word").build();
- x509TestContext.setConfigurations(KeyStoreFileType.JKS,
KeyStoreFileType.JKS);
- }
-
- @AfterClass
- public static void tearDown() throws IOException {
- Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
- if (KDC != null) {
- KDC.stop();
- }
- TEST_UTIL.cleanupTestDir();
- }
-
- @Before
- public void setUpTest() throws Exception {
- krbKeytab = getKeytabFileForTesting();
- krbPrincipal = getPrincipalForTesting();
- ugi = loginKerberosPrincipal(krbKeytab, krbPrincipal);
- clientConf = HBaseConfiguration.create(x509TestContext.getConf());
- setSecuredConfiguration(clientConf);
- clientConf.set(RpcClientFactory.CUSTOM_RPC_CLIENT_IMPL_CONF_KEY,
RPC_CLIENT_IMPL);
- serverConf = HBaseConfiguration.create(x509TestContext.getConf());
- setSecuredConfiguration(serverConf);
- serverConf.set(RpcServerFactory.CUSTOM_RPC_SERVER_IMPL_CONF_KEY,
RPC_SERVER_IMPL);
- }
-
- @Test
- public void testNoPlaintext() throws Exception {
- setRpcProtection("authentication", "authentication");
- setTLSEncryption(true, false, true);
- callRpcService(User.create(ugi));
- }
-
- @Test
- public void testRejectPlaintext() {
- setRpcProtection("authentication", "authentication");
- setTLSEncryption(true, false, false);
- Assert.assertThrows(ConnectionClosedException.class, () ->
callRpcService(User.create(ugi)));
- }
-
- @Test
- public void testAcceptPlaintext() throws Exception {
- setRpcProtection("authentication", "authentication");
- setTLSEncryption(true, true, false);
- callRpcService(User.create(ugi));
- }
-
- void setTLSEncryption(Boolean server, Boolean acceptPlaintext, Boolean
client) {
- serverConf.set(HBASE_SERVER_NETTY_TLS_ENABLED, server.toString());
- serverConf.set(HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT,
acceptPlaintext.toString());
- clientConf.set(HBASE_CLIENT_NETTY_TLS_ENABLED, client.toString());
- }
-
- void setRpcProtection(String clientProtection, String serverProtection) {
- clientConf.set("hbase.rpc.protection", clientProtection);
- serverConf.set("hbase.rpc.protection", serverProtection);
- }
-
- private UserGroupInformation loginKerberosPrincipal(String krbKeytab, String
krbPrincipal)
- throws Exception {
- Configuration cnf = new Configuration();
- cnf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION,
"kerberos");
- UserGroupInformation.setConfiguration(cnf);
- UserGroupInformation.loginUserFromKeytab(krbPrincipal, krbKeytab);
- return UserGroupInformation.getLoginUser();
- }
-
- /**
- * Sets up a RPC Server and a Client. Does a RPC checks the result. If an
exception is thrown from
- * the stub, this function will throw root cause of that exception.
- */
- private void callRpcService(User clientUser) throws Exception {
- SecurityInfo securityInfoMock = Mockito.mock(SecurityInfo.class);
- Mockito.when(securityInfoMock.getServerPrincipal())
- .thenReturn(HBaseKerberosUtils.KRB_PRINCIPAL);
- SecurityInfo.addInfo("TestProtobufRpcProto", securityInfoMock);
-
- InetSocketAddress isa = new InetSocketAddress(HOST, 0);
-
- RpcServerInterface rpcServer = RpcServerFactory.createRpcServer(null,
"AbstractTestSecureIPC",
- Lists
- .newArrayList(new
RpcServer.BlockingServiceAndInterface((BlockingService) SERVICE, null)),
- isa, serverConf, new FifoRpcScheduler(serverConf, 1));
- rpcServer.start();
- try (RpcClient rpcClient =
- RpcClientFactory.createClient(clientConf,
HConstants.DEFAULT_CLUSTER_ID.toString())) {
- TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface stub =
- newBlockingStub(rpcClient, rpcServer.getListenerAddress(), clientUser);
- TestSecureIPC.TestThread th = new TestSecureIPC.TestThread(stub);
- AtomicReference<Throwable> exception = new AtomicReference<>();
- Collections.synchronizedList(new ArrayList<Throwable>());
- Thread.UncaughtExceptionHandler exceptionHandler = new
Thread.UncaughtExceptionHandler() {
- @Override
- public void uncaughtException(Thread th, Throwable ex) {
- exception.set(ex);
- }
- };
- th.setUncaughtExceptionHandler(exceptionHandler);
- th.start();
- th.join();
- if (exception.get() != null) {
- // throw root cause.
- while (exception.get().getCause() != null) {
- exception.set(exception.get().getCause());
- }
- throw (Exception) exception.get();
- }
- } finally {
- rpcServer.stop();
- }
- }
-}