001package org.apache.hadoop.security.rpcauth; 002 003import java.io.DataOutput; 004import java.io.IOException; 005import java.util.Map; 006 007import javax.security.auth.callback.CallbackHandler; 008import javax.security.sasl.Sasl; 009import javax.security.sasl.SaslClient; 010import javax.security.sasl.SaslClientFactory; 011import javax.security.sasl.SaslException; 012 013import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; 014 015public class FakeKerberosAuthMethod extends RpcAuthMethod { 016 private static final String FAKE_SASL_MECH_NAME = "FAKE-SASL-MECHANISM"; 017 private static final byte KERBEROS_AUTH_CODE = 81; 018 019 static { 020 java.security.Security.addProvider(new FakeSaslProvider()); 021 } 022 023 static final RpcAuthMethod INSTANCE = new FakeKerberosAuthMethod(); 024 private FakeKerberosAuthMethod() { 025 super((byte) 0xff, "fake", FAKE_SASL_MECH_NAME, AuthenticationMethod.SIMPLE); 026 } 027 028 029 private static final String[] LOGIN_MODULES = { 030 "org.apache.hadoop.security.login.PermissiveLoginModule" 031 }; 032 @Override 033 public String[] loginModules() { 034 return LOGIN_MODULES; 035 } 036 037 /** Write to out. */ 038 @Override 039 public void write(DataOutput out) throws IOException { 040 out.write(KERBEROS_AUTH_CODE); 041 } 042 043 @Override 044 public boolean isSasl() { 045 return true; 046 } 047 048 @Override 049 public SaslClient createSaslClient(final Map<String, Object> saslProperties) 050 throws IOException { 051 return Sasl.createSaslClient(new String[] {mechanismName}, 052 null, null, null, saslProperties, null); 053 } 054 055 @SuppressWarnings("serial") 056 public static class FakeSaslProvider extends java.security.Provider { 057 public FakeSaslProvider() { 058 super("FakeSasl", 1.0, "Fake SASL provider"); 059 put("SaslClientFactory." + FAKE_SASL_MECH_NAME, FakeSaslClientFactory.class.getName()); 060 } 061 } 062 063 public static class FakeSaslClientFactory implements SaslClientFactory { 064 065 @Override 066 public String[] getMechanismNames(Map<String, ?> props) { 067 return new String[] { FAKE_SASL_MECH_NAME }; 068 } 069 070 @Override 071 public SaslClient createSaslClient(String[] mechanisms, 072 String authorizationId, String protocol, String serverName, 073 Map<String, ?> props, CallbackHandler cbh) throws SaslException { 074 if ( mechanisms != null ) { 075 for ( String mechanism : mechanisms ) { 076 if (FAKE_SASL_MECH_NAME.equals(mechanism)) { 077 return new FakeSaslClient(); 078 } 079 } 080 } 081 return null; 082 } 083 } 084 085 public static class FakeSaslClient implements SaslClient { 086 private boolean firstPass = true; 087 088 @Override 089 public String getMechanismName() { 090 return FAKE_SASL_MECH_NAME; 091 } 092 093 @Override 094 public boolean hasInitialResponse() { 095 return true; 096 } 097 098 private static final byte[] FAKE_TOKEN = {'F', 'A', 'K', 'E', 'T', 'O', 'K', 'E', 'N'}; 099 @Override 100 public byte[] evaluateChallenge(byte[] challenge) throws SaslException { 101 return FAKE_TOKEN; 102 } 103 104 @Override 105 public boolean isComplete() { 106 if (firstPass) { 107 firstPass = false; 108 return false; 109 } 110 return true; 111 } 112 113 @Override 114 public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException { 115 return null; 116 } 117 118 @Override 119 public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException { 120 return null; 121 } 122 123 @Override 124 public Object getNegotiatedProperty(String propName) { 125 return null; 126 } 127 128 @Override 129 public void dispose() throws SaslException { 130 } 131 } 132}