|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.security.jgss; |
|
|
|
import com.sun.security.auth.callback.TextCallbackHandler; |
|
import javax.security.auth.Subject; |
|
import javax.security.auth.kerberos.KerberosPrincipal; |
|
import javax.security.auth.kerberos.KerberosTicket; |
|
import javax.security.auth.kerberos.KerberosKey; |
|
import org.ietf.jgss.*; |
|
import sun.security.jgss.spi.GSSNameSpi; |
|
import sun.security.jgss.spi.GSSCredentialSpi; |
|
import sun.security.action.GetPropertyAction; |
|
import sun.security.jgss.krb5.Krb5NameElement; |
|
import sun.security.jgss.spnego.SpNegoCredElement; |
|
import java.util.Set; |
|
import java.util.HashSet; |
|
import java.util.Vector; |
|
import java.util.Iterator; |
|
import java.security.AccessController; |
|
import java.security.AccessControlContext; |
|
import java.security.PrivilegedExceptionAction; |
|
import java.security.PrivilegedActionException; |
|
import javax.security.auth.callback.CallbackHandler; |
|
import javax.security.auth.login.LoginContext; |
|
import javax.security.auth.login.LoginException; |
|
import sun.security.action.GetBooleanAction; |
|
|
|
|
|
|
|
|
|
*/ |
|
public class GSSUtil { |
|
|
|
public static final Oid GSS_KRB5_MECH_OID = |
|
GSSUtil.createOid("1.2.840.113554.1.2.2"); |
|
public static final Oid GSS_KRB5_MECH_OID2 = |
|
GSSUtil.createOid("1.3.5.1.5.2"); |
|
public static final Oid GSS_KRB5_MECH_OID_MS = |
|
GSSUtil.createOid("1.2.840.48018.1.2.2"); |
|
|
|
public static final Oid GSS_SPNEGO_MECH_OID = |
|
GSSUtil.createOid("1.3.6.1.5.5.2"); |
|
|
|
public static final Oid NT_GSS_KRB5_PRINCIPAL = |
|
GSSUtil.createOid("1.2.840.113554.1.2.2.1"); |
|
|
|
private static final String DEFAULT_HANDLER = |
|
"auth.login.defaultCallbackHandler"; |
|
|
|
static final boolean DEBUG; |
|
static { |
|
DEBUG = (AccessController.doPrivileged |
|
(new GetBooleanAction("sun.security.jgss.debug"))). |
|
booleanValue(); |
|
} |
|
|
|
static void debug(String message) { |
|
if (DEBUG) { |
|
assert(message != null); |
|
System.out.println(message); |
|
} |
|
} |
|
|
|
// NOTE: this method is only for creating Oid objects with |
|
// known to be valid <code>oidStr</code> given it ignores |
|
|
|
public static Oid createOid(String oidStr) { |
|
try { |
|
return new Oid(oidStr); |
|
} catch (GSSException e) { |
|
debug("Ignored invalid OID: " + oidStr); |
|
return null; |
|
} |
|
} |
|
|
|
public static boolean isSpNegoMech(Oid oid) { |
|
return (GSS_SPNEGO_MECH_OID.equals(oid)); |
|
} |
|
|
|
public static boolean isKerberosMech(Oid oid) { |
|
return (GSS_KRB5_MECH_OID.equals(oid) || |
|
GSS_KRB5_MECH_OID2.equals(oid) || |
|
GSS_KRB5_MECH_OID_MS.equals(oid)); |
|
|
|
} |
|
|
|
public static String getMechStr(Oid oid) { |
|
if (isSpNegoMech(oid)) { |
|
return "SPNEGO"; |
|
} else if (isKerberosMech(oid)) { |
|
return "Kerberos V5"; |
|
} else { |
|
return oid.toString(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static Subject getSubject(GSSName name, |
|
GSSCredential creds) { |
|
|
|
HashSet<Object> privCredentials = null; |
|
HashSet<Object> pubCredentials = new HashSet<Object>(); |
|
|
|
Set<GSSCredentialSpi> gssCredentials = null; |
|
|
|
Set<KerberosPrincipal> krb5Principals = |
|
new HashSet<KerberosPrincipal>(); |
|
|
|
if (name instanceof GSSNameImpl) { |
|
try { |
|
GSSNameSpi ne = ((GSSNameImpl) name).getElement |
|
(GSS_KRB5_MECH_OID); |
|
String krbName = ne.toString(); |
|
if (ne instanceof Krb5NameElement) { |
|
krbName = |
|
((Krb5NameElement) ne).getKrb5PrincipalName().getName(); |
|
} |
|
KerberosPrincipal krbPrinc = new KerberosPrincipal(krbName); |
|
krb5Principals.add(krbPrinc); |
|
} catch (GSSException ge) { |
|
debug("Skipped name " + name + " due to " + ge); |
|
} |
|
} |
|
|
|
if (creds instanceof GSSCredentialImpl) { |
|
gssCredentials = ((GSSCredentialImpl) creds).getElements(); |
|
privCredentials = new HashSet<Object>(gssCredentials.size()); |
|
populateCredentials(privCredentials, gssCredentials); |
|
} else { |
|
privCredentials = new HashSet<Object>(); |
|
} |
|
debug("Created Subject with the following"); |
|
debug("principals=" + krb5Principals); |
|
debug("public creds=" + pubCredentials); |
|
debug("private creds=" + privCredentials); |
|
|
|
return new Subject(false, krb5Principals, pubCredentials, |
|
privCredentials); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private static void populateCredentials(Set<Object> credentials, |
|
Set<?> gssCredentials) { |
|
|
|
Object cred; |
|
|
|
Iterator<?> elements = gssCredentials.iterator(); |
|
while (elements.hasNext()) { |
|
|
|
cred = elements.next(); |
|
|
|
|
|
if (cred instanceof SpNegoCredElement) { |
|
cred = ((SpNegoCredElement) cred).getInternalCred(); |
|
} |
|
|
|
if (cred instanceof KerberosTicket) { |
|
if (!cred.getClass().getName().equals |
|
("javax.security.auth.kerberos.KerberosTicket")) { |
|
KerberosTicket tempTkt = (KerberosTicket) cred; |
|
cred = new KerberosTicket(tempTkt.getEncoded(), |
|
tempTkt.getClient(), |
|
tempTkt.getServer(), |
|
tempTkt.getSessionKey().getEncoded(), |
|
tempTkt.getSessionKeyType(), |
|
tempTkt.getFlags(), |
|
tempTkt.getAuthTime(), |
|
tempTkt.getStartTime(), |
|
tempTkt.getEndTime(), |
|
tempTkt.getRenewTill(), |
|
tempTkt.getClientAddresses()); |
|
} |
|
credentials.add(cred); |
|
} else if (cred instanceof KerberosKey) { |
|
if (!cred.getClass().getName().equals |
|
("javax.security.auth.kerberos.KerberosKey")) { |
|
KerberosKey tempKey = (KerberosKey) cred; |
|
cred = new KerberosKey(tempKey.getPrincipal(), |
|
tempKey.getEncoded(), |
|
tempKey.getKeyType(), |
|
tempKey.getVersionNumber()); |
|
} |
|
credentials.add(cred); |
|
} else { |
|
|
|
debug("Skipped cred element: " + cred); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static Subject login(GSSCaller caller, Oid mech) throws LoginException { |
|
|
|
CallbackHandler cb = null; |
|
if (caller instanceof HttpCaller) { |
|
cb = new sun.net.www.protocol.http.spnego.NegotiateCallbackHandler( |
|
((HttpCaller)caller).info()); |
|
} else { |
|
String defaultHandler = |
|
java.security.Security.getProperty(DEFAULT_HANDLER); |
|
|
|
if ((defaultHandler != null) && (defaultHandler.length() != 0)) { |
|
cb = null; |
|
} else { |
|
cb = new TextCallbackHandler(); |
|
} |
|
} |
|
|
|
// New instance of LoginConfigImpl must be created for each login, |
|
// since the entry name is not passed as the first argument, but |
|
|
|
LoginContext lc = new LoginContext("", null, cb, |
|
new LoginConfigImpl(caller, mech)); |
|
lc.login(); |
|
return lc.getSubject(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean useSubjectCredsOnly(GSSCaller caller) { |
|
|
|
String propValue = GetPropertyAction.privilegedGetProperty( |
|
"javax.security.auth.useSubjectCredsOnly"); |
|
|
|
|
|
if (caller instanceof HttpCaller) { |
|
|
|
return "true".equalsIgnoreCase(propValue); |
|
} else { |
|
|
|
return !("false".equalsIgnoreCase(propValue)); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean useMSInterop() { |
|
|
|
|
|
|
|
*/ |
|
String propValue = AccessController.doPrivileged( |
|
new GetPropertyAction("sun.security.spnego.msinterop", |
|
"true")); |
|
|
|
|
|
|
|
*/ |
|
return (!propValue.equalsIgnoreCase("false")); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static <T extends GSSCredentialSpi> Vector<T> |
|
searchSubject(final GSSNameSpi name, |
|
final Oid mech, |
|
final boolean initiate, |
|
final Class<? extends T> credCls) { |
|
debug("Search Subject for " + getMechStr(mech) + |
|
(initiate? " INIT" : " ACCEPT") + " cred (" + |
|
(name == null? "<<DEF>>" : name.toString()) + ", " + |
|
credCls.getName() + ")"); |
|
final AccessControlContext acc = AccessController.getContext(); |
|
try { |
|
Vector<T> creds = |
|
AccessController.doPrivileged |
|
(new PrivilegedExceptionAction<Vector<T>>() { |
|
public Vector<T> run() throws Exception { |
|
Subject accSubj = Subject.getSubject(acc); |
|
Vector<T> result = null; |
|
if (accSubj != null) { |
|
result = new Vector<T>(); |
|
Iterator<GSSCredentialImpl> iterator = |
|
accSubj.getPrivateCredentials |
|
(GSSCredentialImpl.class).iterator(); |
|
while (iterator.hasNext()) { |
|
GSSCredentialImpl cred = iterator.next(); |
|
debug("...Found cred" + cred); |
|
try { |
|
GSSCredentialSpi ce = |
|
cred.getElement(mech, initiate); |
|
debug("......Found element: " + ce); |
|
if (ce.getClass().equals(credCls) && |
|
(name == null || |
|
name.equals((Object) ce.getName()))) { |
|
result.add(credCls.cast(ce)); |
|
} else { |
|
debug("......Discard element"); |
|
} |
|
} catch (GSSException ge) { |
|
debug("...Discard cred (" + ge + ")"); |
|
} |
|
} |
|
} else debug("No Subject"); |
|
return result; |
|
} |
|
}); |
|
return creds; |
|
} catch (PrivilegedActionException pae) { |
|
debug("Unexpected exception when searching Subject:"); |
|
if (DEBUG) pae.printStackTrace(); |
|
return null; |
|
} |
|
} |
|
} |