summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/security/auth/kerberos
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/security/auth/kerberos')
-rw-r--r--libjava/classpath/javax/security/auth/kerberos/DelegationPermission.java136
-rw-r--r--libjava/classpath/javax/security/auth/kerberos/KerberosKey.java180
-rw-r--r--libjava/classpath/javax/security/auth/kerberos/KerberosPrincipal.java207
-rw-r--r--libjava/classpath/javax/security/auth/kerberos/KerberosTicket.java372
-rw-r--r--libjava/classpath/javax/security/auth/kerberos/KeyImpl.java102
-rw-r--r--libjava/classpath/javax/security/auth/kerberos/ServicePermission.java172
6 files changed, 1169 insertions, 0 deletions
diff --git a/libjava/classpath/javax/security/auth/kerberos/DelegationPermission.java b/libjava/classpath/javax/security/auth/kerberos/DelegationPermission.java
new file mode 100644
index 000000000..42bb9c73c
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/kerberos/DelegationPermission.java
@@ -0,0 +1,136 @@
+/* DelegationPermission.java -- kerberos delegation permission
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.kerberos;
+
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * @since 1.4
+ */
+public final class DelegationPermission
+ extends BasicPermission
+{
+ // FIXME: Enable this when serialization works.
+ // private static final long serialVersionUID = 883133252142523922L;
+
+ /**
+ * Create a new instance with the given name.
+ */
+ public DelegationPermission(String name)
+ {
+ super(name);
+ checkSyntax(name);
+ }
+
+ /**
+ * Create a new instance with the given name and actions.
+ *
+ * The name consists of two parts: first the subordinate
+ * service principal, then the target service principal.
+ * Each principal is surrounded by quotes; the two are separated
+ * by a space.
+ *
+ * @param name the name
+ * @param actions the actions; this is ignored
+ */
+ public DelegationPermission(String name, String actions)
+ {
+ super(name, actions);
+ checkSyntax(name);
+ }
+
+ private static void checkSyntax(String name)
+ {
+ int index = name.indexOf('"', 1);
+ int len = name.length();
+ if (name.charAt(0) != '"' || name.charAt(len - 1) != '"'
+ || index == -1 || index + 3 >= len
+ || name.charAt(index + 1) != ' '
+ || name.charAt(index + 2) != '"')
+ // FIXME: better message here.
+ throw new IllegalArgumentException("invalid syntax for principals");
+ }
+
+ public boolean implies(Permission perm)
+ {
+ return equals(perm);
+ }
+
+ public PermissionCollection newPermissionCollection()
+ {
+ // FIXME: don't know how to serialize here. I suspect this
+ // class has to have a particular name, etc ...
+ return new PermissionCollection()
+ {
+ private Vector permissions = new Vector();
+
+ public void add(Permission perm)
+ {
+ if (isReadOnly())
+ throw new SecurityException("readonly");
+ if (! (perm instanceof DelegationPermission))
+ throw new IllegalArgumentException("can only add DelegationPermissions");
+ permissions.add(perm);
+ }
+
+ public boolean implies(Permission perm)
+ {
+ if (! (perm instanceof DelegationPermission))
+ return false;
+ Enumeration e = elements();
+ while (e.hasMoreElements())
+ {
+ DelegationPermission dp = (DelegationPermission) e.nextElement();
+ if (dp.implies(perm))
+ return true;
+ }
+ return false;
+ }
+
+ public Enumeration elements()
+ {
+ return permissions.elements();
+ }
+ };
+ }
+}
diff --git a/libjava/classpath/javax/security/auth/kerberos/KerberosKey.java b/libjava/classpath/javax/security/auth/kerberos/KerberosKey.java
new file mode 100644
index 000000000..e5735fbd5
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/kerberos/KerberosKey.java
@@ -0,0 +1,180 @@
+/* KerberosKey.java -- kerberos key
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.kerberos;
+
+import gnu.classpath.NotImplementedException;
+
+import java.io.Serializable;
+
+import javax.crypto.SecretKey;
+import javax.security.auth.DestroyFailedException;
+import javax.security.auth.Destroyable;
+
+/**
+ * This class represents a Kerberos key. See the Kerberos
+ * authentication RFC for more information:
+ * <a href="http://www.ietf.org/rfc/rfc1510.txt">RFC 1510</a>.
+ *
+ * @since 1.4
+ */
+public class KerberosKey
+ implements Serializable, SecretKey, Destroyable
+{
+ private static final long serialVersionUID = -4625402278148246993L;
+
+ private KerberosPrincipal principal;
+ private int versionNum;
+ private KeyImpl key;
+
+ /**
+ * Construct a new key with the indicated principal and key.
+ * @param principal the principal
+ * @param key the key's data
+ * @param type the key's type
+ * @param version the key's version number
+ */
+ public KerberosKey(KerberosPrincipal principal, byte[] key, int type,
+ int version)
+ {
+ this.principal = principal;
+ this.versionNum = version;
+ this.key = new KeyImpl(key, type);
+ }
+
+ /**
+ * Construct a new key with the indicated principal and a password.
+ * @param principal the principal
+ * @param passwd the password to use
+ * @param algo the algorithm; if null the "DES" algorithm is used
+ */
+ public KerberosKey(KerberosPrincipal principal, char[] passwd, String algo)
+ // Not implemented because KeyImpl really does nothing here.
+ throws NotImplementedException
+ {
+ this.principal = principal;
+ this.versionNum = 0; // FIXME: correct?
+ this.key = new KeyImpl(passwd, algo);
+ }
+
+ /**
+ * Return the name of the algorithm used to create this key.
+ */
+ public final String getAlgorithm()
+ {
+ checkDestroyed();
+ return key.algorithm;
+ }
+
+ /**
+ * Return the format of this key. This implementation always returns "RAW".
+ */
+ public final String getFormat()
+ {
+ checkDestroyed();
+ // Silly, but specified.
+ return "RAW";
+ }
+
+ /**
+ * Return the principal associated with this key.
+ */
+ public final KerberosPrincipal getPrincipal()
+ {
+ checkDestroyed();
+ return principal;
+ }
+
+ /**
+ * Return the type of this key.
+ */
+ public final int getKeyType()
+ {
+ checkDestroyed();
+ return key.type;
+ }
+
+ /**
+ * Return the version number of this key.
+ */
+ public final int getVersionNumber()
+ {
+ checkDestroyed();
+ return versionNum;
+ }
+
+ /**
+ * Return the encoded form of this key.
+ */
+ public final byte[] getEncoded()
+ {
+ checkDestroyed();
+ return (byte[]) key.key.clone();
+ }
+
+ /**
+ * Destroy this key.
+ */
+ public void destroy() throws DestroyFailedException
+ {
+ if (key == null)
+ throw new DestroyFailedException("already destroyed");
+ key = null;
+ }
+
+ /**
+ * Return true if this key has been destroyed. After this has been
+ * called, other methods on this object will throw IllegalStateException.
+ */
+ public boolean isDestroyed()
+ {
+ return key == null;
+ }
+
+ private void checkDestroyed()
+ {
+ if (key == null)
+ throw new IllegalStateException("key is destroyed");
+ }
+
+ public String toString()
+ {
+ // FIXME: random choice here.
+ return principal + ":" + versionNum;
+ }
+}
diff --git a/libjava/classpath/javax/security/auth/kerberos/KerberosPrincipal.java b/libjava/classpath/javax/security/auth/kerberos/KerberosPrincipal.java
new file mode 100644
index 000000000..4ba767226
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/kerberos/KerberosPrincipal.java
@@ -0,0 +1,207 @@
+/* KerberosPrincipal.java -- a kerberos principal
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.kerberos;
+
+import gnu.classpath.NotImplementedException;
+import gnu.classpath.SystemProperties;
+
+import java.io.Serializable;
+import java.security.Principal;
+
+/**
+ * This represents a Kerberos principal. See the Kerberos
+ * authentication RFC for more information:
+ * <a href="http://www.ietf.org/rfc/rfc1510.txt">RFC 1510</a>.
+ *
+ * @since 1.4
+ */
+public final class KerberosPrincipal
+ implements Serializable, Principal
+{
+ // Uncomment when serialization is correct.
+ // private static final long serialVersionUID = -7374788026156829911L;
+
+ /**
+ * Constant from the RFC: "Just the name of the principal as in DCE, or
+ * for users".
+ */
+ public static final int KRB_NT_PRINCIPAL = 1;
+
+ /**
+ * Constant from the RFC: "Service and other unique instance (krbtgt)".
+ */
+ public static final int KRB_NT_SRV_HST = 3;
+
+ /**
+ * Constant from the RFC: "Service with host name as instance (telnet,
+ * rcommands)".
+ */
+ public static final int KRB_NT_SRV_INST = 2;
+
+ /**
+ * Constant from the RFC: "Service with host as remaining components".
+ */
+ public static final int KRB_NT_SRV_XHST = 4;
+
+ /**
+ * Constant from the RFC: "Unique ID".
+ */
+ public static final int KRB_NT_UID = 5;
+
+ /**
+ * Constant from the RFC: "Name type not known".
+ */
+ public static final int KRB_NT_UNKNOWN = 0;
+
+ private String name;
+ private int type;
+ private String realm;
+
+ /**
+ * Create a new instance with the given name and a type of
+ * {@link #KRB_NT_PRINCIPAL}.
+ * @param name the principal's name
+ */
+ public KerberosPrincipal(String name)
+ {
+ this(name, KRB_NT_PRINCIPAL);
+ }
+
+ /**
+ * Create a new instance with the given name and type. The name is
+ * parsed according to the rules in the RFC. If there is no realm,
+ * then the local realm is used instead.
+ *
+ * @param name the principal's name
+ * @param type the principal's type
+ */
+ public KerberosPrincipal(String name, int type)
+ // Marked as unimplemented because we don't look for the realm as needed.
+ throws NotImplementedException
+ {
+ if (type < KRB_NT_UNKNOWN || type > KRB_NT_UID)
+ throw new IllegalArgumentException("unknown type: " + type);
+ this.name = name;
+ this.type = type;
+ this.realm = parseRealm();
+ }
+
+ private String parseRealm()
+ {
+ // Handle quoting as specified by the Kerberos RFC.
+ int i, len = name.length();
+ boolean quoted = false;
+ for (i = 0; i < len; ++i)
+ {
+ if (quoted)
+ {
+ quoted = false;
+ continue;
+ }
+ char c = name.charAt(i);
+ if (c == '\\')
+ {
+ quoted = true;
+ continue;
+ }
+ if (c == '@')
+ break;
+ }
+ if (quoted || i == len - 1)
+ throw new IllegalArgumentException("malformed principal: " + name);
+ if (i < len)
+ {
+ // We have the realm. FIXME: verify its syntax?
+ return name.substring(i + 1);
+ }
+ // Try to find the default realm.
+ String def = SystemProperties.getProperty("java.security.krb5.realm");
+ if (def != null)
+ return def;
+ // Now ask the system.
+ // FIXME: use java.security.krb5.conf,
+ // or $JAVA_HOME/lib/security/krb5.conf to find the krb config file.
+ // Then pass to native code using krb5_set_config_files() and
+ // krb5_get_default_realm(). But... what about /etc/krb5.conf?
+ throw new IllegalArgumentException("default realm can't be found");
+ }
+
+ /**
+ * Return the name of this principal.
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Return the realm of this principal.
+ */
+ public String getRealm()
+ {
+ return realm;
+ }
+
+ /**
+ * Return the type of this principal.
+ */
+ public int getNameType()
+ {
+ return type;
+ }
+
+ public int hashCode()
+ {
+ return name.hashCode();
+ }
+
+ public boolean equals(Object other)
+ {
+ if (! (other instanceof KerberosPrincipal))
+ return false;
+ KerberosPrincipal kp = (KerberosPrincipal) other;
+ return name.equals(kp.name) && type == kp.type;
+ }
+
+ public String toString()
+ {
+ // This is what came to mind.
+ return name + ":" + type;
+ }
+}
diff --git a/libjava/classpath/javax/security/auth/kerberos/KerberosTicket.java b/libjava/classpath/javax/security/auth/kerberos/KerberosTicket.java
new file mode 100644
index 000000000..ff70b9f4e
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/kerberos/KerberosTicket.java
@@ -0,0 +1,372 @@
+/* KerberosTicket.java -- a kerberos ticket
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.kerberos;
+
+import gnu.classpath.NotImplementedException;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.util.Date;
+
+import javax.crypto.SecretKey;
+import javax.security.auth.DestroyFailedException;
+import javax.security.auth.Destroyable;
+import javax.security.auth.RefreshFailedException;
+import javax.security.auth.Refreshable;
+
+/**
+ * This class represents a Kerberos ticket. See the Kerberos
+ * authentication RFC for more information:
+ * <a href="http://www.ietf.org/rfc/rfc1510.txt">RFC 1510</a>.
+ *
+ * @since 1.4
+ */
+public class KerberosTicket
+ implements Destroyable, Serializable, Refreshable
+{
+ private static final long serialVersionUID = 7395334370157380539L;
+
+ // Indices of the various flags. From the kerberos spec.
+ // We only list the ones we use.
+ private static final int FORWARDABLE = 1;
+ private static final int FORWARDED = 2;
+ private static final int PROXIABLE = 3;
+ private static final int PROXY = 4;
+ private static final int POSTDATED = 6;
+ private static final int RENEWABLE = 8;
+ private static final int INITIAL = 9;
+ private static final int NUM_FLAGS = 12;
+
+ private byte[] asn1Encoding;
+ private KeyImpl sessionKey;
+ private boolean[] flags;
+ private Date authTime;
+ private Date startTime;
+ private Date endTime;
+ private Date renewTill;
+ private KerberosPrincipal client;
+ private KerberosPrincipal server;
+ private InetAddress[] clientAddresses;
+
+ /**
+ * Create a new ticket given all the facts about it.
+ *
+ * Note that flags may be null or "short"; any flags not specified
+ * will be taken to be false.
+ *
+ * If the key is not renewable, then renewTill may be null.
+ *
+ * If authTime is null, then it is taken to be the same as startTime.
+ *
+ * If clientAddresses is null, then the ticket can be used anywhere.
+ *
+ * @param asn1Encoding the contents of the ticket, as ASN1
+ * @param client the client principal
+ * @param server the server principal
+ * @param key the contents of the session key
+ * @param type the type of the key
+ * @param flags an array of flags, as specified by the RFC
+ * @param authTime when the client was authenticated
+ * @param startTime starting time at which the ticket is valid
+ * @param endTime ending time, after which the ticket is invalid
+ * @param renewTill for a rewewable ticket, the time before which it must
+ * be renewed
+ * @param clientAddresses a possibly-null array of addresses where this
+ * ticket may be used
+ */
+ public KerberosTicket(byte[] asn1Encoding, KerberosPrincipal client,
+ KerberosPrincipal server, byte[] key, int type,
+ boolean[] flags, Date authTime, Date startTime,
+ Date endTime, Date renewTill,
+ InetAddress[] clientAddresses)
+ {
+ this.asn1Encoding = (byte[]) asn1Encoding.clone();
+ this.sessionKey = new KeyImpl(key, type);
+ this.flags = new boolean[NUM_FLAGS];
+ if (flags != null)
+ System.arraycopy(flags, 0, this.flags, 0,
+ Math.min(flags.length, NUM_FLAGS));
+ this.flags = (boolean[]) flags.clone();
+ this.authTime = (Date) authTime.clone();
+ this.startTime = (Date) ((startTime == null)
+ ? authTime : startTime).clone();
+ this.endTime = (Date) endTime.clone();
+ this.renewTill = (Date) renewTill.clone();
+ this.client = client;
+ this.server = server;
+ this.clientAddresses = (clientAddresses == null
+ ? null
+ : (InetAddress[]) clientAddresses.clone());
+ }
+
+ /**
+ * Destroy this ticket. This discards secret information. After this
+ * method is called, other methods will throw IllegalStateException.
+ */
+ public void destroy() throws DestroyFailedException
+ {
+ if (sessionKey == null)
+ throw new DestroyFailedException("already destroyed");
+ sessionKey = null;
+ asn1Encoding = null;
+ }
+
+ /**
+ * Return true if this ticket has been destroyed.
+ */
+ public boolean isDestroyed()
+ {
+ return sessionKey == null;
+ }
+
+ /**
+ * Return true if the ticket is currently valid. This is true if
+ * the system time is between the ticket's start and end times.
+ */
+ public boolean isCurrent()
+ {
+ long now = System.currentTimeMillis();
+ return startTime.getTime() <= now && now <= endTime.getTime();
+ }
+
+ /**
+ * If the ticket is renewable, and the renewal time has not yet elapsed,
+ * attempt to renew the ticket.
+ * @throws RefreshFailedException if the renewal fails for any reason
+ */
+ public void refresh() throws RefreshFailedException, NotImplementedException
+ {
+ if (! isRenewable())
+ throw new RefreshFailedException("not renewable");
+ if (renewTill != null
+ && System.currentTimeMillis() >= renewTill.getTime())
+ throw new RefreshFailedException("renewal time elapsed");
+ // FIXME: must contact the KDC.
+ // Use the java.security.krb5.kdc property...
+ throw new RefreshFailedException("not implemented");
+ }
+
+ /**
+ * Return the client principal for this ticket.
+ */
+ public final KerberosPrincipal getClient()
+ {
+ return client;
+ }
+
+ /**
+ * Return the server principal for this ticket.
+ */
+ public final KerberosPrincipal getServer()
+ {
+ return server;
+ }
+
+ /**
+ * Return true if this ticket is forwardable.
+ */
+ public final boolean isForwardable()
+ {
+ return flags[FORWARDABLE];
+ }
+
+ /**
+ * Return true if this ticket has been forwarded.
+ */
+ public final boolean isForwarded()
+ {
+ return flags[FORWARDED];
+ }
+
+ /**
+ * Return true if this ticket is proxiable.
+ */
+ public final boolean isProxiable()
+ {
+ return flags[PROXIABLE];
+ }
+
+ /**
+ * Return true if this ticket is a proxy ticket.
+ */
+ public final boolean isProxy()
+ {
+ return flags[PROXY];
+ }
+
+ /**
+ * Return true if this ticket was post-dated.
+ */
+ public final boolean isPostdated()
+ {
+ return flags[POSTDATED];
+ }
+
+ /**
+ * Return true if this ticket is renewable.
+ */
+ public final boolean isRenewable()
+ {
+ return flags[RENEWABLE];
+ }
+
+ /**
+ * Return true if this ticket was granted by an application
+ * server, and not via a ticket-granting ticket.
+ */
+ public final boolean isInitial()
+ {
+ return flags[INITIAL];
+ }
+
+ /**
+ * Return the flags for this ticket as a boolean array.
+ * See the RFC to understand what the different entries mean.
+ */
+ public final boolean[] getFlags()
+ {
+ return (boolean[]) flags.clone();
+ }
+
+ /**
+ * Return the authentication time for this ticket.
+ */
+ public final Date getAuthTime()
+ {
+ return (Date) authTime.clone();
+ }
+
+ /**
+ * Return the start time for this ticket.
+ */
+ public final Date getStartTime()
+ {
+ return (Date) startTime.clone();
+ }
+
+ /**
+ * Return the end time for this ticket.
+ */
+ public final Date getEndTime()
+ {
+ return (Date) endTime.clone();
+ }
+
+ /**
+ * Return the renewal time for this ticket. For a non-renewable
+ * ticket, this will return null.
+ */
+ public final Date getRenewTill()
+ {
+ return flags[RENEWABLE] ? ((Date) renewTill.clone()) : null;
+ }
+
+ /**
+ * Return the allowable client addresses for this ticket. This will
+ * return null if the ticket can be used anywhere.
+ */
+ public final InetAddress[] getClientAddresses()
+ {
+ return (clientAddresses == null
+ ? null
+ : (InetAddress[]) clientAddresses.clone());
+ }
+
+ /**
+ * Return the encoded form of this ticket.
+ */
+ public final byte[] getEncoded()
+ {
+ checkDestroyed();
+ return (byte[]) sessionKey.key.clone();
+ }
+
+ /**
+ * Return the secret key associated with this ticket.
+ */
+ public final SecretKey getSessionKey()
+ {
+ checkDestroyed();
+ return sessionKey;
+ }
+
+ private void checkDestroyed()
+ {
+ if (sessionKey == null)
+ throw new IllegalStateException("key is destroyed");
+ }
+
+ public String toString()
+ {
+ return getClass().getName() +
+ "[client=" + client +
+ ",server=" + server +
+ ",sessionKey=" + sessionKey +
+ ",flags=" + flags +
+ ",authTime=" + authTime +
+ ",startTime= " + startTime +
+ ",endTime=" + endTime +
+ ",renewTill=" + renewTill +
+ ",clientAddresses=" + clientAddresses +
+ "]";
+ }
+
+ /**
+ * <p>
+ * Returns the type of the session key in accordance with
+ * RFC1510. This usually corresponds to the encryption
+ * algorithm used by the key, though more than one algorithm
+ * may use the same key type (e.g. DES with different checksum
+ * mechanisms and chaining modes). Negative values are reserved
+ * for local use. Non-negative values are for officially assigned
+ * type fields. The RFC defines:
+ * </p>
+ * <ul>
+ * <li>0 &mdash; null</li>
+ * <li>1 &mdash; DES (in CBC mode with either MD4 or MD5 checksums)</li>
+ * </ul>
+ *
+ * @return the type of session key used by this ticket.
+ */
+ public final int getSessionKeyType()
+ {
+ return sessionKey.type;
+ }
+
+}
diff --git a/libjava/classpath/javax/security/auth/kerberos/KeyImpl.java b/libjava/classpath/javax/security/auth/kerberos/KeyImpl.java
new file mode 100644
index 000000000..a7cf3d212
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/kerberos/KeyImpl.java
@@ -0,0 +1,102 @@
+/* KeyImpl.java -- kerberos key implementation
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.kerberos;
+
+import java.io.Serializable;
+
+import javax.crypto.SecretKey;
+
+/**
+ * Note that the name of this class is fixed by the serialization
+ * spec, even though the class itself is not public.
+ */
+final class KeyImpl implements Serializable, SecretKey
+{
+ // Enable this when serialization works.
+ // private static final long serialVersionUID = -7889313790214321193L;
+
+ public String algorithm;
+ public int type;
+ public byte[] key;
+
+ public KeyImpl(byte[] key, int type)
+ {
+ // From kerberos spec.
+ if (type == 0)
+ this.algorithm = null;
+ else if (type == 1)
+ this.algorithm = "DES";
+ else
+ this.algorithm = "FIXME";
+ this.type = type;
+ this.key = (byte[]) key.clone();
+ }
+
+ public KeyImpl(char[] passwd, String algo)
+ {
+ this.algorithm = (algo == null) ? "DES" : algo;
+ this.type = 0; // FIXME
+ this.key = null; // double FIXME
+ }
+
+ public String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ public byte[] getEncoded()
+ {
+ return key;
+ }
+
+ public String getFormat()
+ {
+ // FIXME.
+ return null;
+ }
+
+ public String toString()
+ {
+ return getClass().getName() +
+ "[type=" + type +
+ ",algorithm=" + algorithm +
+ "]";
+ }
+
+}
diff --git a/libjava/classpath/javax/security/auth/kerberos/ServicePermission.java b/libjava/classpath/javax/security/auth/kerberos/ServicePermission.java
new file mode 100644
index 000000000..4412ea459
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/kerberos/ServicePermission.java
@@ -0,0 +1,172 @@
+/* ServicePermission.java -- kerberos service permission
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.security.auth.kerberos;
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * This represents permission to access to a Kerberos service principal.
+ * See the Kerberos authentication RFC for more information:
+ * <a href="http://www.ietf.org/rfc/rfc1510.txt">RFC 1510</a>.
+ *
+ * @since 1.4
+ */
+public final class ServicePermission
+ extends Permission
+{
+ // FIXME: Enable this when serialization works.
+ // private static final long serialVersionUID = -1227585031618624935L;
+
+ private static final int INITIATE = 1;
+ private static final int ACCEPT = 2;
+
+ private int flags;
+
+ /**
+ * Create a new service permission with the indicated name and actions.
+ *
+ * The name is the name of the kerberos principal for the service.
+ *
+ * The actions are a comma-separated list of strings. The recognized
+ * actions are "initiate" and "accept". The "initiate" action means
+ * that the holder of the permission can access the service. The
+ * "accept" action means that the holder of the permission can operate
+ * as this service.
+ *
+ * @param name the prinicpal's name
+ * @param action the allowed actions
+ */
+ public ServicePermission(String name, String action)
+ {
+ super(name);
+ parseActions(action);
+ }
+
+ public boolean implies(Permission perm)
+ {
+ if (! (perm instanceof ServicePermission))
+ return false;
+ ServicePermission sp = (ServicePermission) perm;
+ if ((flags & sp.flags) != sp.flags)
+ return false;
+ return getName().equals(sp.getName());
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof ServicePermission))
+ return false;
+ ServicePermission sp = (ServicePermission) obj;
+ return flags == sp.flags && getName().equals(sp.getName());
+ }
+
+ public int hashCode()
+ {
+ return getName().hashCode() + flags;
+ }
+
+ /**
+ * Return a string representing the actions.
+ */
+ public String getActions()
+ {
+ if (flags == (INITIATE | ACCEPT))
+ return "initiate,accept";
+ if (flags == INITIATE)
+ return "initiate";
+ if (flags == ACCEPT)
+ return "accept";
+ return "";
+ }
+
+ public PermissionCollection newPermissionCollection()
+ {
+ return new PermissionCollection()
+ {
+ private Vector permissions = new Vector();
+
+ public void add(Permission perm)
+ {
+ if (isReadOnly())
+ throw new SecurityException("readonly");
+ if (! (perm instanceof ServicePermission))
+ throw new IllegalArgumentException("can only add DelegationPermissions");
+ permissions.add(perm);
+ }
+
+ public boolean implies(Permission perm)
+ {
+ if (! (perm instanceof ServicePermission))
+ return false;
+ Enumeration e = elements();
+ while (e.hasMoreElements())
+ {
+ ServicePermission sp = (ServicePermission) e.nextElement();
+ if (sp.implies(perm))
+ return true;
+ }
+ return false;
+ }
+
+ public Enumeration elements()
+ {
+ return permissions.elements();
+ }
+ };
+ }
+
+ private void parseActions(String actions)
+ {
+ StringTokenizer tok = new StringTokenizer(actions, ",");
+ while (tok.hasMoreTokens())
+ {
+ String token = tok.nextToken();
+ if ("accept".equals(token))
+ flags |= ACCEPT;
+ else if ("initiate".equals(token))
+ flags |= INITIATE;
+ else
+ throw new IllegalArgumentException("unrecognized token: " + token);
+ }
+ }
+}