1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.security;
20
21 import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getKeytabFileForTesting;
22 import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getPrincipalForTesting;
23 import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getSecuredConfiguration;
24 import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.isKerberosPropertySetted;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertNotSame;
27 import static org.junit.Assert.assertSame;
28 import static org.junit.Assume.assumeTrue;
29
30 import java.io.IOException;
31 import java.net.InetSocketAddress;
32 import java.util.ArrayList;
33 import java.util.List;
34
35 import org.apache.hadoop.conf.Configuration;
36 import org.apache.hadoop.fs.CommonConfigurationKeys;
37 import org.apache.hadoop.hbase.HConstants;
38 import org.apache.hadoop.hbase.ServerName;
39 import org.apache.hadoop.hbase.ipc.FifoRpcScheduler;
40 import org.apache.hadoop.hbase.ipc.RpcClient;
41 import org.apache.hadoop.hbase.ipc.RpcServer;
42 import org.apache.hadoop.hbase.ipc.RpcServerInterface;
43 import org.apache.hadoop.hbase.ipc.TestDelayedRpc.TestDelayedImplementation;
44 import org.apache.hadoop.hbase.ipc.TestDelayedRpc.TestThread;
45 import org.apache.hadoop.hbase.ipc.protobuf.generated.TestDelayedRpcProtos;
46 import org.apache.hadoop.hbase.testclassification.SmallTests;
47 import org.apache.hadoop.security.UserGroupInformation;
48 import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
49 import org.junit.Test;
50 import org.junit.experimental.categories.Category;
51 import org.mockito.Mockito;
52
53 import com.google.common.collect.Lists;
54 import com.google.protobuf.BlockingRpcChannel;
55 import com.google.protobuf.BlockingService;
56
57 @Category(SmallTests.class)
58 public class TestSecureRPC {
59 public static RpcServerInterface rpcServer;
60
61
62
63
64
65
66
67 @Test
68 public void testRpcCallWithEnabledKerberosSaslAuth()
69 throws Exception {
70 assumeTrue(isKerberosPropertySetted());
71 String krbKeytab = getKeytabFileForTesting();
72 String krbPrincipal = getPrincipalForTesting();
73
74 UserGroupInformation ugi = loginKerberosPrincipal(krbKeytab, krbPrincipal);
75 UserGroupInformation ugi2 = UserGroupInformation.getCurrentUser();
76
77
78 assertSame(ugi, ugi2);
79 assertEquals(AuthenticationMethod.KERBEROS, ugi.getAuthenticationMethod());
80 assertEquals(krbPrincipal, ugi.getUserName());
81
82 Configuration clientConf = getSecuredConfiguration();
83 callRpcService(User.create(ugi2), clientConf, false);
84 }
85
86 private UserGroupInformation loginKerberosPrincipal(String krbKeytab, String krbPrincipal)
87 throws Exception {
88 Configuration cnf = new Configuration();
89 cnf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos");
90 UserGroupInformation.setConfiguration(cnf);
91 UserGroupInformation.loginUserFromKeytab(krbPrincipal, krbKeytab);
92 return UserGroupInformation.getLoginUser();
93 }
94
95 private void callRpcService(User clientUser, Configuration clientConf,
96 boolean allowInsecureFallback) throws Exception {
97
98 Configuration conf = getSecuredConfiguration();
99 conf.setBoolean(RpcServer.FALLBACK_TO_INSECURE_CLIENT_AUTH, allowInsecureFallback);
100
101 SecurityInfo securityInfoMock = Mockito.mock(SecurityInfo.class);
102 Mockito.when(securityInfoMock.getServerPrincipal())
103 .thenReturn(HBaseKerberosUtils.KRB_PRINCIPAL);
104 SecurityInfo.addInfo("TestDelayedService", securityInfoMock);
105
106 boolean delayReturnValue = false;
107 InetSocketAddress isa = new InetSocketAddress("localhost", 0);
108 TestDelayedImplementation instance = new TestDelayedImplementation(delayReturnValue);
109 BlockingService service =
110 TestDelayedRpcProtos.TestDelayedService.newReflectiveBlockingService(instance);
111
112 rpcServer = new RpcServer(null, "testSecuredDelayedRpc",
113 Lists.newArrayList(new RpcServer.BlockingServiceAndInterface(service, null)),
114 isa, conf, new FifoRpcScheduler(conf, 1));
115 rpcServer.start();
116 RpcClient rpcClient = new RpcClient(clientConf, HConstants.DEFAULT_CLUSTER_ID.toString());
117 try {
118 InetSocketAddress address = rpcServer.getListenerAddress();
119 if (address == null) {
120 throw new IOException("Listener channel is closed");
121 }
122 BlockingRpcChannel channel = rpcClient.createBlockingRpcChannel(
123 ServerName.valueOf(address.getHostName(), address.getPort(),
124 System.currentTimeMillis()), clientUser, 1000);
125 TestDelayedRpcProtos.TestDelayedService.BlockingInterface stub =
126 TestDelayedRpcProtos.TestDelayedService.newBlockingStub(channel);
127 List<Integer> results = new ArrayList<Integer>();
128 TestThread th1 = new TestThread(stub, true, results);
129 th1.start();
130 Thread.sleep(100);
131 th1.join();
132
133 assertEquals(0xDEADBEEF, results.get(0).intValue());
134 } finally {
135 rpcClient.stop();
136 }
137 }
138
139 @Test
140 public void testRpcFallbackToSimpleAuth() throws Exception {
141 assumeTrue(isKerberosPropertySetted());
142 String krbKeytab = getKeytabFileForTesting();
143 String krbPrincipal = getPrincipalForTesting();
144
145 UserGroupInformation ugi = loginKerberosPrincipal(krbKeytab, krbPrincipal);
146 assertEquals(AuthenticationMethod.KERBEROS, ugi.getAuthenticationMethod());
147 assertEquals(krbPrincipal, ugi.getUserName());
148
149 String clientUsername = "testuser";
150 UserGroupInformation clientUgi = UserGroupInformation.createUserForTesting(clientUsername,
151 new String[]{clientUsername});
152
153
154 assertNotSame(ugi, clientUgi);
155 assertEquals(AuthenticationMethod.SIMPLE, clientUgi.getAuthenticationMethod());
156 assertEquals(clientUsername, clientUgi.getUserName());
157
158 Configuration clientConf = new Configuration();
159 clientConf.set(User.HBASE_SECURITY_CONF_KEY, "simple");
160 callRpcService(User.create(clientUgi), clientConf, true);
161 }
162 }