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}