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