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}