|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
/* |
|
* |
|
* (C) Copyright IBM Corp. 1999 All Rights Reserved. |
|
* Copyright 1997 The Open Group Research Institute. All rights reserved. |
|
*/ |
|
|
|
package sun.security.krb5; |
|
|
|
import sun.security.krb5.internal.*; |
|
import sun.security.krb5.internal.ccache.CredentialsCache; |
|
import sun.security.krb5.internal.crypto.EType; |
|
import java.io.IOException; |
|
import java.util.Date; |
|
import java.util.Locale; |
|
import java.net.InetAddress; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public class Credentials { |
|
|
|
Ticket ticket; |
|
PrincipalName client; |
|
PrincipalName clientAlias; |
|
PrincipalName server; |
|
PrincipalName serverAlias; |
|
EncryptionKey key; |
|
TicketFlags flags; |
|
KerberosTime authTime; |
|
KerberosTime startTime; |
|
KerberosTime endTime; |
|
KerberosTime renewTill; |
|
HostAddresses cAddr; |
|
AuthorizationData authzData; |
|
private static boolean DEBUG = Krb5.DEBUG; |
|
private static CredentialsCache cache; |
|
static boolean alreadyLoaded = false; |
|
private static boolean alreadyTried = false; |
|
|
|
private Credentials proxy = null; |
|
|
|
public Credentials getProxy() { |
|
return proxy; |
|
} |
|
|
|
public Credentials setProxy(Credentials proxy) { |
|
this.proxy = proxy; |
|
return this; |
|
} |
|
|
|
|
|
private static native Credentials acquireDefaultNativeCreds(int[] eTypes); |
|
|
|
public Credentials(Ticket new_ticket, |
|
PrincipalName new_client, |
|
PrincipalName new_client_alias, |
|
PrincipalName new_server, |
|
PrincipalName new_server_alias, |
|
EncryptionKey new_key, |
|
TicketFlags new_flags, |
|
KerberosTime authTime, |
|
KerberosTime new_startTime, |
|
KerberosTime new_endTime, |
|
KerberosTime renewTill, |
|
HostAddresses cAddr, |
|
AuthorizationData authzData) { |
|
this(new_ticket, new_client, new_client_alias, new_server, |
|
new_server_alias, new_key, new_flags, authTime, |
|
new_startTime, new_endTime, renewTill, cAddr); |
|
this.authzData = authzData; |
|
} |
|
|
|
public Credentials(Ticket new_ticket, |
|
PrincipalName new_client, |
|
PrincipalName new_client_alias, |
|
PrincipalName new_server, |
|
PrincipalName new_server_alias, |
|
EncryptionKey new_key, |
|
TicketFlags new_flags, |
|
KerberosTime authTime, |
|
KerberosTime new_startTime, |
|
KerberosTime new_endTime, |
|
KerberosTime renewTill, |
|
HostAddresses cAddr) { |
|
ticket = new_ticket; |
|
client = new_client; |
|
clientAlias = new_client_alias; |
|
server = new_server; |
|
serverAlias = new_server_alias; |
|
key = new_key; |
|
flags = new_flags; |
|
this.authTime = authTime; |
|
startTime = new_startTime; |
|
endTime = new_endTime; |
|
this.renewTill = renewTill; |
|
this.cAddr = cAddr; |
|
} |
|
|
|
public Credentials(byte[] encoding, |
|
String client, |
|
String clientAlias, |
|
String server, |
|
String serverAlias, |
|
byte[] keyBytes, |
|
int keyType, |
|
boolean[] flags, |
|
Date authTime, |
|
Date startTime, |
|
Date endTime, |
|
Date renewTill, |
|
InetAddress[] cAddrs) throws KrbException, IOException { |
|
this(new Ticket(encoding), |
|
new PrincipalName(client, PrincipalName.KRB_NT_PRINCIPAL), |
|
(clientAlias == null? null : new PrincipalName(clientAlias, |
|
PrincipalName.KRB_NT_PRINCIPAL)), |
|
new PrincipalName(server, PrincipalName.KRB_NT_SRV_INST), |
|
(serverAlias == null? null : new PrincipalName(serverAlias, |
|
PrincipalName.KRB_NT_SRV_INST)), |
|
new EncryptionKey(keyType, keyBytes), |
|
(flags == null? null: new TicketFlags(flags)), |
|
(authTime == null? null: new KerberosTime(authTime)), |
|
(startTime == null? null: new KerberosTime(startTime)), |
|
(endTime == null? null: new KerberosTime(endTime)), |
|
(renewTill == null? null: new KerberosTime(renewTill)), |
|
null); |
|
} |
|
|
|
/** |
|
* Acquires a service ticket for the specified service |
|
* principal. If the service ticket is not already available, it |
|
* obtains a new one from the KDC. |
|
*/ |
|
/* |
|
public Credentials(Credentials tgt, PrincipalName service) |
|
throws KrbException { |
|
} |
|
*/ |
|
|
|
public final PrincipalName getClient() { |
|
return client; |
|
} |
|
|
|
public final PrincipalName getClientAlias() { |
|
return clientAlias; |
|
} |
|
|
|
public final PrincipalName getServer() { |
|
return server; |
|
} |
|
|
|
public final PrincipalName getServerAlias() { |
|
return serverAlias; |
|
} |
|
|
|
public final EncryptionKey getSessionKey() { |
|
return key; |
|
} |
|
|
|
public final Date getAuthTime() { |
|
if (authTime != null) { |
|
return authTime.toDate(); |
|
} else { |
|
return null; |
|
} |
|
} |
|
|
|
public final Date getStartTime() { |
|
if (startTime != null) |
|
{ |
|
return startTime.toDate(); |
|
} |
|
return null; |
|
} |
|
|
|
public final Date getEndTime() { |
|
if (endTime != null) |
|
{ |
|
return endTime.toDate(); |
|
} |
|
return null; |
|
} |
|
|
|
public final Date getRenewTill() { |
|
if (renewTill != null) |
|
{ |
|
return renewTill.toDate(); |
|
} |
|
return null; |
|
} |
|
|
|
public final boolean[] getFlags() { |
|
if (flags == null) |
|
return null; |
|
return flags.toBooleanArray(); |
|
} |
|
|
|
public final InetAddress[] getClientAddresses() { |
|
|
|
if (cAddr == null) |
|
return null; |
|
|
|
return cAddr.getInetAddresses(); |
|
} |
|
|
|
public final byte[] getEncoded() { |
|
byte[] retVal = null; |
|
try { |
|
retVal = ticket.asn1Encode(); |
|
} catch (Asn1Exception e) { |
|
if (DEBUG) |
|
System.out.println(e); |
|
} catch (IOException ioe) { |
|
if (DEBUG) |
|
System.out.println(ioe); |
|
} |
|
return retVal; |
|
} |
|
|
|
public boolean isForwardable() { |
|
return flags.get(Krb5.TKT_OPTS_FORWARDABLE); |
|
} |
|
|
|
public boolean isRenewable() { |
|
return flags.get(Krb5.TKT_OPTS_RENEWABLE); |
|
} |
|
|
|
public Ticket getTicket() { |
|
return ticket; |
|
} |
|
|
|
public TicketFlags getTicketFlags() { |
|
return flags; |
|
} |
|
|
|
public AuthorizationData getAuthzData() { |
|
return authzData; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean checkDelegate() { |
|
return flags.get(Krb5.TKT_OPTS_DELEGATE); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void resetDelegate() { |
|
flags.set(Krb5.TKT_OPTS_DELEGATE, false); |
|
} |
|
|
|
public Credentials renew() throws KrbException, IOException { |
|
KDCOptions options = new KDCOptions(); |
|
options.set(KDCOptions.RENEW, true); |
|
|
|
|
|
*/ |
|
options.set(KDCOptions.RENEWABLE, true); |
|
|
|
return new KrbTgsReq(options, |
|
this, |
|
server, |
|
serverAlias, |
|
null, |
|
null, |
|
null, |
|
null, |
|
cAddr, |
|
null, |
|
null, |
|
null).sendAndGetCreds(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static Credentials acquireTGTFromCache(PrincipalName princ, |
|
String ticketCache) |
|
throws KrbException, IOException { |
|
|
|
if (ticketCache == null) { |
|
|
|
String os = java.security.AccessController.doPrivileged( |
|
new sun.security.action.GetPropertyAction("os.name")); |
|
if (os.toUpperCase(Locale.ENGLISH).startsWith("WINDOWS") || |
|
os.toUpperCase(Locale.ENGLISH).contains("OS X")) { |
|
Credentials creds = acquireDefaultCreds(); |
|
if (creds == null) { |
|
if (DEBUG) { |
|
System.out.println(">>> Found no TGT's in LSA"); |
|
} |
|
return null; |
|
} |
|
if (princ != null) { |
|
if (creds.getClient().equals(princ)) { |
|
if (DEBUG) { |
|
System.out.println(">>> Obtained TGT from LSA: " |
|
+ creds); |
|
} |
|
return creds; |
|
} else { |
|
if (DEBUG) { |
|
System.out.println(">>> LSA contains TGT for " |
|
+ creds.getClient() |
|
+ " not " |
|
+ princ); |
|
} |
|
return null; |
|
} |
|
} else { |
|
if (DEBUG) { |
|
System.out.println(">>> Obtained TGT from LSA: " |
|
+ creds); |
|
} |
|
return creds; |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
CredentialsCache ccache = |
|
CredentialsCache.getInstance(princ, ticketCache); |
|
|
|
if (ccache == null) { |
|
return null; |
|
} |
|
|
|
Credentials tgtCred = ccache.getInitialCreds(); |
|
|
|
if (tgtCred == null) { |
|
return null; |
|
} |
|
|
|
if (EType.isSupported(tgtCred.key.getEType())) { |
|
return tgtCred; |
|
} else { |
|
if (DEBUG) { |
|
System.out.println( |
|
">>> unsupported key type found the default TGT: " + |
|
tgtCred.key.getEType()); |
|
} |
|
return null; |
|
} |
|
} |
|
|
|
/** |
|
* Acquires default credentials. |
|
* <br>The possible locations for default credentials cache is searched in |
|
* the following order: |
|
* <ol> |
|
* <li> The directory and cache file name specified by "KRB5CCNAME" system. |
|
* property. |
|
* <li> The directory and cache file name specified by "KRB5CCNAME" |
|
* environment variable. |
|
* <li> A cache file named krb5cc_{user.name} at {user.home} directory. |
|
* </ol> |
|
* @return a <code>KrbCreds</code> object if the credential is found, |
|
* otherwise return null. |
|
*/ |
|
|
|
// this method is intentionally changed to not check if the caller's |
|
// principal name matches cache file's principal name. |
|
// It assumes that the GSS call has |
|
// the privilege to access the default cache file. |
|
|
|
// This method is only called on Windows and Mac OS X, the native |
|
|
|
public static synchronized Credentials acquireDefaultCreds() { |
|
Credentials result = null; |
|
|
|
if (cache == null) { |
|
cache = CredentialsCache.getInstance(); |
|
} |
|
if (cache != null) { |
|
Credentials temp = cache.getInitialCreds(); |
|
if (temp != null) { |
|
if (DEBUG) { |
|
System.out.println(">>> KrbCreds found the default ticket" |
|
+ " granting ticket in credential cache."); |
|
} |
|
if (EType.isSupported(temp.key.getEType())) { |
|
result = temp; |
|
} else { |
|
if (DEBUG) { |
|
System.out.println( |
|
">>> unsupported key type found the default TGT: " + |
|
temp.key.getEType()); |
|
} |
|
} |
|
} |
|
} |
|
if (result == null) { |
|
// Doesn't seem to be a default cache on this system or |
|
// TGT has unsupported encryption type |
|
|
|
if (!alreadyTried) { |
|
|
|
try { |
|
ensureLoaded(); |
|
} catch (Exception e) { |
|
if (DEBUG) { |
|
System.out.println("Can not load credentials cache"); |
|
e.printStackTrace(); |
|
} |
|
alreadyTried = true; |
|
} |
|
} |
|
if (alreadyLoaded) { |
|
|
|
if (DEBUG) { |
|
System.out.println(">> Acquire default native Credentials"); |
|
} |
|
try { |
|
result = acquireDefaultNativeCreds( |
|
EType.getDefaults("default_tkt_enctypes")); |
|
} catch (KrbException ke) { |
|
// when there is no default_tkt_enctypes. |
|
} |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Acquires credentials for a specified service using initial credential. |
|
* When the service has a different realm |
|
* from the initial credential, we do cross-realm authentication |
|
* - first, we use the current credential to get |
|
* a cross-realm credential from the local KDC, then use that |
|
* cross-realm credential to request service credential |
|
* from the foreigh KDC. |
|
* |
|
* @param service the name of service principal using format |
|
* components@realm |
|
* @param ccreds client's initial credential. |
|
* @exception IOException if an error occurs in reading the credentials |
|
* cache |
|
* @exception KrbException if an error occurs specific to Kerberos |
|
* @return a <code>Credentials</code> object. |
|
*/ |
|
|
|
public static Credentials acquireServiceCreds(String service, |
|
Credentials ccreds) |
|
throws KrbException, IOException { |
|
return CredentialsUtil.acquireServiceCreds(service, ccreds); |
|
} |
|
|
|
public static Credentials acquireS4U2selfCreds(PrincipalName user, |
|
Credentials ccreds) throws KrbException, IOException { |
|
return CredentialsUtil.acquireS4U2selfCreds(user, ccreds); |
|
} |
|
|
|
public static Credentials acquireS4U2proxyCreds(String service, |
|
Ticket second, PrincipalName client, Credentials ccreds) |
|
throws KrbException, IOException { |
|
return CredentialsUtil.acquireS4U2proxyCreds( |
|
service, second, client, ccreds); |
|
} |
|
|
|
public CredentialsCache getCache() { |
|
return cache; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public static void printDebug(Credentials c) { |
|
System.out.println(">>> DEBUG: ----Credentials----"); |
|
System.out.println("\tclient: " + c.client.toString()); |
|
if (c.clientAlias != null) |
|
System.out.println("\tclient alias: " + c.clientAlias.toString()); |
|
System.out.println("\tserver: " + c.server.toString()); |
|
if (c.serverAlias != null) |
|
System.out.println("\tserver alias: " + c.serverAlias.toString()); |
|
System.out.println("\tticket: sname: " + c.ticket.sname.toString()); |
|
if (c.startTime != null) { |
|
System.out.println("\tstartTime: " + c.startTime.getTime()); |
|
} |
|
System.out.println("\tendTime: " + c.endTime.getTime()); |
|
System.out.println(" ----Credentials end----"); |
|
} |
|
|
|
|
|
static void ensureLoaded() { |
|
java.security.AccessController.doPrivileged( |
|
new java.security.PrivilegedAction<Void> () { |
|
public Void run() { |
|
if (System.getProperty("os.name").contains("OS X")) { |
|
System.loadLibrary("osxkrb5"); |
|
} else { |
|
System.loadLibrary("w2k_lsa_auth"); |
|
} |
|
return null; |
|
} |
|
}); |
|
alreadyLoaded = true; |
|
} |
|
|
|
public String toString() { |
|
StringBuffer buffer = new StringBuffer("Credentials:"); |
|
buffer.append( "\n client=").append(client); |
|
if (clientAlias != null) |
|
buffer.append( "\n clientAlias=").append(clientAlias); |
|
buffer.append( "\n server=").append(server); |
|
if (serverAlias != null) |
|
buffer.append( "\n serverAlias=").append(serverAlias); |
|
if (authTime != null) { |
|
buffer.append("\n authTime=").append(authTime); |
|
} |
|
if (startTime != null) { |
|
buffer.append("\n startTime=").append(startTime); |
|
} |
|
buffer.append( "\n endTime=").append(endTime); |
|
buffer.append( "\n renewTill=").append(renewTill); |
|
buffer.append( "\n flags=").append(flags); |
|
buffer.append( "\nEType (skey)=").append(key.getEType()); |
|
buffer.append( "\n (tkt key)=").append(ticket.encPart.eType); |
|
return buffer.toString(); |
|
} |
|
|
|
public sun.security.krb5.internal.ccache.Credentials toCCacheCreds() { |
|
return new sun.security.krb5.internal.ccache.Credentials( |
|
getClient(), getServer(), |
|
getSessionKey(), |
|
date2kt(getAuthTime()), |
|
date2kt(getStartTime()), |
|
date2kt(getEndTime()), |
|
date2kt(getRenewTill()), |
|
false, |
|
flags, |
|
new HostAddresses(getClientAddresses()), |
|
getAuthzData(), |
|
getTicket(), |
|
null); |
|
} |
|
|
|
private static KerberosTime date2kt(Date d) { |
|
return d == null ? null : new KerberosTime(d); |
|
} |
|
} |