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 */
018
019package org.apache.hadoop.security.alias;
020
021import java.io.IOException;
022import java.util.List;
023
024import org.apache.hadoop.classification.InterfaceAudience;
025import org.apache.hadoop.classification.InterfaceStability;
026
027/**
028 * A provider of credentials or password for Hadoop applications. Provides an
029 * abstraction to separate credential storage from users of them. It
030 * is intended to support getting or storing passwords in a variety of ways,
031 * including third party bindings.
032 * 
033 * <code>CredentialProvider</code> implementations must be thread safe.
034 */
035@InterfaceAudience.Public
036@InterfaceStability.Unstable
037public abstract class CredentialProvider {
038  public static final String CLEAR_TEXT_FALLBACK 
039      = "hadoop.security.credential.clear-text-fallback";
040
041  /**
042   * The combination of both the alias and the actual credential value.
043   */
044  public static class CredentialEntry {
045    private final String alias;
046    private final char[] credential;
047
048    protected CredentialEntry(String alias,
049                         char[] credential) {
050      this.alias = alias;
051      this.credential = credential;
052    }
053
054    public String getAlias() {
055      return alias;
056    }
057
058    public char[] getCredential() {
059      return credential;
060    }
061
062    public String toString() {
063      StringBuilder buf = new StringBuilder();
064      buf.append("alias(");
065      buf.append(alias);
066      buf.append(")=");
067      if (credential == null) {
068        buf.append("null");
069      } else {
070        for(char c: credential) {
071          buf.append(c);
072        }
073      }
074      return buf.toString();
075    }
076  }
077
078  /**
079   * Indicates whether this provider represents a store
080   * that is intended for transient use - such as the UserProvider
081   * is. These providers are generally used to provide job access to
082   * passwords rather than for long term storage.
083   * @return true if transient, false otherwise
084   */
085  public boolean isTransient() {
086    return false;
087  }
088
089  /**
090   * Ensures that any changes to the credentials are written to persistent
091   * store.
092   * @throws IOException
093   */
094  public abstract void flush() throws IOException;
095
096  /**
097   * Get the credential entry for a specific alias.
098   * @param alias the name of a specific credential
099   * @return the credentialEntry
100   * @throws IOException
101   */
102  public abstract CredentialEntry getCredentialEntry(String alias) 
103      throws IOException;
104
105  /**
106   * Get the aliases for all credentials.
107   * @return the list of alias names
108   * @throws IOException
109   */
110  public abstract List<String> getAliases() throws IOException;
111
112  /**
113   * Create a new credential. The given alias must not already exist.
114   * @param name the alias of the credential
115   * @param credential the credential value for the alias.
116   * @throws IOException
117   */
118  public abstract CredentialEntry createCredentialEntry(String name, 
119      char[] credential) throws IOException;
120
121  /**
122   * Delete the given credential.
123   * @param name the alias of the credential to delete
124   * @throws IOException
125   */
126  public abstract void deleteCredentialEntry(String name) throws IOException;
127
128  /**
129   * Does this provider require a password? This means that a password is
130   * required for normal operation, and it has not been found through normal
131   * means. If true, the password should be provided by the caller using
132   * setPassword().
133   * @return Whether or not the provider requires a password
134   * @throws IOException
135   */
136  public boolean needsPassword() throws IOException {
137    return false;
138  }
139
140  /**
141   * If a password for the provider is needed, but is not provided, this will
142   * return a warning and instructions for supplying said password to the
143   * provider.
144   * @return A warning and instructions for supplying the password
145   */
146  public String noPasswordWarning() {
147    return null;
148  }
149
150  /**
151   * If a password for the provider is needed, but is not provided, this will
152   * return an error message and instructions for supplying said password to
153   * the provider.
154   * @return An error message and instructions for supplying the password
155   */
156  public String noPasswordError() {
157    return null;
158  }
159}