View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.security;
20  
21  import org.apache.commons.codec.binary.Base64;
22  import org.apache.hadoop.hbase.classification.InterfaceAudience;
23  
24  import java.util.Map;
25  import java.util.TreeMap;
26  
27  import javax.security.sasl.Sasl;
28  
29  import org.apache.commons.codec.binary.Base64;
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.apache.hadoop.hbase.classification.InterfaceAudience;
33  
34  @InterfaceAudience.Private
35  public class SaslUtil {
36    private static final Log log = LogFactory.getLog(SaslUtil.class);
37    public static final String SASL_DEFAULT_REALM = "default";
38    public static final int SWITCH_TO_SIMPLE_AUTH = -88;
39  
40    public enum QualityOfProtection {
41      AUTHENTICATION("auth"),
42      INTEGRITY("auth-int"),
43      PRIVACY("auth-conf");
44  
45      private final String saslQop;
46  
47      QualityOfProtection(String saslQop) {
48        this.saslQop = saslQop;
49      }
50  
51      public String getSaslQop() {
52        return saslQop;
53      }
54  
55      public boolean matches(String stringQop) {
56        if (saslQop.equals(stringQop)) {
57          log.warn("Use authentication/integrity/privacy as value for rpc protection "
58              + "configurations instead of auth/auth-int/auth-conf.");
59          return true;
60        }
61        return name().equalsIgnoreCase(stringQop);
62      }
63    }
64  
65    /** Splitting fully qualified Kerberos name into parts */
66    public static String[] splitKerberosName(String fullName) {
67      return fullName.split("[/@]");
68    }
69  
70    static String encodeIdentifier(byte[] identifier) {
71      return new String(Base64.encodeBase64(identifier));
72    }
73  
74    static byte[] decodeIdentifier(String identifier) {
75      return Base64.decodeBase64(identifier.getBytes());
76    }
77  
78    static char[] encodePassword(byte[] password) {
79      return new String(Base64.encodeBase64(password)).toCharArray();
80    }
81  
82    /**
83     * Returns {@link org.apache.hadoop.hbase.security.SaslUtil.QualityOfProtection}
84     * corresponding to the given {@code stringQop} value.
85     * @throws IllegalArgumentException If stringQop doesn't match any QOP.
86     */
87    public static QualityOfProtection getQop(String stringQop) {
88      for (QualityOfProtection qop : QualityOfProtection.values()) {
89        if (qop.matches(stringQop)) {
90          return qop;
91        }
92      }
93      throw new IllegalArgumentException("Invalid qop: " +  stringQop
94          + ". It must be one of 'authentication', 'integrity', 'privacy'.");
95    }
96  
97    /**
98     * @param rpcProtection Value of 'hbase.rpc.protection' configuration.
99     * @return Map with values for SASL properties.
100    */
101   static Map<String, String> initSaslProperties(String rpcProtection) {
102     String saslQop;
103     if (rpcProtection.isEmpty()) {
104       saslQop = QualityOfProtection.AUTHENTICATION.getSaslQop();
105     } else {
106       String[] qops = rpcProtection.split(",");
107       StringBuilder saslQopBuilder = new StringBuilder();
108       for (int i = 0; i < qops.length; ++i) {
109         QualityOfProtection qop = getQop(qops[i]);
110         saslQopBuilder.append(",").append(qop.getSaslQop());
111       }
112       saslQop = saslQopBuilder.substring(1);  // remove first ','
113     }
114     Map<String, String> saslProps = new TreeMap<>();
115     saslProps.put(Sasl.QOP, saslQop);
116     saslProps.put(Sasl.SERVER_AUTH, "true");
117     return saslProps;
118   }
119 }