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.IOException; 021import java.net.InetAddress; 022import java.util.Map; 023 024import javax.security.sasl.SaslClient; 025import javax.security.sasl.SaslException; 026 027import org.apache.hadoop.conf.Configuration; 028import org.apache.hadoop.hbase.security.provider.SaslClientAuthenticationProvider; 029import org.apache.hadoop.security.token.Token; 030import org.apache.hadoop.security.token.TokenIdentifier; 031import org.apache.yetus.audience.InterfaceAudience; 032 033/** 034 * A utility class that encapsulates SASL logic for RPC client. Copied from 035 * <code>org.apache.hadoop.security</code> 036 * @since 2.0.0 037 */ 038@InterfaceAudience.Private 039public abstract class AbstractHBaseSaslRpcClient { 040 private static final byte[] EMPTY_TOKEN = new byte[0]; 041 042 protected final SaslClient saslClient; 043 044 protected final boolean fallbackAllowed; 045 046 protected final Map<String, String> saslProps; 047 048 /** 049 * Create a HBaseSaslRpcClient for an authentication method 050 * @param conf the configuration object 051 * @param provider the authentication provider 052 * @param token token to use if needed by the authentication method 053 * @param serverAddr the address of the hbase service 054 * @param securityInfo the security details for the remote hbase service 055 * @param fallbackAllowed does the client allow fallback to simple authentication 056 * @throws IOException 057 */ 058 protected AbstractHBaseSaslRpcClient(Configuration conf, 059 SaslClientAuthenticationProvider provider, Token<? extends TokenIdentifier> token, 060 InetAddress serverAddr, SecurityInfo securityInfo, boolean fallbackAllowed) 061 throws IOException { 062 this(conf, provider, token, serverAddr, securityInfo, fallbackAllowed, "authentication"); 063 } 064 065 /** 066 * Create a HBaseSaslRpcClient for an authentication method 067 * @param conf configuration object 068 * @param provider the authentication provider 069 * @param token token to use if needed by the authentication method 070 * @param serverAddr the address of the hbase service 071 * @param securityInfo the security details for the remote hbase service 072 * @param fallbackAllowed does the client allow fallback to simple authentication 073 * @param rpcProtection the protection level ("authentication", "integrity" or "privacy") 074 * @throws IOException 075 */ 076 protected AbstractHBaseSaslRpcClient(Configuration conf, 077 SaslClientAuthenticationProvider provider, Token<? extends TokenIdentifier> token, 078 InetAddress serverAddr, SecurityInfo securityInfo, boolean fallbackAllowed, 079 String rpcProtection) throws IOException { 080 this.fallbackAllowed = fallbackAllowed; 081 saslProps = SaslUtil.initSaslProperties(rpcProtection); 082 083 saslClient = provider.createClient( 084 conf, serverAddr, securityInfo, token, fallbackAllowed, saslProps); 085 if (saslClient == null) { 086 throw new IOException("Authentication provider " + provider.getClass() 087 + " returned a null SaslClient"); 088 } 089 } 090 091 public byte[] getInitialResponse() throws SaslException { 092 if (saslClient.hasInitialResponse()) { 093 return saslClient.evaluateChallenge(EMPTY_TOKEN); 094 } else { 095 return EMPTY_TOKEN; 096 } 097 } 098 099 public boolean isComplete() { 100 return saslClient.isComplete(); 101 } 102 103 public byte[] evaluateChallenge(byte[] challenge) throws SaslException { 104 return saslClient.evaluateChallenge(challenge); 105 } 106 107 /** Release resources used by wrapped saslClient */ 108 public void dispose() { 109 SaslUtil.safeDispose(saslClient); 110 } 111}