001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.security; 019 020import java.io.File; 021import java.security.Security; 022import java.util.ArrayList; 023import java.util.List; 024import java.util.stream.Stream; 025import org.apache.commons.io.FileUtils; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate; 028import org.apache.hadoop.hbase.io.crypto.tls.KeyStoreFileType; 029import org.apache.hadoop.hbase.io.crypto.tls.X509KeyType; 030import org.apache.hadoop.hbase.io.crypto.tls.X509TestContext; 031import org.apache.hadoop.hbase.io.crypto.tls.X509TestContextProvider; 032import org.apache.hadoop.hbase.io.crypto.tls.X509Util; 033import org.apache.hadoop.hbase.ipc.NettyRpcClient; 034import org.apache.hadoop.hbase.ipc.NettyRpcServer; 035import org.apache.hadoop.hbase.ipc.RpcClient; 036import org.apache.hadoop.hbase.ipc.RpcClientFactory; 037import org.apache.hadoop.hbase.ipc.RpcServer; 038import org.apache.hadoop.hbase.ipc.RpcServerFactory; 039import org.apache.hadoop.hbase.testclassification.LargeTests; 040import org.apache.hadoop.hbase.testclassification.SecurityTests; 041import org.bouncycastle.jce.provider.BouncyCastleProvider; 042import org.junit.jupiter.api.AfterAll; 043import org.junit.jupiter.api.AfterEach; 044import org.junit.jupiter.api.BeforeAll; 045import org.junit.jupiter.api.BeforeEach; 046import org.junit.jupiter.api.Tag; 047import org.junit.jupiter.params.provider.Arguments; 048 049@Tag(SecurityTests.TAG) 050@Tag(LargeTests.TAG) 051@HBaseParameterizedTestTemplate(name = "{index}: caKeyType={0}, certKeyType={1}, keyPassword={2}," 052 + " acceptPlainText={3}, clientTlsEnabled={4}") 053public class TestSaslTlsIPC extends AbstractTestSecureIPC { 054 055 private static X509TestContextProvider PROVIDER; 056 057 private X509KeyType caKeyType; 058 059 private X509KeyType certKeyType; 060 061 private char[] keyPassword; 062 063 private boolean acceptPlainText; 064 065 private boolean clientTlsEnabled; 066 067 public TestSaslTlsIPC(X509KeyType caKeyType, X509KeyType certKeyType, char[] keyPassword, 068 boolean acceptPlainText, boolean clientTlsEnabled) { 069 this.caKeyType = caKeyType; 070 this.certKeyType = certKeyType; 071 this.keyPassword = keyPassword; 072 this.acceptPlainText = acceptPlainText; 073 this.clientTlsEnabled = clientTlsEnabled; 074 } 075 076 private X509TestContext x509TestContext; 077 078 public static Stream<Arguments> parameters() { 079 List<Arguments> params = new ArrayList<>(); 080 for (X509KeyType caKeyType : X509KeyType.values()) { 081 for (X509KeyType certKeyType : X509KeyType.values()) { 082 for (char[] keyPassword : new char[][] { "".toCharArray(), "pa$$w0rd".toCharArray() }) { 083 // do not accept plain text 084 params.add(Arguments.of(caKeyType, certKeyType, keyPassword, false, true)); 085 // support plain text and client enables tls 086 params.add(Arguments.of(caKeyType, certKeyType, keyPassword, true, true)); 087 // support plain text and client disables tls 088 params.add(Arguments.of(caKeyType, certKeyType, keyPassword, true, false)); 089 } 090 } 091 } 092 return params.stream(); 093 } 094 095 @BeforeAll 096 public static void setUpBeforeClass() throws Exception { 097 Security.addProvider(new BouncyCastleProvider()); 098 File dir = new File(TEST_UTIL.getDataTestDir(TestSaslTlsIPC.class.getSimpleName()).toString()) 099 .getCanonicalFile(); 100 FileUtils.forceMkdir(dir); 101 initKDCAndConf(); 102 Configuration conf = TEST_UTIL.getConfiguration(); 103 // server must enable tls 104 conf.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_ENABLED, true); 105 // only netty support tls 106 conf.setClass(RpcClientFactory.CUSTOM_RPC_CLIENT_IMPL_CONF_KEY, NettyRpcClient.class, 107 RpcClient.class); 108 conf.setClass(RpcServerFactory.CUSTOM_RPC_SERVER_IMPL_CONF_KEY, NettyRpcServer.class, 109 RpcServer.class); 110 PROVIDER = new X509TestContextProvider(conf, dir); 111 } 112 113 @AfterAll 114 public static void tearDownAfterClass() throws InterruptedException { 115 stopKDC(); 116 Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME); 117 TEST_UTIL.cleanupTestDir(); 118 } 119 120 @BeforeEach 121 public void setUp() throws Exception { 122 x509TestContext = PROVIDER.get(caKeyType, certKeyType, keyPassword); 123 x509TestContext.setConfigurations(KeyStoreFileType.JKS, KeyStoreFileType.JKS); 124 Configuration conf = TEST_UTIL.getConfiguration(); 125 conf.setBoolean(X509Util.HBASE_SERVER_NETTY_TLS_SUPPORTPLAINTEXT, acceptPlainText); 126 conf.setBoolean(X509Util.HBASE_CLIENT_NETTY_TLS_ENABLED, clientTlsEnabled); 127 setUpPrincipalAndConf(); 128 } 129 130 @AfterEach 131 public void tearDown() { 132 x509TestContext.clearConfigurations(); 133 x509TestContext.getConf().unset(X509Util.TLS_CONFIG_OCSP); 134 x509TestContext.getConf().unset(X509Util.TLS_CONFIG_CLR); 135 x509TestContext.getConf().unset(X509Util.TLS_CONFIG_PROTOCOL); 136 System.clearProperty("com.sun.net.ssl.checkRevocation"); 137 System.clearProperty("com.sun.security.enableCRLDP"); 138 Security.setProperty("ocsp.enable", Boolean.FALSE.toString()); 139 Security.setProperty("com.sun.security.enableCRLDP", Boolean.FALSE.toString()); 140 } 141}