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.ByteArrayInputStream; 021import java.io.DataInputStream; 022import java.io.IOException; 023import java.util.Map; 024import java.util.Optional; 025 026import javax.security.sasl.Sasl; 027import javax.security.sasl.SaslException; 028import javax.security.sasl.SaslServer; 029 030import org.apache.hadoop.hbase.security.provider.AttemptingUserProvidingSaslServer; 031import org.apache.hadoop.hbase.security.provider.SaslServerAuthenticationProvider; 032import org.apache.hadoop.security.UserGroupInformation; 033import org.apache.hadoop.security.token.SecretManager; 034import org.apache.hadoop.security.token.SecretManager.InvalidToken; 035import org.apache.hadoop.security.token.TokenIdentifier; 036import org.apache.yetus.audience.InterfaceAudience; 037 038/** 039 * A utility class that encapsulates SASL logic for RPC server. Copied from 040 * <code>org.apache.hadoop.security</code> 041 */ 042@InterfaceAudience.Private 043public class HBaseSaslRpcServer { 044 045 private final AttemptingUserProvidingSaslServer serverWithProvider; 046 private final SaslServer saslServer; 047 048 public HBaseSaslRpcServer(SaslServerAuthenticationProvider provider, 049 Map<String, String> saslProps, SecretManager<TokenIdentifier> secretManager) 050 throws IOException { 051 serverWithProvider = provider.createServer(secretManager, saslProps); 052 saslServer = serverWithProvider.getServer(); 053 } 054 055 public boolean isComplete() { 056 return saslServer.isComplete(); 057 } 058 059 public byte[] evaluateResponse(byte[] response) throws SaslException { 060 return saslServer.evaluateResponse(response); 061 } 062 063 /** Release resources used by wrapped saslServer */ 064 public void dispose() { 065 SaslUtil.safeDispose(saslServer); 066 } 067 068 public String getAttemptingUser() { 069 Optional<UserGroupInformation> optionalUser = serverWithProvider.getAttemptingUser(); 070 if (optionalUser.isPresent()) { 071 optionalUser.get().toString(); 072 } 073 return "Unknown"; 074 } 075 076 public byte[] wrap(byte[] buf, int off, int len) throws SaslException { 077 return saslServer.wrap(buf, off, len); 078 } 079 080 public byte[] unwrap(byte[] buf, int off, int len) throws SaslException { 081 return saslServer.unwrap(buf, off, len); 082 } 083 084 public String getNegotiatedQop() { 085 return (String) saslServer.getNegotiatedProperty(Sasl.QOP); 086 } 087 088 public String getAuthorizationID() { 089 return saslServer.getAuthorizationID(); 090 } 091 092 public static <T extends TokenIdentifier> T getIdentifier(String id, 093 SecretManager<T> secretManager) throws InvalidToken { 094 byte[] tokenId = SaslUtil.decodeIdentifier(id); 095 T tokenIdentifier = secretManager.createIdentifier(); 096 try { 097 tokenIdentifier.readFields(new DataInputStream(new ByteArrayInputStream(tokenId))); 098 } catch (IOException e) { 099 throw (InvalidToken) new InvalidToken("Can't de-serialize tokenIdentifier").initCause(e); 100 } 101 return tokenIdentifier; 102 } 103}