001package org.apache.hadoop.security.rpcauth; 002 003import java.io.DataInput; 004import java.io.IOException; 005import java.util.ArrayList; 006import java.util.LinkedHashMap; 007import java.util.List; 008import java.util.Map; 009 010import org.apache.commons.logging.Log; 011import org.apache.commons.logging.LogFactory; 012import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; 013 014public class RpcAuthRegistry { 015 private static final Log LOG = 016 LogFactory.getLog(RpcAuthRegistry.class); 017 private static final Map<Byte, RpcAuthMethod> authMethods = 018 new LinkedHashMap<Byte, RpcAuthMethod>(); 019 private static final Map<String, RpcAuthMethod> loginModuleMap = 020 new LinkedHashMap<String, RpcAuthMethod>(); 021 022 /** 023 * Pre-defined authentication methods 024 */ 025 public static final RpcAuthMethod KERBEROS = KerberosAuthMethod.INSTANCE; 026 public static final RpcAuthMethod FAKE_KERBEROS = FakeKerberosAuthMethod.INSTANCE; 027 public static final RpcAuthMethod SIMPLE = SimpleAuthMethod.INSTANCE; 028 public static final RpcAuthMethod DIGEST = DigestAuthMethod.INSTANCE; 029 030 static { 031 addRpcAuthMethod(SIMPLE); 032 addRpcAuthMethod(KERBEROS); 033 addRpcAuthMethod(DIGEST); 034 addRpcAuthMethod(FAKE_KERBEROS); 035 } 036 037 public synchronized static void addRpcAuthMethod(RpcAuthMethod authMethod) { 038 if (authMethods.containsKey(authMethod.authcode)) { 039 RpcAuthMethod oldMethod = authMethods.get(authMethod.authcode); 040 if (!oldMethod.getClass().equals(authMethod.getClass())) { 041 throw new IllegalArgumentException( 042 String.format("Duplicate authcode [%d] for '%s'. Already registerd for '%s'.", 043 authMethod.authcode, 044 authMethod.getClass().getCanonicalName(), 045 oldMethod.getClass().getCanonicalName() 046 )); 047 } 048 } 049 050 for (String module : authMethod.loginModules()) { 051 if (loginModuleMap.containsKey(module)) { 052 RpcAuthMethod oldMethod = loginModuleMap.get(module); 053 if (!oldMethod.getClass().equals(authMethod.getClass())) { 054 throw new IllegalArgumentException( 055 String.format("Duplicate login module [%s] for '%s'. Already registerd for '%s'.", 056 module, 057 authMethod.getClass().getCanonicalName(), 058 oldMethod.getClass().getCanonicalName() 059 )); 060 } 061 } 062 loginModuleMap.put(module, authMethod); 063 } 064 authMethods.put(authMethod.authcode, authMethod); 065 if (LOG.isDebugEnabled()) { 066 LOG.debug("Added " + authMethod + " to registry."); 067 } 068 } 069 070 /** Return the RpcAuthMethod for given JAAS login module */ 071 public static RpcAuthMethod getAuthMethodForLoginModule(String loginModule) { 072 return loginModuleMap.get(loginModule); 073 } 074 075 /** Return the RpcAuthMethod for given auth code */ 076 public static RpcAuthMethod getAuthMethod(byte authCode) { 077 return authMethods.get(authCode); 078 } 079 080 public static RpcAuthMethod getAuthMethod(String name) { 081 for (RpcAuthMethod method : authMethods.values()) { 082 if (method.simpleName.equalsIgnoreCase(name)) { 083 return method; 084 } 085 } 086 LOG.warn("No RpcAuthMethod registerd for name " + name); 087 return null; 088 } 089 090 public static RpcAuthMethod getAuthMethod(AuthenticationMethod authenticationMethod) { 091 for (RpcAuthMethod method : authMethods.values()) { 092 if (method.authenticationMethod.equals(authenticationMethod)) { 093 return method; 094 } 095 } 096 LOG.warn("No RpcAuthMethod registerd for authentication method " + authenticationMethod); 097 return null; 098 } 099 100 /** Read from in. */ 101 @Deprecated 102 public static RpcAuthMethod readAuthMethod(DataInput in) throws IOException { 103 byte code = in.readByte(); 104 if (!authMethods.containsKey(code)) { 105 LOG.warn("No RpcAuthMethod registerd for auth code " + code); 106 } 107 return authMethods.get(code); 108 } 109 110 /** 111 * Return the ordered list of auth method for given comma separated names. 112 * To be used for logging purpose only. 113 */ 114 @Deprecated 115 public static List<RpcAuthMethod> getAuthMethodList(byte[] authCodes) { 116 List<RpcAuthMethod> list = new ArrayList<RpcAuthMethod>(); 117 for (byte code : authCodes) { 118 RpcAuthMethod method = authMethods.get(code); 119 if (method == null) { 120 String name = "UNKNOWN(" + code + ")"; 121 method = new RpcAuthMethod(code, name, name, null) {}; 122 } 123 list.add(method); 124 } 125 return list; 126 } 127 128}