OSDN Git Service

GNU Classpath import (libgcj-snapshot-20100921).
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / security / auth / kerberos / KerberosTicket.java
1 /* KerberosTicket.java -- a kerberos ticket
2    Copyright (C) 2006 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package javax.security.auth.kerberos;
40
41 import gnu.classpath.NotImplementedException;
42
43 import java.io.Serializable;
44 import java.net.InetAddress;
45 import java.util.Date;
46
47 import javax.crypto.SecretKey;
48 import javax.security.auth.DestroyFailedException;
49 import javax.security.auth.Destroyable;
50 import javax.security.auth.RefreshFailedException;
51 import javax.security.auth.Refreshable;
52
53 /**
54  * This class represents a Kerberos ticket.  See the Kerberos
55  * authentication RFC for more information:
56  * <a href="http://www.ietf.org/rfc/rfc1510.txt">RFC 1510</a>.
57  *
58  * @since 1.4
59  */
60 public class KerberosTicket
61     implements Destroyable, Serializable, Refreshable
62 {
63   private static final long serialVersionUID = 7395334370157380539L;
64
65   // Indices of the various flags.  From the kerberos spec.
66   // We only list the ones we use.
67   private static final int FORWARDABLE = 1;
68   private static final int FORWARDED = 2;
69   private static final int PROXIABLE = 3;
70   private static final int PROXY = 4;
71   private static final int POSTDATED = 6;
72   private static final int RENEWABLE = 8;
73   private static final int INITIAL = 9;
74   private static final int NUM_FLAGS = 12;
75
76   private byte[] asn1Encoding;
77   private KeyImpl sessionKey;
78   private boolean[] flags;
79   private Date authTime;
80   private Date startTime;
81   private Date endTime;
82   private Date renewTill;
83   private KerberosPrincipal client;
84   private KerberosPrincipal server;
85   private InetAddress[] clientAddresses;
86
87   /**
88    * Create a new ticket given all the facts about it.
89    *
90    * Note that flags may be null or "short"; any flags not specified
91    * will be taken to be false.
92    *
93    * If the key is not renewable, then renewTill may be null.
94    *
95    * If authTime is null, then it is taken to be the same as startTime.
96    *
97    * If clientAddresses is null, then the ticket can be used anywhere.
98    *
99    * @param asn1Encoding the contents of the ticket, as ASN1
100    * @param client the client principal
101    * @param server the server principal
102    * @param key the contents of the session key
103    * @param type the type of the key
104    * @param flags an array of flags, as specified by the RFC
105    * @param authTime when the client was authenticated
106    * @param startTime starting time at which the ticket is valid
107    * @param endTime ending time, after which the ticket is invalid
108    * @param renewTill for a rewewable ticket, the time before which it must
109    * be renewed
110    * @param clientAddresses a possibly-null array of addresses where this
111    * ticket may be used
112    */
113   public KerberosTicket(byte[] asn1Encoding, KerberosPrincipal client,
114                         KerberosPrincipal server, byte[] key, int type,
115                         boolean[] flags, Date authTime, Date startTime,
116                         Date endTime, Date renewTill,
117                         InetAddress[] clientAddresses)
118   {
119     this.asn1Encoding = (byte[]) asn1Encoding.clone();
120     this.sessionKey = new KeyImpl(key, type);
121     this.flags = new boolean[NUM_FLAGS];
122     if (flags != null)
123       System.arraycopy(flags, 0, this.flags, 0,
124                        Math.min(flags.length, NUM_FLAGS));
125     this.flags = (boolean[]) flags.clone();
126     this.authTime = (Date) authTime.clone();
127     this.startTime = (Date) ((startTime == null)
128                               ? authTime : startTime).clone();
129     this.endTime = (Date) endTime.clone();
130     this.renewTill = (Date) renewTill.clone();
131     this.client = client;
132     this.server = server;
133     this.clientAddresses = (clientAddresses == null
134                             ? null
135                             : (InetAddress[]) clientAddresses.clone());
136   }
137
138   /**
139    * Destroy this ticket.  This discards secret information.  After this
140    * method is called, other methods will throw IllegalStateException.
141    */
142   public void destroy() throws DestroyFailedException
143   {
144     if (sessionKey == null)
145       throw new DestroyFailedException("already destroyed");
146     sessionKey = null;
147     asn1Encoding = null;
148   }
149
150   /**
151    * Return true if this ticket has been destroyed.
152    */
153   public boolean isDestroyed()
154   {
155     return sessionKey == null;
156   }
157
158   /**
159    * Return true if the ticket is currently valid.  This is true if
160    * the system time is between the ticket's start and end times.
161    */
162   public boolean isCurrent()
163   {
164     long now = System.currentTimeMillis();
165     return startTime.getTime() <= now && now <= endTime.getTime();
166   }
167
168   /**
169    * If the ticket is renewable, and the renewal time has not yet elapsed,
170    * attempt to renew the ticket.
171    * @throws RefreshFailedException if the renewal fails for any reason
172    */
173   public void refresh() throws RefreshFailedException, NotImplementedException
174   {
175     if (! isRenewable())
176       throw new RefreshFailedException("not renewable");
177     if (renewTill != null
178         && System.currentTimeMillis() >= renewTill.getTime())
179       throw new RefreshFailedException("renewal time elapsed");
180     // FIXME: must contact the KDC.
181     // Use the java.security.krb5.kdc property...
182     throw new RefreshFailedException("not implemented");
183   }
184
185   /**
186    * Return the client principal for this ticket.
187    */
188   public final KerberosPrincipal getClient()
189   {
190     return client;
191   }
192
193   /**
194    * Return the server principal for this ticket.
195    */
196   public final KerberosPrincipal getServer()
197   {
198     return server;
199   }
200
201   /**
202    * Return true if this ticket is forwardable.
203    */
204   public final boolean isForwardable()
205   {
206     return flags[FORWARDABLE];
207   }
208
209   /**
210    * Return true if this ticket has been forwarded.
211    */
212   public final boolean isForwarded()
213   {
214     return flags[FORWARDED];
215   }
216
217   /**
218    * Return true if this ticket is proxiable.
219    */
220   public final boolean isProxiable()
221   {
222     return flags[PROXIABLE];
223   }
224
225   /**
226    * Return true if this ticket is a proxy ticket.
227    */
228   public final boolean isProxy()
229   {
230     return flags[PROXY];
231   }
232
233   /**
234    * Return true if this ticket was post-dated.
235    */
236   public final boolean isPostdated()
237   {
238     return flags[POSTDATED];
239   }
240
241   /**
242    * Return true if this ticket is renewable.
243    */
244   public final boolean isRenewable()
245   {
246     return flags[RENEWABLE];
247   }
248
249   /**
250    * Return true if this ticket was granted by an application
251    * server, and not via a ticket-granting ticket.
252    */
253   public final boolean isInitial()
254   {
255     return flags[INITIAL];
256   }
257
258   /**
259    * Return the flags for this ticket as a boolean array.
260    * See the RFC to understand what the different entries mean.
261    */
262   public final boolean[] getFlags()
263   {
264     return (boolean[]) flags.clone();
265   }
266
267   /**
268    * Return the authentication time for this ticket.
269    */
270   public final Date getAuthTime()
271   {
272     return (Date) authTime.clone();
273   }
274
275   /**
276    * Return the start time for this ticket.
277    */
278   public final Date getStartTime()
279   {
280     return (Date) startTime.clone();
281   }
282
283   /**
284    * Return the end time for this ticket.
285    */
286   public final Date getEndTime()
287   {
288     return (Date) endTime.clone();
289   }
290
291   /**
292    * Return the renewal time for this ticket.  For a non-renewable
293    * ticket, this will return null.
294    */
295   public final Date getRenewTill()
296   {
297     return flags[RENEWABLE] ? ((Date) renewTill.clone()) : null;
298   }
299
300   /**
301    * Return the allowable client addresses for this ticket.  This will
302    * return null if the ticket can be used anywhere.
303    */
304   public final InetAddress[] getClientAddresses()
305   {
306     return (clientAddresses == null
307             ? null
308             : (InetAddress[]) clientAddresses.clone());
309   }
310
311   /**
312    * Return the encoded form of this ticket.
313    */
314   public final byte[] getEncoded()
315   {
316     checkDestroyed();
317     return (byte[]) sessionKey.key.clone();
318   }
319
320   /**
321    * Return the secret key associated with this ticket.
322    */
323   public final SecretKey getSessionKey()
324   {
325     checkDestroyed();
326     return sessionKey;
327   }
328
329   private void checkDestroyed()
330   {
331     if (sessionKey == null)
332       throw new IllegalStateException("key is destroyed");
333   }
334
335   public String toString()
336   {
337     return getClass().getName() +
338       "[client=" + client +
339       ",server=" + server +
340       ",sessionKey=" + sessionKey +
341       ",flags=" + flags +
342       ",authTime=" + authTime +
343       ",startTime= " + startTime +
344       ",endTime=" + endTime +
345       ",renewTill=" + renewTill +
346       ",clientAddresses=" + clientAddresses +
347       "]";
348   }
349
350   /**
351    * <p>
352    * Returns the type of the session key in accordance with
353    * RFC1510.  This usually corresponds to the encryption
354    * algorithm used by the key, though more than one algorithm
355    * may use the same key type (e.g. DES with different checksum
356    * mechanisms and chaining modes). Negative values are reserved
357    * for local use.  Non-negative values are for officially assigned
358    * type fields.  The RFC defines:
359    * </p>
360    * <ul>
361    * <li>0 &mdash; null</li>
362    * <li>1 &mdash; DES (in CBC mode with either MD4 or MD5 checksums)</li>
363    * </ul>
364    *
365    * @return the type of session key used by this ticket.
366    */
367   public final int getSessionKeyType()
368   {
369     return sessionKey.type;
370   }
371
372 }