Repository: hbase Updated Branches: refs/heads/branch-1 d7666b606 -> 094e9a311
http://git-wip-us.apache.org/repos/asf/hbase/blob/094e9a31/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestSecureIPC.java ---------------------------------------------------------------------- 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 baaa985..b016bd3 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 @@ -1,4 +1,5 @@ /** + * * 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 @@ -15,19 +16,259 @@ * 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.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.getSecuredConfiguration; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; + +import com.google.common.collect.Lists; +import com.google.protobuf.BlockingService; +import com.google.protobuf.ServiceException; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import javax.security.sasl.SaslException; + +import org.apache.commons.lang.RandomStringUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.CommonConfigurationKeys; +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.RpcClient; -import org.apache.hadoop.hbase.ipc.RpcClientImpl; +import org.apache.hadoop.hbase.ipc.RpcClientFactory; +import org.apache.hadoop.hbase.ipc.RpcServer; +import org.apache.hadoop.hbase.ipc.RpcServerInterface; +import org.apache.hadoop.hbase.ipc.protobuf.generated.TestProtos; +import org.apache.hadoop.hbase.ipc.protobuf.generated.TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface; import org.apache.hadoop.hbase.testclassification.SecurityTests; import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.minikdc.MiniKdc; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +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; +@RunWith(Parameterized.class) @Category({ SecurityTests.class, SmallTests.class }) -public class TestSecureIPC extends AbstractTestSecureIPC { +public class TestSecureIPC { + + 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; + + String krbKeytab; + String krbPrincipal; + UserGroupInformation ugi; + Configuration clientConf; + Configuration serverConf; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Parameters(name = "{index}: rpcClientImpl={0}") + public static Collection<Object[]> parameters() { + return Arrays.asList(new Object[] { BlockingRpcClient.class.getName() }, + new Object[] { NettyRpcClient.class.getName() }); + } + + @Parameter + public String rpcClientImpl; + + @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()); + } + + @AfterClass + public static void tearDown() throws IOException { + if (KDC != null) { + KDC.stop(); + } + TEST_UTIL.cleanupTestDir(); + } + + @Before + public void setUpTest() throws Exception { + krbKeytab = getKeytabFileForTesting(); + krbPrincipal = getPrincipalForTesting(); + ugi = loginKerberosPrincipal(krbKeytab, krbPrincipal); + clientConf = getSecuredConfiguration(); + clientConf.set(RpcClientFactory.CUSTOM_RPC_CLIENT_IMPL_CONF_KEY, rpcClientImpl); + serverConf = getSecuredConfiguration(); + } + + @Test + public void testRpcCallWithEnabledKerberosSaslAuth() throws Exception { + UserGroupInformation ugi2 = UserGroupInformation.getCurrentUser(); + + // check that the login user is okay: + assertSame(ugi, ugi2); + assertEquals(AuthenticationMethod.KERBEROS, ugi.getAuthenticationMethod()); + assertEquals(krbPrincipal, ugi.getUserName()); + + callRpcService(User.create(ugi2)); + } + + @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)); + } + + 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. + * @throws Exception + */ + @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)); + } + + @Ignore + @Test + public void testSaslNoCommonQop() throws Exception { + exception.expect(SaslException.class); + exception.expectMessage("No common protection layer between client and server"); + setRpcProtection("integrity", "privacy"); + callRpcService(User.create(ugi)); + } + + 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 = new RpcServer(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() { + 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; + } - Class<? extends RpcClient> getRpcClientClass() { - return RpcClientImpl.class; + @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 (ServiceException e) { + throw new RuntimeException(e); + } + } } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/hbase/blob/094e9a31/hbase-server/src/test/java/org/apache/hadoop/hbase/security/token/TestDelegationTokenWithEncryption.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/token/TestDelegationTokenWithEncryption.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/token/TestDelegationTokenWithEncryption.java index 60d4a6a..aa8c7ee 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/token/TestDelegationTokenWithEncryption.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/token/TestDelegationTokenWithEncryption.java @@ -19,6 +19,9 @@ package org.apache.hadoop.hbase.security.token; import com.google.protobuf.ServiceException; + +import java.io.IOException; + import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.TableName; @@ -29,10 +32,10 @@ import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Table; -import org.apache.hadoop.hbase.ipc.AsyncRpcClient; +import org.apache.hadoop.hbase.ipc.BlockingRpcClient; +import org.apache.hadoop.hbase.ipc.NettyRpcClient; import org.apache.hadoop.hbase.ipc.RpcClient; import org.apache.hadoop.hbase.ipc.RpcClientFactory; -import org.apache.hadoop.hbase.ipc.RpcClientImpl; import org.apache.hadoop.hbase.testclassification.MediumTests; import org.apache.hadoop.hbase.testclassification.SecurityTests; import org.apache.hadoop.hbase.util.Bytes; @@ -43,7 +46,6 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; -import java.io.IOException; @Category({ SecurityTests.class, MediumTests.class }) public class TestDelegationTokenWithEncryption extends SecureTestCluster { @@ -84,8 +86,8 @@ public class TestDelegationTokenWithEncryption extends SecureTestCluster { tableDescriptor.addFamily(new HColumnDescriptor("family")); admin.createTable(tableDescriptor); - testPutGetWithDelegationToken(RpcClientImpl.class); - testPutGetWithDelegationToken(AsyncRpcClient.class); + testPutGetWithDelegationToken(BlockingRpcClient.class); + testPutGetWithDelegationToken(NettyRpcClient.class); } } } http://git-wip-us.apache.org/repos/asf/hbase/blob/094e9a31/hbase-server/src/test/java/org/apache/hadoop/hbase/security/token/TestGenerateDelegationToken.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/token/TestGenerateDelegationToken.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/token/TestGenerateDelegationToken.java index 1d7c676..25e252a 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/token/TestGenerateDelegationToken.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/token/TestGenerateDelegationToken.java @@ -20,6 +20,8 @@ package org.apache.hadoop.hbase.security.token; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import com.google.protobuf.ServiceException; + import java.io.IOException; import org.apache.hadoop.hbase.HConstants; @@ -27,11 +29,11 @@ import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.ConnectionFactory; import org.apache.hadoop.hbase.client.Table; -import org.apache.hadoop.hbase.ipc.AsyncRpcClient; +import org.apache.hadoop.hbase.ipc.BlockingRpcClient; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; +import org.apache.hadoop.hbase.ipc.NettyRpcClient; import org.apache.hadoop.hbase.ipc.RpcClient; import org.apache.hadoop.hbase.ipc.RpcClientFactory; -import org.apache.hadoop.hbase.ipc.RpcClientImpl; import org.apache.hadoop.hbase.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.protobuf.generated.AuthenticationProtos; import org.apache.hadoop.hbase.protobuf.generated.AuthenticationProtos.GetAuthenticationTokenRequest; @@ -47,8 +49,6 @@ import org.apache.hadoop.security.token.TokenIdentifier; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.google.protobuf.ServiceException; - @Category({ SecurityTests.class, MediumTests.class }) public class TestGenerateDelegationToken extends SecureTestCluster { @@ -79,8 +79,8 @@ public class TestGenerateDelegationToken extends SecureTestCluster { try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) { Token<? extends TokenIdentifier> token = TokenUtil.obtainToken(conn); UserGroupInformation.getCurrentUser().addToken(token); - testTokenAuth(RpcClientImpl.class); - testTokenAuth(AsyncRpcClient.class); + testTokenAuth(BlockingRpcClient.class); + testTokenAuth(NettyRpcClient.class); } } } http://git-wip-us.apache.org/repos/asf/hbase/blob/094e9a31/hbase-server/src/test/protobuf/test.proto ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/protobuf/test.proto b/hbase-server/src/test/protobuf/test.proto index 566b04b..72b68e9 100644 --- a/hbase-server/src/test/protobuf/test.proto +++ b/hbase-server/src/test/protobuf/test.proto @@ -33,3 +33,11 @@ message EchoRequestProto { message EchoResponseProto { required string message = 1; } + +message PauseRequestProto { + required uint32 ms = 1; +} + +message AddrResponseProto { + required string addr = 1; +} http://git-wip-us.apache.org/repos/asf/hbase/blob/094e9a31/hbase-server/src/test/protobuf/test_rpc_service.proto ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/protobuf/test_rpc_service.proto b/hbase-server/src/test/protobuf/test_rpc_service.proto index 4ed0380..5f91dc4 100644 --- a/hbase-server/src/test/protobuf/test_rpc_service.proto +++ b/hbase-server/src/test/protobuf/test_rpc_service.proto @@ -30,4 +30,6 @@ service TestProtobufRpcProto { rpc ping(EmptyRequestProto) returns (EmptyResponseProto); rpc echo(EchoRequestProto) returns (EchoResponseProto); rpc error(EmptyRequestProto) returns (EmptyResponseProto); + rpc pause(PauseRequestProto) returns (EmptyResponseProto); + rpc addr(EmptyRequestProto) returns (AddrResponseProto); } http://git-wip-us.apache.org/repos/asf/hbase/blob/094e9a31/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index bdccd28..03f885a 100644 --- a/pom.xml +++ b/pom.xml @@ -1207,7 +1207,7 @@ <clover.version>4.0.3</clover.version> <jamon-runtime.version>2.4.1</jamon-runtime.version> <jettison.version>1.3.3</jettison.version> - <netty.version>4.0.23.Final</netty.version> + <netty.version>4.1.8.Final</netty.version> <netty.hadoop.version>3.6.2.Final</netty.hadoop.version> <joni.version>2.1.2</joni.version> <jcodings.version>1.0.8</jcodings.version>
