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