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.security;
019
020import java.net.InetAddress;
021import java.util.Map;
022import java.util.TreeMap;
023
024import javax.security.sasl.Sasl;
025
026import org.apache.hadoop.conf.Configurable;
027import org.apache.hadoop.conf.Configuration;
028import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
029import org.apache.hadoop.security.SaslRpcServer.QualityOfProtection;
030import org.apache.hadoop.util.ReflectionUtils;
031import org.apache.hadoop.util.StringUtils;
032
033/**
034 * Provides SaslProperties to be used for a connection.
035 * The default implementation is to read the values from configuration.
036 * This class can be overridden to provide custom SaslProperties. 
037 * The custom class can be specified via configuration.
038 *
039 */
040public class SaslPropertiesResolver implements Configurable{
041  private Map<String,String> properties;
042  Configuration conf;
043
044  /**
045   * Returns an instance of SaslPropertiesResolver.
046   * Looks up the configuration to see if there is custom class specified.
047   * Constructs the instance by passing the configuration directly to the
048   * constructor to achieve thread safety using final fields.
049   * @param conf
050   * @return SaslPropertiesResolver
051   */
052  public static SaslPropertiesResolver getInstance(Configuration conf) {
053    Class<? extends SaslPropertiesResolver> clazz =
054      conf.getClass(
055          CommonConfigurationKeysPublic.HADOOP_SECURITY_SASL_PROPS_RESOLVER_CLASS,
056          SaslPropertiesResolver.class, SaslPropertiesResolver.class);
057    return ReflectionUtils.newInstance(clazz, conf);
058  }
059
060  @Override
061  public void setConf(Configuration conf) {
062    this.conf = conf;
063    properties = new TreeMap<String,String>();
064    String[] qop = conf.getTrimmedStrings(
065        CommonConfigurationKeysPublic.HADOOP_RPC_PROTECTION,
066        QualityOfProtection.AUTHENTICATION.toString());
067    for (int i=0; i < qop.length; i++) {
068      qop[i] = QualityOfProtection.valueOf(qop[i].toUpperCase()).getSaslQop();
069    }
070    properties.put(Sasl.QOP, StringUtils.join(",", qop));
071    properties.put(Sasl.SERVER_AUTH, "true");
072  }
073
074  @Override
075  public Configuration getConf() {
076    return conf;
077  }
078
079  /**
080   * The default Sasl Properties read from the configuration
081   * @return sasl Properties
082   */
083  public Map<String,String> getDefaultProperties() {
084    return properties;
085  }
086
087  /**
088   * Identify the Sasl Properties to be used for a connection with a  client.
089   * @param clientAddress client's address
090   * @return the sasl properties to be used for the connection.
091   */
092  public Map<String, String> getServerProperties(InetAddress clientAddress){
093    return properties;
094  }
095
096  /**
097   * Identify the Sasl Properties to be used for a connection with a server.
098   * @param serverAddress server's address
099   * @return the sasl properties to be used for the connection.
100   */
101  public Map<String, String> getClientProperties(InetAddress serverAddress){
102    return properties;
103  }
104}