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.rpcauth;
020
021import java.io.DataOutput;
022import java.io.IOException;
023import java.util.Map;
024
025import javax.security.sasl.SaslClient;
026import javax.security.sasl.SaslServer;
027
028import org.apache.hadoop.ipc.Server;
029import org.apache.hadoop.ipc.protobuf.IpcConnectionContextProtos.UserInformationProto.Builder;
030import org.apache.hadoop.security.AccessControlException;
031import org.apache.hadoop.security.UserGroupInformation;
032import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
033import org.apache.hadoop.security.token.SecretManager;
034import javax.security.auth.callback.CallbackHandler;
035
036public abstract class RpcAuthMethod {
037  private static final String[] LOGIN_MODULES = new String[0];
038
039  @Deprecated
040  protected final byte authcode;
041  protected final String simpleName;
042  protected final String mechanismName;
043  protected final AuthenticationMethod authenticationMethod;
044
045  protected RpcAuthMethod(byte code, String simpleName,
046      String mechanismName, AuthenticationMethod authMethod) {
047    this.authcode = code;
048    this.simpleName = simpleName;
049    this.mechanismName = mechanismName;
050    this.authenticationMethod = authMethod;
051  }
052
053  @Deprecated
054  public byte getAuthCode() {
055    return authcode;
056  }
057
058  /** Return the SASL mechanism name */
059  public String getMechanismName() {
060    return mechanismName;
061  }
062
063  public AuthenticationMethod getAuthenticationMethod() {
064    return authenticationMethod;
065  }
066
067  public CallbackHandler createCallbackHandler() {
068    throw new UnsupportedOperationException(
069        this.getClass().getCanonicalName() + " does not support createCallbackHandler()");
070  }
071
072  @Override
073  public final int hashCode() {
074    return getClass().getName().hashCode();
075  }
076
077  @Override
078  public final boolean equals(Object that) {
079    if (this == that) {
080      return true;
081    }
082    if (that instanceof RpcAuthMethod) {
083      RpcAuthMethod other = (RpcAuthMethod)that;
084      getClass().getName().equals(other.getClass().getName());
085    }
086    return false;
087  }
088
089  public String[] loginModules() {
090    return RpcAuthMethod.LOGIN_MODULES;
091  }
092
093  /** Write to out. */
094  public void write(DataOutput out) throws IOException {
095    out.write(authcode);
096  }
097
098  public UserGroupInformation getUser(UserGroupInformation ticket) {
099    return ticket;
100  }
101
102  public void writeUGI(UserGroupInformation ugi, Builder ugiProto) {
103    // default, do-nothing implementation
104  }
105
106  public UserGroupInformation getAuthorizedUgi(String authorizedId,
107      SecretManager secretManager) throws IOException {
108    return UserGroupInformation.createRemoteUser(authorizedId);
109  }
110
111  public boolean shouldReLogin() throws IOException {
112    return false;
113  }
114
115  /** does nothing */
116  public void reLogin() throws IOException {
117  }
118
119  public boolean isProxyAllowed() {
120    return true;
121  }
122
123  @Override
124  public String toString() {
125    return simpleName.toUpperCase();
126  }
127
128  /** {@code false} by default */
129  public boolean isNegotiable() {
130    return false;
131  }
132
133  /** {@code false} by default */
134  public boolean isSasl() {
135    return false;
136  }
137
138  public String getProtocol() throws IOException {
139      throw new AccessControlException("Server does not support SASL " + this.simpleName.toUpperCase());
140  }
141
142  public String getServerId() throws IOException {
143    throw new AccessControlException("Server does not support SASL " + this.simpleName.toUpperCase());
144  }
145
146  /**
147   * Implementors which uses SASL authentication must return {@code true}
148   * for {@link #isSasl() isSasl()} method and return and instance of
149   * {@link javax.security.sasl.SaslClient}.
150   * @throws IOException
151   */
152  public SaslClient createSaslClient(final Map<String, Object> saslProperties)
153      throws IOException {
154    throw new UnsupportedOperationException(
155        this.getClass().getCanonicalName() + " does not support createSaslClient()");
156  }
157
158  /**
159   * Implementors which uses SASL authentication must return {@code true}
160   * for {@link #isSasl() isSasl()} method and return and instance of
161   * {@link javax.security.sasl.SaslServer}.
162   * @param connection
163   * @throws IOException
164   * @throws InterruptedException
165   */
166  public SaslServer createSaslServer(Server.Connection connection,
167      final Map<String, Object> saslProperties)
168      throws IOException, InterruptedException {
169    throw new UnsupportedOperationException(
170        this.getClass().getCanonicalName() + " does not support createSaslServer()");
171  }
172
173}