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