784 lines · 27.0 KB · Java
RawDownload
/* * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.security.auth.kerberos; import java.io.*;import java.util.Date;import java.util.Arrays;import java.net.InetAddress;import javax.crypto.SecretKey;import javax.security.auth.Refreshable;import javax.security.auth.Destroyable;import javax.security.auth.RefreshFailedException;import javax.security.auth.DestroyFailedException;import sun.misc.HexDumpEncoder;import sun.security.krb5.EncryptionKey;import sun.security.krb5.Asn1Exception;import sun.security.util.*; /** * 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 (<a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>). * <p> * 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 * {@link javax.security.auth.Subject Subject}.<p> * * It might be necessary for the application to be granted a * {@link javax.security.auth.PrivateCredentialPermission * PrivateCredentialPermission} if it needs to access a KerberosTicket * instance from a Subject. This permission is not needed when the * application depends on the default JGSS Kerberos mechanism to access the * KerberosTicket. In that case, however, the application will need an * appropriate * {@link javax.security.auth.kerberos.ServicePermission ServicePermission}. * <p> * 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. * * @see javax.security.auth.Subject * @see javax.security.auth.PrivateCredentialPermission * @see javax.security.auth.login.LoginContext * @see org.ietf.jgss.GSSCredential * @see org.ietf.jgss.GSSManager * * @author Mayank Upadhyay * @since 1.4 */public class KerberosTicket implements Destroyable, Refreshable,         java.io.Serializable {     private static final long serialVersionUID = 7395334370157380539L;     // XXX Make these flag indices public    private static final int FORWARDABLE_TICKET_FLAG = 1;    private static final int FORWARDED_TICKET_FLAG   = 2;    private static final int PROXIABLE_TICKET_FLAG   = 3;    private static final int PROXY_TICKET_FLAG       = 4;    private static final int POSTDATED_TICKET_FLAG   = 6;    private static final int RENEWABLE_TICKET_FLAG   = 8;    private static final int INITIAL_TICKET_FLAG     = 9;     private static final int NUM_FLAGS = 32;     /**     *     * ASN.1 DER Encoding of the Ticket as defined in the     * Kerberos Protocol Specification RFC4120.     *     * @serial     */     private byte[] asn1Encoding;     /**     *<code>KeyImpl</code> is serialized by writing out the ASN1 Encoded bytes     * of the encryption key. The ASN1 encoding is defined in RFC4120 and as     * follows:     * <pre>     * EncryptionKey   ::= SEQUENCE {     *          keytype    [0] Int32 -- actually encryption type --,     *          keyvalue   [1] OCTET STRING     * }     * </pre>     *     * @serial     */     private KeyImpl sessionKey;     /**     *     * Ticket Flags as defined in the Kerberos Protocol Specification RFC4120.     *     * @serial     */     private boolean[] flags;     /**     *     * Time of initial authentication     *     * @serial     */     private Date authTime;     /**     *     * Time after which the ticket is valid.     * @serial     */    private Date startTime;     /**     *     * Time after which the ticket will not be honored. (its expiration time).     *     * @serial     */     private Date endTime;     /**     *     * For renewable Tickets it indicates the maximum endtime that may be     * included in a renewal. It can be thought of as the absolute expiration     * time for the ticket, including all renewals. This field may be null     * for tickets that are not renewable.     *     * @serial     */     private Date renewTill;     /**     *     * Client that owns the service ticket     *     * @serial     */     private KerberosPrincipal client;     /**     *     * The service for which the ticket was issued.     *     * @serial     */     private KerberosPrincipal server;     /**     *     * 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.     *     * @serial     */      private InetAddress[] clientAddresses;     private transient boolean destroyed = false;     /**     * Constructs a KerberosTicket using credentials information that a     * client either receives from a KDC or reads from a cache.     *     * @param asn1Encoding the ASN.1 encoding of the ticket as defined by     * the Kerberos protocol specification.     * @param client the client that owns this service     * ticket     * @param server the service that this ticket is for     * @param sessionKey the raw bytes for the session key that must be     * used to encrypt the authenticator that will be sent to the server     * @param keyType the key type for the session key as defined by the     * Kerberos protocol specification.     * @param 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.     * @param authTime the time of initial authentication for the client     * @param 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.     * @param endTime the time after which the ticket will no longer be     * valid     * @param 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.     * @param 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.     */    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);    }     private void init(byte[] asn1Encoding,                         KerberosPrincipal client,                         KerberosPrincipal server,                         byte[] sessionKey,                         int keyType,                         boolean[] flags,                         Date authTime,                         Date startTime,                         Date endTime,                         Date renewTill,                         InetAddress[] clientAddresses) {        if (sessionKey == null)           throw new IllegalArgumentException("Session key for ticket"                                              + " cannot be null");        init(asn1Encoding, client, server,             new KeyImpl(sessionKey, keyType), flags, authTime,             startTime, endTime, renewTill, clientAddresses);    }     private void init(byte[] asn1Encoding,                         KerberosPrincipal client,                         KerberosPrincipal server,                         KeyImpl sessionKey,                         boolean[] flags,                         Date authTime,                         Date startTime,                         Date endTime,                         Date renewTill,                         InetAddress[] clientAddresses) {        if (asn1Encoding == null)           throw new IllegalArgumentException("ASN.1 encoding of ticket"                                              + " cannot be null");        this.asn1Encoding = asn1Encoding.clone();         if (client == null)           throw new IllegalArgumentException("Client name in ticket"                                              + " cannot be null");        this.client = client;         if (server == null)           throw new IllegalArgumentException("Server name in ticket"                                              + " cannot be null");        this.server = server;         // Caller needs to make sure `sessionKey` will not be null        this.sessionKey = sessionKey;         if (flags != null) {           if (flags.length >= NUM_FLAGS)                this.flags = flags.clone();           else {                this.flags = new boolean[NUM_FLAGS];                // Fill in whatever we have                for (int i = 0; i < flags.length; i++)                    this.flags[i] = flags[i];           }        } else           this.flags = new boolean[NUM_FLAGS];         if (this.flags[RENEWABLE_TICKET_FLAG]) {           if (renewTill == null)                throw new IllegalArgumentException("The renewable period "                       + "end time cannot be null for renewable tickets.");            this.renewTill = new Date(renewTill.getTime());        }         if (authTime != null) {            this.authTime = new Date(authTime.getTime());        }        if (startTime != null) {            this.startTime = new Date(startTime.getTime());        } else {            this.startTime = this.authTime;        }         if (endTime == null)           throw new IllegalArgumentException("End time for ticket validity"                                              + " cannot be null");        this.endTime = new Date(endTime.getTime());         if (clientAddresses != null)           this.clientAddresses = clientAddresses.clone();    }     /**     * Returns the client principal associated with this ticket.     *     * @return the client principal.     */    public final KerberosPrincipal getClient() {        return client;    }     /**     * Returns the service principal associated with this ticket.     *     * @return the service principal.     */    public final KerberosPrincipal getServer() {        return server;    }     /**     * Returns the session key associated with this ticket.     *     * @return the session key.     */    public final SecretKey getSessionKey() {        if (destroyed)            throw new IllegalStateException("This ticket is no longer valid");        return sessionKey;    }     /**     * Returns the key type of the session key associated with this     * ticket as defined by the Kerberos Protocol Specification.     *     * @return the key type of the session key associated with this     * ticket.     *     * @see #getSessionKey()     */    public final int getSessionKeyType() {        if (destroyed)            throw new IllegalStateException("This ticket is no longer valid");        return sessionKey.getKeyType();    }     /**     * Determines if this ticket is forwardable.     *     * @return true if this ticket is forwardable, false if not.     */    public final boolean isForwardable() {        return flags[FORWARDABLE_TICKET_FLAG];    }     /**     * Determines if this ticket had been forwarded or was issued based on     * authentication involving a forwarded ticket-granting ticket.     *     * @return true if this ticket had been forwarded or was issued based on     * authentication involving a forwarded ticket-granting ticket,     * false otherwise.     */    public final boolean isForwarded() {        return flags[FORWARDED_TICKET_FLAG];    }     /**     * Determines if this ticket is proxiable.     *     * @return true if this ticket is proxiable, false if not.     */    public final boolean isProxiable() {        return flags[PROXIABLE_TICKET_FLAG];    }     /**     * Determines is this ticket is a proxy-ticket.     *     * @return true if this ticket is a proxy-ticket, false if not.     */    public final boolean isProxy() {        return flags[PROXY_TICKET_FLAG];    }      /**     * Determines is this ticket is post-dated.     *     * @return true if this ticket is post-dated, false if not.     */    public final boolean isPostdated() {        return flags[POSTDATED_TICKET_FLAG];    }     /**     * Determines is this ticket is renewable. If so, the {@link #refresh()     * refresh} method can be called, assuming the validity period for     * renewing is not already over.     *     * @return true if this ticket is renewable, false if not.     */    public final boolean isRenewable() {        return flags[RENEWABLE_TICKET_FLAG];    }     /**     * Determines if this ticket was issued using the Kerberos AS-Exchange     * protocol, and not issued based on some ticket-granting ticket.     *     * @return true if this ticket was issued using the Kerberos AS-Exchange     * protocol, false if not.     */    public final boolean isInitial() {        return flags[INITIAL_TICKET_FLAG];    }     /**     * 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.     *     * @return the flags associated with this ticket.     */    public final boolean[]  getFlags() {        return (flags == null? null: flags.clone());    }     /**     * Returns the time that the client was authenticated.     *     * @return the time that the client was authenticated     *         or null if not set.     */    public final java.util.Date getAuthTime() {        return (authTime == null) ? null : (Date)authTime.clone();    }     /**     * Returns the start time for this ticket's validity period.     *     * @return the start time for this ticket's validity period     *         or null if not set.     */    public final java.util.Date getStartTime() {        return (startTime == null) ? null : (Date)startTime.clone();    }     /**     * Returns the expiration time for this ticket's validity period.     *     * @return the expiration time for this ticket's validity period.     */    public final java.util.Date getEndTime() {        return (Date) endTime.clone();    }     /**     * Returns the latest expiration time for this ticket, including all     * renewals. This will return a null value for non-renewable tickets.     *     * @return the latest expiration time for this ticket.     */    public final java.util.Date getRenewTill() {        return (renewTill == null) ? null: (Date)renewTill.clone();    }     /**     * Returns a list of addresses from where the ticket can be used.     *     * @return ths list of addresses or null, if the field was not     * provided.     */

Lines 1–500 of 784.