This class encapsulates a Kerberos ticket and associated
information as viewed from the client's point of view. It captures all
information that the Key Distribution Center (KDC) sends to the client
in the reply message KDC-REP defined in the Kerberos Protocol
Specification (
).
All Kerberos JAAS login modules that authenticate a user to a KDC should
use this class. Where available, the login module might even read this
information from a ticket cache in the operating system instead of
directly communicating with the KDC. During the commit phase of the JAAS
authentication process, the JAAS login module should instantiate this
class and store the instance in the private credential set of a
Subject .
Note that this class is applicable to both ticket granting tickets and
other regular service tickets. A ticket granting ticket is just a
special case of a more generalized service ticket.
Constructor: |
public KerberosTicket(byte[] asn1Encoding,
KerberosPrincipal client,
KerberosPrincipal server,
byte[] sessionKey,
int keyType,
boolean[] flags,
Date authTime,
Date startTime,
Date endTime,
Date renewTill,
InetAddress[] clientAddresses) {
init(asn1Encoding, client, server, sessionKey, keyType, flags,
authTime, startTime, endTime, renewTill, clientAddresses);
}
Constructs a KerberosTicket using credentials information that a
client either receives from a KDC or reads from a cache. Parameters:
asn1Encoding - the ASN.1 encoding of the ticket as defined by
the Kerberos protocol specification.
client - the client that owns this service
ticket
server - the service that this ticket is for
sessionKey - the raw bytes for the session key that must be
used to encrypt the authenticator that will be sent to the server
keyType - the key type for the session key as defined by the
Kerberos protocol specification.
flags - the ticket flags. Each element in this array indicates
the value for the corresponding bit in the ASN.1 BitString that
represents the ticket flags. If the number of elements in this array
is less than the number of flags used by the Kerberos protocol,
then the missing flags will be filled in with false.
authTime - the time of initial authentication for the client
startTime - the time after which the ticket will be valid. This
may be null in which case the value of authTime is treated as the
startTime.
endTime - the time after which the ticket will no longer be
valid
renewTill - an absolute expiration time for the ticket,
including all renewal that might be possible. This field may be null
for tickets that are not renewable.
clientAddresses - the addresses from where the ticket may be
used by the client. This field may be null when the ticket is usable
from any address.
|
Method from javax.security.auth.kerberos.KerberosTicket Detail: |
public void destroy() throws DestroyFailedException {
if (!destroyed) {
Arrays.fill(asn1Encoding, (byte) 0);
client = null;
server = null;
sessionKey.destroy();
flags = null;
authTime = null;
startTime = null;
endTime = null;
renewTill = null;
clientAddresses = null;
destroyed = true;
}
}
Destroys the ticket and destroys any sensitive information stored in
it. |
public boolean equals(Object other) {
if (other == this)
return true;
if (! (other instanceof KerberosTicket)) {
return false;
}
KerberosTicket otherTicket = ((KerberosTicket) other);
if (isDestroyed() || otherTicket.isDestroyed()) {
return false;
}
if (!Arrays.equals(getEncoded(), otherTicket.getEncoded()) ||
!endTime.equals(otherTicket.getEndTime()) ||
!server.equals(otherTicket.getServer()) ||
!client.equals(otherTicket.getClient()) ||
!sessionKey.equals(otherTicket.getSessionKey()) ||
!Arrays.equals(clientAddresses, otherTicket.getClientAddresses()) ||
!Arrays.equals(flags, otherTicket.getFlags())) {
return false;
}
// authTime may be null
if (authTime == null) {
if (otherTicket.getAuthTime() != null)
return false;
} else {
if (!authTime.equals(otherTicket.getAuthTime()))
return false;
}
// startTime may be null
if (startTime == null) {
if (otherTicket.getStartTime() != null)
return false;
} else {
if (!startTime.equals(otherTicket.getStartTime()))
return false;
}
if (renewTill == null) {
if (otherTicket.getRenewTill() != null)
return false;
} else {
if (!renewTill.equals(otherTicket.getRenewTill()))
return false;
}
return true;
}
Compares the specified Object with this KerberosTicket for equality.
Returns true if the given object is also a
KerberosTicket and the two
KerberosTicket instances are equivalent. |
public final Date getAuthTime() {
return (authTime == null) ? null : (Date)authTime.clone();
}
Returns the time that the client was authenticated. |
public final KerberosPrincipal getClient() {
return client;
}
Returns the client principal associated with this ticket. |
public final InetAddress[] getClientAddresses() {
return (clientAddresses == null) ? null: clientAddresses.clone();
}
Returns a list of addresses from where the ticket can be used. |
public final byte[] getEncoded() {
if (destroyed)
throw new IllegalStateException("This ticket is no longer valid");
return asn1Encoding.clone();
}
Returns an ASN.1 encoding of the entire ticket. |
public final Date getEndTime() {
return (Date) endTime.clone();
}
Returns the expiration time for this ticket's validity period. |
public final boolean[] getFlags() {
return (flags == null? null: flags.clone());
}
Returns the flags associated with this ticket. Each element in the
returned array indicates the value for the corresponding bit in the
ASN.1 BitString that represents the ticket flags. |
public final Date getRenewTill() {
return (renewTill == null) ? null: (Date)renewTill.clone();
}
Returns the latest expiration time for this ticket, including all
renewals. This will return a null value for non-renewable tickets. |
public final KerberosPrincipal getServer() {
return server;
}
Returns the service principal associated with this ticket. |
public final SecretKey getSessionKey() {
if (destroyed)
throw new IllegalStateException("This ticket is no longer valid");
return sessionKey;
}
Returns the session key associated with this ticket. |
public final int getSessionKeyType() {
if (destroyed)
throw new IllegalStateException("This ticket is no longer valid");
return sessionKey.getKeyType();
}
Returns the key type of the session key associated with this
ticket as defined by the Kerberos Protocol Specification. |
public final Date getStartTime() {
return (startTime == null) ? null : (Date)startTime.clone();
}
Returns the start time for this ticket's validity period. |
public int hashCode() {
int result = 17;
if (isDestroyed()) {
return result;
}
result = result * 37 + Arrays.hashCode(getEncoded());
result = result * 37 + endTime.hashCode();
result = result * 37 + client.hashCode();
result = result * 37 + server.hashCode();
result = result * 37 + sessionKey.hashCode();
// authTime may be null
if (authTime != null) {
result = result * 37 + authTime.hashCode();
}
// startTime may be null
if (startTime != null) {
result = result * 37 + startTime.hashCode();
}
// renewTill may be null
if (renewTill != null) {
result = result * 37 + renewTill.hashCode();
}
// clientAddress may be null, the array's hashCode is 0
result = result * 37 + Arrays.hashCode(clientAddresses);
return result * 37 + Arrays.hashCode(flags);
}
Returns a hashcode for this KerberosTicket. |
public boolean isCurrent() {
return (System.currentTimeMillis() < = getEndTime().getTime());
}
Determines if this ticket is still current. |
public boolean isDestroyed() {
return destroyed;
}
Determines if this ticket has been destroyed. |
public final boolean isForwardable() {
return flags[FORWARDABLE_TICKET_FLAG];
}
Determines if this ticket is forwardable. |
public final boolean isForwarded() {
return flags[FORWARDED_TICKET_FLAG];
}
Determines if this ticket had been forwarded or was issued based on
authentication involving a forwarded ticket-granting ticket. |
public final boolean isInitial() {
return flags[INITIAL_TICKET_FLAG];
}
Determines if this ticket was issued using the Kerberos AS-Exchange
protocol, and not issued based on some ticket-granting ticket. |
public final boolean isPostdated() {
return flags[POSTDATED_TICKET_FLAG];
}
Determines is this ticket is post-dated. |
public final boolean isProxiable() {
return flags[PROXIABLE_TICKET_FLAG];
}
Determines if this ticket is proxiable. |
public final boolean isProxy() {
return flags[PROXY_TICKET_FLAG];
}
Determines is this ticket is a proxy-ticket. |
public final boolean isRenewable() {
return flags[RENEWABLE_TICKET_FLAG];
}
Determines is this ticket is renewable. If so, the refresh method can be called, assuming the validity period for
renewing is not already over. |
public void refresh() throws RefreshFailedException {
if (destroyed)
throw new RefreshFailedException("A destroyed ticket "
+ "cannot be renewd.");
if (!isRenewable())
throw new RefreshFailedException("This ticket is not renewable");
if (System.currentTimeMillis() > getRenewTill().getTime())
throw new RefreshFailedException("This ticket is past "
+ "its last renewal time.");
Throwable e = null;
sun.security.krb5.Credentials krb5Creds = null;
try {
krb5Creds = new sun.security.krb5.Credentials(asn1Encoding,
client.toString(),
server.toString(),
sessionKey.getEncoded(),
sessionKey.getKeyType(),
flags,
authTime,
startTime,
endTime,
renewTill,
clientAddresses);
krb5Creds = krb5Creds.renew();
} catch (sun.security.krb5.KrbException krbException) {
e = krbException;
} catch (java.io.IOException ioException) {
e = ioException;
}
if (e != null) {
RefreshFailedException rfException
= new RefreshFailedException("Failed to renew Kerberos Ticket "
+ "for client " + client
+ " and server " + server
+ " - " + e.getMessage());
rfException.initCause(e);
throw rfException;
}
/*
* In case multiple threads try to refresh it at the same time.
*/
synchronized (this) {
try {
this.destroy();
} catch (DestroyFailedException dfException) {
// Squelch it since we don't care about the old ticket.
}
init(krb5Creds.getEncoded(),
new KerberosPrincipal(krb5Creds.getClient().getName()),
new KerberosPrincipal(krb5Creds.getServer().getName(),
KerberosPrincipal.KRB_NT_SRV_INST),
krb5Creds.getSessionKey().getBytes(),
krb5Creds.getSessionKey().getEType(),
krb5Creds.getFlags(),
krb5Creds.getAuthTime(),
krb5Creds.getStartTime(),
krb5Creds.getEndTime(),
krb5Creds.getRenewTill(),
krb5Creds.getClientAddresses());
destroyed = false;
}
}
Extends the validity period of this ticket. The ticket will contain
a new session key if the refresh operation succeeds. The refresh
operation will fail if the ticket is not renewable or the latest
allowable renew time has passed. Any other error returned by the
KDC will also cause this method to fail.
Note: This method is not synchronized with the the accessor
methods of this object. Hence callers need to be aware of multiple
threads that might access this and try to renew it at the same
time. |
public String toString() {
if (destroyed)
throw new IllegalStateException("This ticket is no longer valid");
StringBuffer caddrBuf = new StringBuffer();
if (clientAddresses != null) {
for (int i = 0; i < clientAddresses.length; i++) {
caddrBuf.append("clientAddresses[" + i + "] = " +
clientAddresses[i].toString());
}
}
return ("Ticket (hex) = " + "\n" +
(new HexDumpEncoder()).encodeBuffer(asn1Encoding) + "\n" +
"Client Principal = " + client.toString() + "\n" +
"Server Principal = " + server.toString() + "\n" +
"Session Key = " + sessionKey.toString() + "\n" +
"Forwardable Ticket " + flags[FORWARDABLE_TICKET_FLAG] + "\n" +
"Forwarded Ticket " + flags[FORWARDED_TICKET_FLAG] + "\n" +
"Proxiable Ticket " + flags[PROXIABLE_TICKET_FLAG] + "\n" +
"Proxy Ticket " + flags[PROXY_TICKET_FLAG] + "\n" +
"Postdated Ticket " + flags[POSTDATED_TICKET_FLAG] + "\n" +
"Renewable Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
"Initial Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
"Auth Time = " + String.valueOf(authTime) + "\n" +
"Start Time = " + String.valueOf(startTime) + "\n" +
"End Time = " + endTime.toString() + "\n" +
"Renew Till = " + String.valueOf(renewTill) + "\n" +
"Client Addresses " +
(clientAddresses == null ? " Null " : caddrBuf.toString() +
"\n"));
}
|