From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001
From: upstream source tree <ports@midipix.org>
Date: Sun, 15 Mar 2015 20:14:05 -0400
Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified
 gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream
 tarball.

downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.

if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
---
 .../javax/security/auth/AuthPermission.java        | 146 ++++++
 .../security/auth/DestroyFailedException.java      |  67 +++
 .../classpath/javax/security/auth/Destroyable.java |  64 +++
 libjava/classpath/javax/security/auth/Policy.java  |  79 +++
 .../security/auth/PrivateCredentialPermission.java | 326 ++++++++++++
 .../security/auth/RefreshFailedException.java      |  63 +++
 .../classpath/javax/security/auth/Refreshable.java |  65 +++
 libjava/classpath/javax/security/auth/Subject.java | 557 +++++++++++++++++++++
 .../javax/security/auth/SubjectDomainCombiner.java |  97 ++++
 .../javax/security/auth/callback/Callback.java     |  64 +++
 .../security/auth/callback/CallbackHandler.java    | 155 ++++++
 .../security/auth/callback/ChoiceCallback.java     | 236 +++++++++
 .../auth/callback/ConfirmationCallback.java        | 505 +++++++++++++++++++
 .../security/auth/callback/LanguageCallback.java   | 100 ++++
 .../javax/security/auth/callback/NameCallback.java | 178 +++++++
 .../security/auth/callback/PasswordCallback.java   | 168 +++++++
 .../security/auth/callback/TextInputCallback.java  | 177 +++++++
 .../security/auth/callback/TextOutputCallback.java | 140 ++++++
 .../callback/UnsupportedCallbackException.java     | 101 ++++
 .../javax/security/auth/callback/package.html      |  46 ++
 .../auth/kerberos/DelegationPermission.java        | 136 +++++
 .../javax/security/auth/kerberos/KerberosKey.java  | 180 +++++++
 .../security/auth/kerberos/KerberosPrincipal.java  | 207 ++++++++
 .../security/auth/kerberos/KerberosTicket.java     | 372 ++++++++++++++
 .../javax/security/auth/kerberos/KeyImpl.java      | 102 ++++
 .../security/auth/kerberos/ServicePermission.java  | 172 +++++++
 .../security/auth/login/AccountException.java      |  64 +++
 .../auth/login/AccountExpiredException.java        |  64 +++
 .../auth/login/AccountLockedException.java         |  64 +++
 .../auth/login/AccountNotFoundException.java       |  64 +++
 .../security/auth/login/AppConfigurationEntry.java | 143 ++++++
 .../javax/security/auth/login/Configuration.java   | 121 +++++
 .../security/auth/login/CredentialException.java   |  64 +++
 .../auth/login/CredentialExpiredException.java     |  64 +++
 .../auth/login/CredentialNotFoundException.java    |  65 +++
 .../security/auth/login/FailedLoginException.java  |  63 +++
 .../javax/security/auth/login/LoginContext.java    | 265 ++++++++++
 .../javax/security/auth/login/LoginException.java  |  65 +++
 .../security/auth/login/NullConfiguration.java     |  62 +++
 .../javax/security/auth/login/package.html         |  46 ++
 libjava/classpath/javax/security/auth/package.html |  46 ++
 .../javax/security/auth/spi/LoginModule.java       | 122 +++++
 .../classpath/javax/security/auth/spi/package.html |  46 ++
 .../javax/security/auth/x500/X500Principal.java    | 556 ++++++++++++++++++++
 .../security/auth/x500/X500PrivateCredential.java  | 149 ++++++
 .../javax/security/auth/x500/package.html          |  46 ++
 46 files changed, 6682 insertions(+)
 create mode 100644 libjava/classpath/javax/security/auth/AuthPermission.java
 create mode 100644 libjava/classpath/javax/security/auth/DestroyFailedException.java
 create mode 100644 libjava/classpath/javax/security/auth/Destroyable.java
 create mode 100644 libjava/classpath/javax/security/auth/Policy.java
 create mode 100644 libjava/classpath/javax/security/auth/PrivateCredentialPermission.java
 create mode 100644 libjava/classpath/javax/security/auth/RefreshFailedException.java
 create mode 100644 libjava/classpath/javax/security/auth/Refreshable.java
 create mode 100644 libjava/classpath/javax/security/auth/Subject.java
 create mode 100644 libjava/classpath/javax/security/auth/SubjectDomainCombiner.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/Callback.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/CallbackHandler.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/ChoiceCallback.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/ConfirmationCallback.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/LanguageCallback.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/NameCallback.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/PasswordCallback.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/TextInputCallback.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/TextOutputCallback.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/UnsupportedCallbackException.java
 create mode 100644 libjava/classpath/javax/security/auth/callback/package.html
 create mode 100644 libjava/classpath/javax/security/auth/kerberos/DelegationPermission.java
 create mode 100644 libjava/classpath/javax/security/auth/kerberos/KerberosKey.java
 create mode 100644 libjava/classpath/javax/security/auth/kerberos/KerberosPrincipal.java
 create mode 100644 libjava/classpath/javax/security/auth/kerberos/KerberosTicket.java
 create mode 100644 libjava/classpath/javax/security/auth/kerberos/KeyImpl.java
 create mode 100644 libjava/classpath/javax/security/auth/kerberos/ServicePermission.java
 create mode 100644 libjava/classpath/javax/security/auth/login/AccountException.java
 create mode 100644 libjava/classpath/javax/security/auth/login/AccountExpiredException.java
 create mode 100644 libjava/classpath/javax/security/auth/login/AccountLockedException.java
 create mode 100644 libjava/classpath/javax/security/auth/login/AccountNotFoundException.java
 create mode 100644 libjava/classpath/javax/security/auth/login/AppConfigurationEntry.java
 create mode 100644 libjava/classpath/javax/security/auth/login/Configuration.java
 create mode 100644 libjava/classpath/javax/security/auth/login/CredentialException.java
 create mode 100644 libjava/classpath/javax/security/auth/login/CredentialExpiredException.java
 create mode 100644 libjava/classpath/javax/security/auth/login/CredentialNotFoundException.java
 create mode 100644 libjava/classpath/javax/security/auth/login/FailedLoginException.java
 create mode 100644 libjava/classpath/javax/security/auth/login/LoginContext.java
 create mode 100644 libjava/classpath/javax/security/auth/login/LoginException.java
 create mode 100644 libjava/classpath/javax/security/auth/login/NullConfiguration.java
 create mode 100644 libjava/classpath/javax/security/auth/login/package.html
 create mode 100644 libjava/classpath/javax/security/auth/package.html
 create mode 100644 libjava/classpath/javax/security/auth/spi/LoginModule.java
 create mode 100644 libjava/classpath/javax/security/auth/spi/package.html
 create mode 100644 libjava/classpath/javax/security/auth/x500/X500Principal.java
 create mode 100644 libjava/classpath/javax/security/auth/x500/X500PrivateCredential.java
 create mode 100644 libjava/classpath/javax/security/auth/x500/package.html

(limited to 'libjava/classpath/javax/security/auth')

diff --git a/libjava/classpath/javax/security/auth/AuthPermission.java b/libjava/classpath/javax/security/auth/AuthPermission.java
new file mode 100644
index 000000000..176ed9fb4
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/AuthPermission.java
@@ -0,0 +1,146 @@
+/* AuthPermission.java -- permissions related to authentication.
+   Copyright (C) 2004 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;
+
+import java.security.BasicPermission;
+
+/**
+ * <p>A permission controlling access to authentication service. The
+ * <i>actions</i> field of auth permission objects is ignored; the whole
+ * of the permission is defined by the <i>target</i>.</p>
+ *
+ * <p>The authentication permission targets recognized are:</p>
+ *
+ * <dl>
+ * <dt><code>doAs</code></dt>
+ *
+ * <dd><p>Allows access to the {@link
+ * Subject#doAs(javax.security.auth.Subject  java.security.PrivilegedAction)}
+ * methods.</p></dd>
+ *
+ * <dt><code>doAsPrivileged</code></dt>
+ *
+ * <dd><p>Allows access to the {@link
+ * Subject#doAsPrivileged(javax.security.auth.Subject,
+ * java.security.PrivilegedAction, java.security.AccessControlContext)}
+ * methods.</p></dd>
+ *
+ * <dt><code>getSubject</code></dt>
+ *
+ * <dd><p>Allows access to the {@link Subject} associated with a
+ * thread.</p></dd>
+ *
+ * <dt><code>getSubjectFromDomainCombiner</code></dt>
+ *
+ * <dd><p>Allows access to the {@link Subject} associated with a
+ * {@link SubjectDomainCombiner}.</p></dd>
+ *
+ * <dt><code>setReadOnly</code></dt>
+ *
+ * <dd><p>Allows a {@link Subject} to be marked as read-only.</p></dd>
+ *
+ * <dt><code>modifyPrincipals</code></dt>
+ *
+ * <dd><p>Allows the set of principals of a subject to be modified.</p></dd>
+ *
+ * <dt><code>modifyPublicCredentials</code></dt>
+ *
+ * <dd><p>Allows the set of public credentials of a subject to be
+ * modified.</p></dd>
+ *
+ * <dt><code>modifyPrivateCredentials</code></dt>
+ *
+ * <dd><p>Allows the set of private credentials of a subject to be
+ * modified.</p></dd>
+ *
+ * <dt><code>refreshCredential</code></dt>
+ *
+ * <dd><p>Allows a {@link Refreshable} credential to be refreshed.</p></dd>
+ *
+ * <dt><code>destroyCredential</code></dt>
+ *
+ * <dd><p>Allows a {@link Destroyable} credential to be destroyed.</p></dd>
+ *
+ * <dt><code>createLoginContext.<i>name</i></code></dt>
+ *
+ * <dd><p>Allows a {@link javax.security.auth.login.LoginContext} for the
+ * given <i>name</i>. <i>name</i> can also be a wildcard (<code>'*'</code>),
+ * which allows the creation of a context with any name.</p></dd>
+ *
+ * <dt><code>getLoginConfiguration</code></dt>
+ *
+ * <dd><p>Allows the system-wide login {@link
+ * javax.security.auth.login.Configuration} to be retrieved.</p></dd>
+ *
+ * <dt><code>setLoginConfiguration</code></dt>
+ *
+ * <dd><p>Allows the system-wide login {@link
+ * javax.security.auth.login.Configuration} to be set.</p></dd>
+ *
+ * <dt><code>refreshLoginConfiguration</code></dt>
+ *
+ * <dd><p>Allows the system-wide login {@link
+ * javax.security.auth.login.Configuration} to be refreshed.</p></dd>
+ * </dl>
+ */
+public final class AuthPermission extends BasicPermission
+{
+
+  /**
+   * Creates a new authentication permission for the given target name.
+   *
+   * @param name The target name.
+   */
+  public AuthPermission (String name)
+  {
+    super (name);
+  }
+
+  /**
+   * Creates a new authentication permission for the given target name.
+   * The actions list is not used by this class.
+   *
+   * @param name The target name.
+   * @param actions The action list.
+   */
+  public AuthPermission (String name, String actions)
+  {
+    super (name, actions);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/DestroyFailedException.java b/libjava/classpath/javax/security/auth/DestroyFailedException.java
new file mode 100644
index 000000000..98de82bd4
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/DestroyFailedException.java
@@ -0,0 +1,67 @@
+/* DestroyFailedException.java -- signals an object could not be destroyed.
+   Copyright (C) 2004 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;
+
+/**
+ * An exception thrown when the {@link Destroyable#destroy()} method
+ * fails for a credential.
+ *
+ * @see Destroyable
+ */
+public class DestroyFailedException extends Exception
+{
+
+  /**
+   * Creates a new DestroyFailedException with no detail message.
+   */
+  public DestroyFailedException()
+  {
+    super();
+  }
+
+  /**
+   * Creates a new DestroyFailedException with a detail message.
+   *
+   * @param message The detail message.
+   */
+  public DestroyFailedException (String message)
+  {
+    super (message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/Destroyable.java b/libjava/classpath/javax/security/auth/Destroyable.java
new file mode 100644
index 000000000..1ebd85c07
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/Destroyable.java
@@ -0,0 +1,64 @@
+/* Destroyable.java -- an immutable object that may be destroyed.
+   Copyright (C) 2004 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;
+
+/**
+ * An interface for objects that are immutable but whose sensitive
+ * data may be wiped out.
+ */
+public interface Destroyable
+{
+
+  /**
+   * Destroy this object, clearing all sensitive fields appropriately.
+   *
+   * @throws DestroyFailedException If this object could not be
+   *   destroyed.
+   * @throws SecurityException If the caller does not have permission
+   *   to destroy this object.
+   */
+  void destroy() throws DestroyFailedException;
+
+  /**
+   * Tells whether or not this object has been destroyed.
+   *
+   * @return True if this object has been destroyed.
+   */
+  boolean isDestroyed();
+}
diff --git a/libjava/classpath/javax/security/auth/Policy.java b/libjava/classpath/javax/security/auth/Policy.java
new file mode 100644
index 000000000..4da9a84df
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/Policy.java
@@ -0,0 +1,79 @@
+/* Policy.java -- deprecated precursor to java.security.Policy.
+   Copyright (C) 2004 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;
+
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+
+/**
+ * @deprecated The classes java.security.Policy and
+ * java.security.ProtectionDomain provide the functionality of this class.
+ */
+public abstract class Policy
+{
+
+  private static Policy policy;
+
+  protected Policy()
+  {
+  }
+
+  public static synchronized Policy getPolicy()
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      {
+        sm.checkPermission (new AuthPermission ("getPolicy"));
+      }
+    return policy;
+  }
+
+  public static synchronized void setPolicy (Policy p)
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      {
+        sm.checkPermission (new AuthPermission ("setPolicy"));
+      }
+    policy = p;
+  }
+
+  public abstract PermissionCollection getPermissions (Subject subject, CodeSource source);
+  public abstract void refresh();
+}
diff --git a/libjava/classpath/javax/security/auth/PrivateCredentialPermission.java b/libjava/classpath/javax/security/auth/PrivateCredentialPermission.java
new file mode 100644
index 000000000..1982eef3d
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/PrivateCredentialPermission.java
@@ -0,0 +1,326 @@
+/* PrivateCredentialPermission.java -- permissions governing private credentials.
+   Copyright (C) 2004 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;
+
+import java.io.Serializable;
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * A permission governing access to a private credential. The action of this
+ * permission is always "read" -- meaning that the private credential
+ * information can be read from an object.
+ *
+ * <p>The target of this permission is formatted as follows:</p>
+ *
+ * <p><code>CredentialClassName ( PrinicpalClassName PrincipalName )*</code></p>
+ *
+ * <p><i>CredentialClassName</i> is either the name of a private credential
+ * class name, or a wildcard character (<code>'*'</code>).
+ * <i>PrinicpalClassName</i> is the class name of a principal object, and
+ * <i>PrincipalName</i> is a string representing the principal, or the
+ * wildcard character.</p>
+ */
+public final class PrivateCredentialPermission extends Permission
+  implements Serializable
+{
+  /**
+   * For compatability with Sun's JDK 1.4.2 rev. 5
+   */
+  private static final long serialVersionUID = 5284372143517237068L;
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  /**
+   * @serial The credential class name.
+   */
+  private final String credentialClass;
+
+  /**
+   * @serial The principals, a set of CredOwner objects (an undocumented
+   *  inner class of this class).
+   */
+  private final Set principals;
+
+  /**
+   * @serial Who knows?
+   */
+  private final boolean testing;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Create a new private credential permission.
+   *
+   * @param name The permission target name.
+   * @param actions The list of actions, which, for this class, must be
+   *  <code>"read"</code>.
+   */
+  public PrivateCredentialPermission (final String name, String actions)
+  {
+    super(name);
+    actions = actions.trim().toLowerCase();
+    if (!"read".equals (actions))
+      {
+        throw new IllegalArgumentException("actions must be \"read\"");
+      }
+    StringTokenizer st = new StringTokenizer (name, " \"'");
+    principals = new HashSet();
+    if (st.countTokens() < 3 || (st.countTokens() & 1) == 0)
+      {
+        throw new IllegalArgumentException ("badly formed credential name");
+      }
+    credentialClass = st.nextToken();
+    while (st.hasMoreTokens())
+      {
+        principals.add (new CredOwner (st.nextToken(), st.nextToken()));
+      }
+    testing = false; // WTF ever.
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public boolean equals (Object o)
+  {
+    if (! (o instanceof PrivateCredentialPermission))
+      {
+        return false;
+      }
+    PrivateCredentialPermission that = (PrivateCredentialPermission) o;
+    if (!that.getActions().equals (getActions()))
+      {
+        return false;
+      }
+    if (!that.getCredentialClass().equals (getCredentialClass()))
+      {
+        return false;
+      }
+
+    final String[][] principals = getPrincipals();
+    final String[][] that_principals = that.getPrincipals();
+    if (that_principals == null)
+      {
+        return false;
+      }
+    if (that_principals.length != principals.length)
+      {
+        return false;
+      }
+    for (int i = 0; i < principals.length; i++)
+      {
+        if (!principals[i][0].equals (that_principals[i][0]) ||
+            !principals[i][1].equals (that_principals[i][1]))
+          {
+            return false;
+          }
+      }
+    return true;
+  }
+
+  /**
+   * Returns the actions this permission encompasses. For private credential
+   * permissions, this is always the string <code>"read"</code>.
+   *
+   * @return The list of actions.
+   */
+  public String getActions()
+  {
+    return "read";
+  }
+
+  /**
+   * Returns the credential class name that was embedded in this permission's
+   * target name.
+   *
+   * @return The credential class name.
+   */
+  public String getCredentialClass()
+  {
+    return credentialClass;
+  }
+
+  /**
+   * Returns the principal list that was embedded in this permission's target
+   * name.
+   *
+   * <p>Each element of the returned array is a pair; the first element is the
+   * principal class name, and the second is the principal name.
+   *
+   * @return The principal list.
+   */
+  public String[][] getPrincipals()
+  {
+    String[][] ret = new String[principals.size()][];
+    Iterator it = principals.iterator();
+    for (int i = 0; i < principals.size() && it.hasNext(); i++)
+      {
+        CredOwner co = (CredOwner) it.next();
+        ret[i] = new String[] { co.getPrincipalClass(), co.getPrincipalName() };
+      }
+    return ret;
+  }
+
+  public int hashCode()
+  {
+    return credentialClass.hashCode() + principals.hashCode();
+  }
+
+  /**
+   * Test if this permission implies another. This method returns true if:
+   *
+   * <ol>
+   * <li><i>p</i> is an instance of PrivateCredentialPermission</li>.
+   * <li>The credential class name of this instance matches that of <i>p</i>,
+   * and one of the principals of <i>p</i> is contained in the principals of
+   * this class. Thus,
+   *   <ul>
+   *   <li><code>[ * P "foo" ]  implies [ C P "foo" ]</code></li>
+   *   <li><code>[ C P1 "foo" ] implies [ C P1 "foo" P2 "bar" ]</code></li>
+   *   <li><code>[ C P1 "*" ]   implies [ C P1 "foo" ]</code></li>
+   *   </ul>
+   * </ol>
+   *
+   * @param p The permission to check.
+   * @return True if this permission implies <i>p</i>.
+   */
+  public boolean implies (Permission p)
+  {
+    if (! (p instanceof PrivateCredentialPermission))
+      {
+        return false;
+      }
+    PrivateCredentialPermission that = (PrivateCredentialPermission) p;
+    if (!credentialClass.equals ("*")
+        && !credentialClass.equals (that.getCredentialClass()))
+      {
+        return false;
+      }
+    String[][] principals = getPrincipals();
+    String[][] that_principals = that.getPrincipals();
+    if (that_principals == null)
+      {
+        return false;
+      }
+    for (int i = 0; i < principals.length; i++)
+      {
+        for (int j = 0; j < that_principals.length; j++)
+          {
+            if (principals[i][0].equals (that_principals[j][0]) &&
+                (principals[i][1].equals ("*") ||
+                 principals[i][1].equals (that_principals[j][1])))
+              {
+                return true;
+              }
+          }
+      }
+    return false;
+  }
+
+  /**
+   * This method is not necessary for this class, thus it always returns null.
+   *
+   * @return null.
+   */
+  public PermissionCollection newPermissionCollection()
+  {
+    return null;
+  }
+
+  // Inner class.
+  // -------------------------------------------------------------------------
+
+  /**
+   * An undocumented inner class present for serialization compatibility.
+   */
+  private static class CredOwner implements Serializable
+  {
+
+    // Fields.
+    // -----------------------------------------------------------------------
+
+    private final String principalClass;
+    private final String principalName;
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    CredOwner (final String principalClass, final String principalName)
+    {
+      this.principalClass = principalClass;
+      this.principalName = principalName;
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public boolean equals (Object o)
+    {
+      if (!(o instanceof CredOwner))
+        {
+          return false;
+        }
+      return principalClass.equals (((CredOwner) o).getPrincipalClass()) &&
+        principalName.equals (((CredOwner) o).getPrincipalName());
+    }
+
+    public int hashCode()
+    {
+      return principalClass.hashCode() + principalName.hashCode();
+    }
+
+    public String getPrincipalClass()
+    {
+      return principalClass;
+    }
+
+    public String getPrincipalName()
+    {
+      return principalName;
+    }
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/RefreshFailedException.java b/libjava/classpath/javax/security/auth/RefreshFailedException.java
new file mode 100644
index 000000000..6b8f94dcd
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/RefreshFailedException.java
@@ -0,0 +1,63 @@
+/* RefreshFailedException.java -- signals a failed refresh.
+   Copyright (C) 2004 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;
+
+/**
+ * A signal that a call to {@link Refreshable#refresh()} failed.
+ */
+public class RefreshFailedException extends Exception
+{
+
+  /**
+   * Create a new RefreshFailedException with no detail message.
+   */
+  public RefreshFailedException()
+  {
+  }
+
+  /**
+   * Create a new RefreshFailedException with a detail message.
+   *
+   * @param message The detail message.
+   */
+  public RefreshFailedException (String message)
+  {
+    super (message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/Refreshable.java b/libjava/classpath/javax/security/auth/Refreshable.java
new file mode 100644
index 000000000..14d766079
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/Refreshable.java
@@ -0,0 +1,65 @@
+/* Refreshable.java -- an object whose state may be refreshed.
+   Copyright (C) 2004 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;
+
+/**
+ * An object whose internal state may be <em>refreshed:</em> as in a
+ * credential object with a expiry date.
+ */
+public interface Refreshable
+{
+
+  /**
+   * Tells whether or not this object is current. Refreshable objects that
+   * are not current may need to be refreshed.
+   *
+   * @return Whether this object is current.
+   */
+  boolean isCurrent();
+
+  /**
+   * Refresh this object. The process involved in refreshing an object is
+   * per-implementation dependent.
+   *
+   * @throws RefreshFailedException If refreshing this object fails.
+   * @throws SecurityException If the caller does not have permission to
+   *  refresh, or to take the steps involved in refreshing, this object.
+   */
+  void refresh() throws RefreshFailedException;
+}
diff --git a/libjava/classpath/javax/security/auth/Subject.java b/libjava/classpath/javax/security/auth/Subject.java
new file mode 100644
index 000000000..e9b0804a5
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/Subject.java
@@ -0,0 +1,557 @@
+/* Subject.java -- a single entity in the system.
+   Copyright (C) 2004, 2005 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;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.DomainCombiner;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+
+public final class Subject implements Serializable
+{
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private static final long serialVersionUID = -8308522755600156056L;
+
+  /**
+   * @serial The set of principals. The type of this field is SecureSet, a
+   *  private inner class.
+   */
+  private final Set principals;
+
+  /**
+   * @serial The read-only flag.
+   */
+  private boolean readOnly;
+
+  private final transient SecureSet pubCred;
+  private final transient SecureSet privCred;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  public Subject()
+  {
+    principals = new SecureSet (this, SecureSet.PRINCIPALS);
+    pubCred = new SecureSet (this, SecureSet.PUBLIC_CREDENTIALS);
+    privCred = new SecureSet (this, SecureSet.PRIVATE_CREDENTIALS);
+    readOnly = false;
+  }
+
+  public Subject (final boolean readOnly,
+                  final Set<? extends Principal> principals,
+                  final Set<?> pubCred, final Set<?> privCred)
+  {
+    if (principals == null || pubCred == null || privCred == null)
+      {
+        throw new NullPointerException();
+      }
+    this.principals = new SecureSet (this, SecureSet.PRINCIPALS, principals);
+    this.pubCred = new SecureSet (this, SecureSet.PUBLIC_CREDENTIALS, pubCred);
+    this.privCred = new SecureSet (this, SecureSet.PRIVATE_CREDENTIALS, privCred);
+    this.readOnly = readOnly;
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * <p>Returns the subject associated with the given {@link
+   * AccessControlContext}.</p>
+   *
+   * <p>All this method does is retrieve the Subject object from the supplied
+   * context's {@link DomainCombiner}, if any, and if it is an instance of
+   * a {@link SubjectDomainCombiner}.
+   *
+   * @param context The context to retrieve the subject from.
+   * @return The subject assoctiated with the context, or <code>null</code>
+   *  if there is none.
+   * @throws NullPointerException If <i>subject</i> is null.
+   * @throws SecurityException If the caller does not have permission to get
+   *  the subject (<code>"getSubject"</code> target of {@link AuthPermission}.
+   */
+  public static Subject getSubject (final AccessControlContext context)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      {
+        sm.checkPermission (new AuthPermission ("getSubject"));
+      }
+    DomainCombiner dc = context.getDomainCombiner();
+    if (!(dc instanceof SubjectDomainCombiner))
+      {
+        return null;
+      }
+    return ((SubjectDomainCombiner) dc).getSubject();
+  }
+
+  /**
+   * <p>Run a method as another subject. This method will obtain the current
+   * {@link AccessControlContext} for this thread, then creates another with
+   * a {@link SubjectDomainCombiner} with the given subject. The supplied
+   * action will then be run with the modified context.</p>
+   *
+   * @param subject The subject to run as.
+   * @param action The action to run.
+   * @return The value returned by the privileged action.
+   * @throws SecurityException If the caller is not allowed to run under a
+   *  different identity (<code>"doAs"</code> target of {@link AuthPermission}.
+   */
+  public static Object doAs (final Subject subject, final PrivilegedAction action)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      {
+        sm.checkPermission (new AuthPermission ("doAs"));
+      }
+    AccessControlContext context =
+      new AccessControlContext (AccessController.getContext(),
+                                new SubjectDomainCombiner (subject));
+    return AccessController.doPrivileged (action, context);
+  }
+
+  /**
+   * <p>Run a method as another subject. This method will obtain the current
+   * {@link AccessControlContext} for this thread, then creates another with
+   * a {@link SubjectDomainCombiner} with the given subject. The supplied
+   * action will then be run with the modified context.</p>
+   *
+   * @param subject The subject to run as.
+   * @param action The action to run.
+   * @return The value returned by the privileged action.
+   * @throws SecurityException If the caller is not allowed to run under a
+   *  different identity (<code>"doAs"</code> target of {@link AuthPermission}.
+   * @throws PrivilegedActionException If the action throws an exception.
+   */
+  public static Object doAs (final Subject subject,
+                             final PrivilegedExceptionAction action)
+    throws PrivilegedActionException
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      {
+        sm.checkPermission (new AuthPermission ("doAs"));
+      }
+    AccessControlContext context =
+      new AccessControlContext (AccessController.getContext(),
+                                new SubjectDomainCombiner(subject));
+    return AccessController.doPrivileged (action, context);
+  }
+
+  /**
+   * <p>Run a method as another subject. This method will create a new
+   * {@link AccessControlContext} derived from the given one, with a
+   * {@link SubjectDomainCombiner} with the given subject. The supplied
+   * action will then be run with the modified context.</p>
+   *
+   * @param subject The subject to run as.
+   * @param action The action to run.
+   * @param acc The context to use.
+   * @return The value returned by the privileged action.
+   * @throws SecurityException If the caller is not allowed to run under a
+   *  different identity (<code>"doAsPrivileged"</code> target of {@link
+   *  AuthPermission}.
+   */
+  public static Object doAsPrivileged (final Subject subject,
+                                       final PrivilegedAction action,
+                                       final AccessControlContext acc)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      {
+        sm.checkPermission (new AuthPermission ("doAsPrivileged"));
+      }
+    AccessControlContext context =
+      new AccessControlContext (acc, new SubjectDomainCombiner (subject));
+    return AccessController.doPrivileged (action, context);
+  }
+
+  /**
+   * <p>Run a method as another subject. This method will create a new
+   * {@link AccessControlContext} derived from the given one, with a
+   * {@link SubjectDomainCombiner} with the given subject. The supplied
+   * action will then be run with the modified context.</p>
+   *
+   * @param subject The subject to run as.
+   * @param action The action to run.
+   * @param acc The context to use.
+   * @return The value returned by the privileged action.
+   * @throws SecurityException If the caller is not allowed to run under a
+   *  different identity (<code>"doAsPrivileged"</code> target of
+   *  {@link AuthPermission}.
+   * @throws PrivilegedActionException If the action throws an exception.
+   */
+  public static Object doAsPrivileged (final Subject subject,
+                                       final PrivilegedExceptionAction action,
+                                       AccessControlContext acc)
+    throws PrivilegedActionException
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      {
+        sm.checkPermission (new AuthPermission ("doAsPrivileged"));
+      }
+    if (acc == null)
+      acc = new AccessControlContext (new java.security.ProtectionDomain[0]);
+    AccessControlContext context =
+      new AccessControlContext (acc, new SubjectDomainCombiner (subject));
+    return AccessController.doPrivileged (action, context);
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public boolean equals (Object o)
+  {
+    if (!(o instanceof Subject))
+      {
+        return false;
+      }
+    Subject that = (Subject) o;
+    return principals.containsAll (that.getPrincipals()) &&
+      pubCred.containsAll (that.getPublicCredentials()) &&
+      privCred.containsAll (that.getPrivateCredentials());
+  }
+
+  public Set<Principal> getPrincipals()
+  {
+    return principals;
+  }
+
+  public <T extends Principal> Set<T> getPrincipals(Class<T> clazz)
+  {
+    HashSet result = new HashSet (principals.size());
+    for (Iterator it = principals.iterator(); it.hasNext(); )
+      {
+        Object o = it.next();
+        if (o != null && clazz.isAssignableFrom (o.getClass()))
+          {
+            result.add(o);
+          }
+      }
+    return Collections.unmodifiableSet (result);
+  }
+
+  public Set<Object> getPrivateCredentials()
+  {
+    return privCred;
+  }
+
+  public <T> Set<T> getPrivateCredentials (Class<T> clazz)
+  {
+    HashSet result = new HashSet (privCred.size());
+    for (Iterator it = privCred.iterator(); it.hasNext(); )
+      {
+        Object o = it.next();
+        if (o != null && clazz.isAssignableFrom (o.getClass()))
+          {
+            result.add(o);
+          }
+      }
+    return Collections.unmodifiableSet (result);
+  }
+
+  public Set<Object> getPublicCredentials()
+  {
+    return pubCred;
+  }
+
+  public <T> Set<T> getPublicCredentials (Class<T> clazz)
+  {
+    HashSet result = new HashSet (pubCred.size());
+    for (Iterator it = pubCred.iterator(); it.hasNext(); )
+      {
+        Object o = it.next();
+        if (o != null && clazz.isAssignableFrom (o.getClass()))
+          {
+            result.add(o);
+          }
+      }
+    return Collections.unmodifiableSet (result);
+  }
+
+  public int hashCode()
+  {
+    return principals.hashCode() + privCred.hashCode() + pubCred.hashCode();
+  }
+
+  /**
+   * <p>Returns whether or not this subject is read-only.</p>
+   *
+   * @return True is this subject is read-only.
+   */
+  public boolean isReadOnly()
+  {
+    return readOnly;
+  }
+
+  /**
+   * <p>Marks this subject as read-only.</p>
+   *
+   * @throws SecurityException If the caller does not have permission to
+   *  set this subject as read-only (<code>"setReadOnly"</code> target of
+   *  {@link AuthPermission}.
+   */
+  public void setReadOnly()
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      {
+        sm.checkPermission (new AuthPermission ("setReadOnly"));
+      }
+    readOnly = true;
+  }
+
+  public String toString()
+  {
+    return Subject.class.getName() + " [ principals=" + principals +
+      ", private credentials=" + privCred + ", public credentials=" +
+      pubCred + ", read-only=" + readOnly + " ]";
+  }
+
+// Inner class.
+  // -------------------------------------------------------------------------
+
+  /**
+   * An undocumented inner class that is used for sets in the parent class.
+   */
+  private static class SecureSet extends AbstractSet implements Serializable
+  {
+    // Fields.
+    // -----------------------------------------------------------------------
+
+    private static final long serialVersionUID = 7911754171111800359L;
+
+    static final int PRINCIPALS = 0;
+    static final int PUBLIC_CREDENTIALS = 1;
+    static final int PRIVATE_CREDENTIALS = 2;
+
+    private final Subject subject;
+    private final LinkedList elements;
+    private final transient int type;
+
+    // Constructors.
+    // -----------------------------------------------------------------------
+
+    SecureSet (final Subject subject, final int type, final Collection inElements)
+    {
+      this (subject, type);
+      for (Iterator it = inElements.iterator(); it.hasNext(); )
+        {
+          Object o = it.next();
+          if (type == PRINCIPALS && !(o instanceof Principal))
+            {
+              throw new IllegalArgumentException(o+" is not a Principal");
+            }
+          if (!this.elements.contains (o))
+            {
+              this.elements.add (o);
+            }
+        }
+    }
+
+    SecureSet (final Subject subject, final int type)
+    {
+      this.subject = subject;
+      this.type = type;
+      this.elements = new LinkedList();
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public synchronized int size()
+    {
+      return elements.size();
+    }
+
+    public Iterator iterator()
+    {
+      return elements.iterator();
+    }
+
+    public synchronized boolean add(Object element)
+    {
+      if (subject.isReadOnly())
+        {
+          throw new IllegalStateException ("subject is read-only");
+        }
+      final SecurityManager sm = System.getSecurityManager();
+      switch (type)
+        {
+        case PRINCIPALS:
+          if (sm != null)
+            {
+              sm.checkPermission (new AuthPermission ("modifyPrincipals"));
+            }
+          if (!(element instanceof Principal))
+            {
+              throw new IllegalArgumentException ("element is not a Principal");
+            }
+          break;
+
+        case PUBLIC_CREDENTIALS:
+          if (sm != null)
+            {
+              sm.checkPermission (new AuthPermission ("modifyPublicCredentials"));
+            }
+          break;
+
+        case PRIVATE_CREDENTIALS:
+          if (sm != null)
+            {
+              sm.checkPermission (new AuthPermission ("modifyPrivateCredentials"));
+            }
+          break;
+
+        default:
+          throw new Error ("this statement should be unreachable");
+        }
+
+      if (elements.contains (element))
+        {
+          return false;
+        }
+
+      return elements.add (element);
+    }
+
+    public synchronized boolean remove (final Object element)
+    {
+      if (subject.isReadOnly())
+        {
+          throw new IllegalStateException ("subject is read-only");
+        }
+      final SecurityManager sm = System.getSecurityManager();
+      switch (type)
+        {
+        case PRINCIPALS:
+          if (sm != null)
+            {
+              sm.checkPermission (new AuthPermission ("modifyPrincipals"));
+            }
+          if (!(element instanceof Principal))
+            {
+              throw new IllegalArgumentException ("element is not a Principal");
+            }
+          break;
+
+        case PUBLIC_CREDENTIALS:
+          if (sm != null)
+            {
+              sm.checkPermission (new AuthPermission ("modifyPublicCredentials"));
+            }
+          break;
+
+        case PRIVATE_CREDENTIALS:
+          if (sm != null)
+            {
+              sm.checkPermission (new AuthPermission ("modifyPrivateCredentials"));
+            }
+          break;
+
+        default:
+          throw new Error("this statement should be unreachable");
+        }
+
+      return elements.remove(element);
+    }
+
+    public synchronized boolean contains (final Object element)
+    {
+      return elements.contains (element);
+    }
+
+    public boolean removeAll (final Collection c)
+    {
+      if (subject.isReadOnly())
+        {
+          throw new IllegalStateException ("subject is read-only");
+        }
+      return super.removeAll (c);
+    }
+
+    public boolean retainAll (final Collection c)
+    {
+      if (subject.isReadOnly())
+        {
+          throw new IllegalStateException ("subject is read-only");
+        }
+      return super.retainAll (c);
+    }
+
+    public void clear()
+    {
+      if (subject.isReadOnly())
+        {
+          throw new IllegalStateException ("subject is read-only");
+        }
+      elements.clear();
+    }
+
+    private synchronized void writeObject (ObjectOutputStream out)
+      throws IOException
+    {
+      throw new UnsupportedOperationException ("FIXME: determine serialization");
+    }
+
+    private void readObject (ObjectInputStream in)
+      throws ClassNotFoundException, IOException
+    {
+      throw new UnsupportedOperationException ("FIXME: determine serialization");
+    }
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/SubjectDomainCombiner.java b/libjava/classpath/javax/security/auth/SubjectDomainCombiner.java
new file mode 100644
index 000000000..927e7479d
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/SubjectDomainCombiner.java
@@ -0,0 +1,97 @@
+/* SubjectDomainCombiner.java -- domain combiner for Subjects.
+   Copyright (C) 2004, 2005  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;
+
+import java.security.DomainCombiner;
+import java.security.Principal;
+import java.security.ProtectionDomain;
+
+import java.util.LinkedList;
+
+public class SubjectDomainCombiner implements DomainCombiner
+{
+
+  // Field.
+  // -------------------------------------------------------------------------
+
+  private final Subject subject;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public SubjectDomainCombiner (final Subject subject)
+  {
+    this.subject = subject;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public ProtectionDomain[] combine (final ProtectionDomain[] current,
+                                     final ProtectionDomain[] assigned)
+  {
+    LinkedList domains = new LinkedList();
+    Principal[] principals = null;
+    if (subject != null)
+      principals = (Principal[]) subject.getPrincipals().toArray (new Principal[0]);
+    if (current != null)
+      {
+        for (int i = 0; i < current.length; i++)
+          {
+            domains.add (new ProtectionDomain (current[i].getCodeSource(),
+                                               current[i].getPermissions(),
+                                               current[i].getClassLoader(),
+                                               principals));
+          }
+      }
+    if (assigned != null)
+      {
+        for (int i = 0; i < assigned.length; i++)
+          {
+            domains.add (assigned[i]);
+          }
+      }
+    return (ProtectionDomain[]) domains.toArray (new ProtectionDomain[domains.size()]);
+  }
+
+  public Subject getSubject()
+  {
+    return subject;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/callback/Callback.java b/libjava/classpath/javax/security/auth/callback/Callback.java
new file mode 100644
index 000000000..359828e1a
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/Callback.java
@@ -0,0 +1,64 @@
+/* Callback.java -- marker interface for callback classes
+   Copyright (C) 2003, 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.callback;
+
+/**
+ * <p>Implementations of this interface are passed to a {@link CallbackHandler},
+ * allowing underlying security services the ability to interact with a calling
+ * application to retrieve specific authentication data such as usernames and
+ * passwords, or to display certain information, such as error and warning
+ * messages.</p>
+ *
+ * <p><code>Callback</code> implementations do not retrieve or display the
+ * information requested by underlying security services. <code>Callback</code>
+ * implementations simply provide the means to pass such requests to
+ * applications, and for applications, if appropriate, to return requested
+ * information back to the underlying security services.</p>
+ *
+ * @see CallbackHandler
+ * @see ChoiceCallback
+ * @see ConfirmationCallback
+ * @see LanguageCallback
+ * @see NameCallback
+ * @see PasswordCallback
+ * @see TextInputCallback
+ * @see TextOutputCallback
+ */
+public interface Callback {
+}
diff --git a/libjava/classpath/javax/security/auth/callback/CallbackHandler.java b/libjava/classpath/javax/security/auth/callback/CallbackHandler.java
new file mode 100644
index 000000000..8d22943ca
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/CallbackHandler.java
@@ -0,0 +1,155 @@
+/* CallbackHandler.java -- base interface for callback handlers.
+   Copyright (C) 2003, 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.callback;
+
+import java.io.IOException;
+
+/**
+ * <p>An application implements a <code>CallbackHandler</code> and passes it to
+ * underlying security services so that they may interact with the application
+ * to retrieve specific authentication data, such as usernames and passwords, or
+ * to display certain information, such as error and warning messages.</p>
+ *
+ * <p><code>CallbackHandler</code>s are implemented in an application-dependent
+ * fashion. For example, implementations for an application with a graphical
+ * user interface (GUI) may pop up windows to prompt for requested information
+ * or to display error messages. An implementation may also choose to obtain
+ * requested information from an alternate source without asking the end user.</p>
+ *
+ * <p>Underlying security services make requests for different types of
+ * information by passing individual Callbacks to the <code>CallbackHandler</code>.
+ * The <code>CallbackHandler</code> implementation decides how to retrieve and
+ * display information depending on the {@link Callback}s passed to it. For
+ * example, if the underlying service needs a username and password to
+ * authenticate a user, it uses a {@link NameCallback} and
+ * {@link PasswordCallback}. The <code>CallbackHandler</code> can then choose
+ * to prompt for a username and password serially, or to prompt for both in a
+ * single window.</p>
+ *
+ * <p>A default <code>CallbackHandler</code> class implementation may be
+ * specified in the <code>auth.login.defaultCallbackHandler</code> security
+ * property. The security property can be set in the Java security properties
+ * file located in the file named
+ * <code>&lt;JAVA_HOME>/lib/security/java.security</code>, where
+ * <code>&lt;JAVA_HOME></code> refers to the directory where the SDK was
+ * installed.</p>
+ *
+ * <p>If the security property is set to the fully qualified name of a
+ * <code>CallbackHandler</code> implementation class, then a
+ * <code>LoginContext</code>will load the specified <code>CallbackHandler</code>
+ * and pass it to the underlying <code>LoginModules</code>. The
+ * <code>LoginContext</code> only loads the default handler if one was not
+ * provided.</p>
+ *
+ * <p>All default handler implementations must provide a public zero-argument
+ * constructor.</p>
+ *
+ */
+public interface CallbackHandler
+{
+
+  /**
+   * <p>Retrieve or display the information requested in the provided
+   * {@link Callback}s.</p>
+   *
+   * <p>The <code>handle()</code> method implementation checks the instance(s)
+   * of the {@link Callback} object(s) passed in to retrieve or display the
+   * requested information. The following example is provided to help
+   * demonstrate what an <code>handle()</code> method implementation might look
+   * like. This example code is for guidance only. Many details, including
+   * proper error handling, are left out for simplicity.</p>
+   *
+   * <pre>
+   *public void handle(Callback[] callbacks)
+   *throws IOException, UnsupportedCallbackException {
+   *   for (int i = 0; i < callbacks.length; i++) {
+   *      if (callbacks[i] instanceof TextOutputCallback) {
+   *         // display the message according to the specified type
+   *         TextOutputCallback toc = (TextOutputCallback)callbacks[i];
+   *         switch (toc.getMessageType()) {
+   *         case TextOutputCallback.INFORMATION:
+   *            System.out.println(toc.getMessage());
+   *            break;
+   *         case TextOutputCallback.ERROR:
+   *            System.out.println("ERROR: " + toc.getMessage());
+   *            break;
+   *         case TextOutputCallback.WARNING:
+   *            System.out.println("WARNING: " + toc.getMessage());
+   *            break;
+   *         default:
+   *            throw new IOException("Unsupported message type: "
+   *                  + toc.getMessageType());
+   *         }
+   *      } else if (callbacks[i] instanceof NameCallback) {
+   *         // prompt the user for a username
+   *         NameCallback nc = (NameCallback)callbacks[i];
+   *         // ignore the provided defaultName
+   *         System.err.print(nc.getPrompt());
+   *         System.err.flush();
+   *         nc.setName((new BufferedReader(
+   *               new InputStreamReader(System.in))).readLine());
+   *      } else if (callbacks[i] instanceof PasswordCallback) {
+   *         // prompt the user for sensitive information
+   *         PasswordCallback pc = (PasswordCallback)callbacks[i];
+   *         System.err.print(pc.getPrompt());
+   *         System.err.flush();
+   *         pc.setPassword(readPassword(System.in));
+   *      } else {
+   *         throw new UnsupportedCallbackException(
+   *               callbacks[i], "Unrecognized Callback");
+   *      }
+   *   }
+   *}
+   *
+   * // Reads user password from given input stream.
+   *private char[] readPassword(InputStream in) throws IOException {
+   *   // insert code to read a user password from the input stream
+   *}
+   * </pre>
+   *
+   * @param callbacks an array of {@link Callback} objects provided by an
+   * underlying security service which contains the information requested to
+   * be retrieved or displayed.
+   * @throws IOException if an input or output error occurs.
+   * @throws UnsupportedCallbackException if the implementation of this method
+   * does not support one or more of the Callbacks specified in the
+   * <code>callbacks</code> parameter.
+   */
+  void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException;
+}
diff --git a/libjava/classpath/javax/security/auth/callback/ChoiceCallback.java b/libjava/classpath/javax/security/auth/callback/ChoiceCallback.java
new file mode 100644
index 000000000..30bddd559
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/ChoiceCallback.java
@@ -0,0 +1,236 @@
+/* ChoiceCallback.java -- callback for a choice of values.
+   Copyright (C) 2003, 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.callback;
+
+import java.io.Serializable;
+
+/**
+ * Underlying security services instantiate and pass a
+ * <code>ChoiceCallback</code> to the <code>handle()</code> method of a
+ * {@link CallbackHandler} to display a list of choices and to retrieve the
+ * selected choice(s).
+ *
+ * @see CallbackHandler
+ */
+public class ChoiceCallback implements Callback, Serializable
+{
+
+  // Constants and variables
+  // -------------------------------------------------------------------------
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String prompt;
+
+  /**
+   * @serial the list of choices.
+   * @since 1.4
+   */
+  private String[] choices;
+
+  /**
+   * @serial the choice to be used as the default choice.
+   * @since 1.4
+   */
+  private int defaultChoice;
+
+  /**
+   * @serial whether multiple selections are allowed from the list of choices.
+   * @since 1.4
+   */
+  private boolean multipleSelectionsAllowed;
+
+  /**
+   * @serial the selected choices, represented as indexes into the choices list.
+   * @since 1.4
+   */
+  private int[] selections;
+
+  // Constructor(s)
+  //--------------------------------------------------------------------------
+
+  /**
+   * Construct a <code>ChoiceCallback</code> with a prompt, a list of choices,
+   * a default choice, and a boolean specifying whether or not multiple
+   * selections from the list of choices are allowed.
+   *
+   * @param prompt the prompt used to describe the list of choices.
+   * @param choices the list of choices.
+   * @param defaultChoice the choice to be used as the default choice when the
+   * list of choices are displayed. This value is represented as an index into
+   * the <code>choices</code> array.
+   * @param multipleSelectionsAllowed boolean specifying whether or not
+   * multiple selections can be made from the list of choices.
+   * @throws IllegalArgumentException if <code>prompt</code> is <code>null</code>,
+   * if <code>prompt</code> has a length of <code>0</code>, if <code>choices</code>
+   * is <code>null</code>, if <code>choices</code> has a length of <code>0</code>,
+   * if any element from <code>choices</code> is <code>null</code>, if any
+   * element from <code>choices</code> has a length of <code>0</code> or if
+   * <code>defaultChoice</code> does not fall within the array boundaries of
+   * <code>choices</code>.
+   */
+  public ChoiceCallback(String prompt, String[] choices, int defaultChoice,
+                        boolean multipleSelectionsAllowed)
+  {
+    super();
+
+    setPrompt(prompt);
+    setChoices(choices);
+    if (defaultChoice < 0 || defaultChoice >= this.choices.length)
+      {
+        throw new IllegalArgumentException("default choice is out of bounds");
+      }
+    this.defaultChoice = defaultChoice;
+    this.multipleSelectionsAllowed = multipleSelectionsAllowed;
+  }
+
+  // Instance methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Get the prompt.
+   *
+   * @return the prompt.
+   */
+  public String getPrompt()
+  {
+    return prompt;
+  }
+
+  /**
+   * Get the list of choices.
+   *
+   * @return the list of choices.
+   */
+  public String[] getChoices()
+  {
+    return choices;
+  }
+
+  /**
+   * Get the defaultChoice.
+   *
+   * @return the defaultChoice, represented as an index into the choices list.
+   */
+  public int getDefaultChoice()
+  {
+    return defaultChoice;
+  }
+
+  /**
+   * Get the boolean determining whether multiple selections from the choices
+   * list are allowed.
+   *
+   * @return whether multiple selections are allowed.
+   */
+  public boolean allowMultipleSelections()
+  {
+    return multipleSelectionsAllowed;
+  }
+
+  /**
+   * Set the selected choice.
+   *
+   * @param selection the selection represented as an index into the choices
+   * list.
+   * @see #getSelectedIndexes()
+   */
+  public void setSelectedIndex(int selection)
+  {
+    this.selections = new int[1];
+    this.selections[0] = selection;
+  }
+
+  /**
+   * Set the selected choices.
+   *
+   * @param selections the selections represented as indexes into the choices
+   * list.
+   * @throws UnsupportedOperationException if multiple selections are not
+   * allowed, as determined by <code>allowMultipleSelections</code>.
+   * @see #getSelectedIndexes()
+   */
+  public void setSelectedIndexes(int[] selections)
+  {
+    if (!multipleSelectionsAllowed)
+      {
+        throw new UnsupportedOperationException("not allowed");
+      }
+
+    this.selections = selections;
+  }
+
+  /**
+   * Get the selected choices.
+   *
+   * @return the selected choices, represented as indexes into the choices list.
+   * @see #setSelectedIndexes(int[])
+   */
+  public int[] getSelectedIndexes()
+  {
+    return selections;
+  }
+
+  private void setPrompt(String prompt) throws IllegalArgumentException
+  {
+    if ((prompt == null) || (prompt.length() == 0))
+      {
+        throw new IllegalArgumentException("invalid prompt");
+      }
+    this.prompt = prompt;
+  }
+
+  private void setChoices(String[] choices) throws IllegalArgumentException
+  {
+    if (choices == null || choices.length == 0)
+      {
+        throw new IllegalArgumentException("invalid choices");
+      }
+    for (int i = 0; i < choices.length; i++)
+      {
+        if (choices[i] == null || choices[i].length() == 0)
+          {
+            throw new IllegalArgumentException("invalid choice at index #"+i);
+          }
+      }
+    this.choices = choices;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/callback/ConfirmationCallback.java b/libjava/classpath/javax/security/auth/callback/ConfirmationCallback.java
new file mode 100644
index 000000000..8f89bf5fa
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/ConfirmationCallback.java
@@ -0,0 +1,505 @@
+/* ConfirmationCallback.java -- callback for confirmations.
+   Copyright (C) 2003, 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.callback;
+
+import java.io.Serializable;
+
+/**
+ * Underlying security services instantiate and pass a
+ * <code>ConfirmationCallback</code> to the <code>handle()</code> method of a
+ * {@link CallbackHandler} to ask for YES/NO, OK/CANCEL, YES/NO/CANCEL or other
+ * similar confirmations.
+ *
+ * @see CallbackHandler
+ */
+public class ConfirmationCallback implements Callback, Serializable
+{
+
+  // Constants and variables
+  // -------------------------------------------------------------------------
+
+  /**
+   * <p>Unspecified option type.</p>
+   *
+   * <p>The <code>getOptionType</code> method returns this value if this
+   * <code>ConfirmationCallback</code> was instantiated with <code>options</code>
+   * instead of an <code>optionType</code>.</p>
+   */
+  public static final int UNSPECIFIED_OPTION = -1;
+
+  /**
+   * <p>YES/NO confirmation option.</p>
+   *
+   * <p>An underlying security service specifies this as the <code>optionType</code>
+   * to a <code>ConfirmationCallback</code> constructor if it requires a
+   * confirmation which can be answered with either <code>YES</code> or
+   * <code>NO</code>.</p>
+   */
+  public static final int YES_NO_OPTION = 0;
+
+  /**
+   * <p>YES/NO/CANCEL confirmation confirmation option.</p>
+   *
+   * <p>An underlying security service specifies this as the <code>optionType</code>
+   * to a <code>ConfirmationCallback</code> constructor if it requires a
+   * confirmation which can be answered with either <code>YES</code>,
+   * <code>NO</code> or <code>CANCEL</code>.
+   */
+  public static final int YES_NO_CANCEL_OPTION = 1;
+
+  /**
+   * <p>OK/CANCEL confirmation confirmation option.</p>
+   *
+   * <p>An underlying security service specifies this as the <code>optionType</code>
+   * to a <code>ConfirmationCallback</code> constructor if it requires a
+   * confirmation which can be answered with either <code>OK</code> or
+   * <code>CANCEL</code>.</p>
+   */
+  public static final int OK_CANCEL_OPTION = 2;
+
+  /**
+   * <p>YES option.</p>
+   *
+   * <p>If an <code>optionType</code> was specified to this
+   * <code>ConfirmationCallback</code>, this option may be specified as a
+   * <code>defaultOption</code> or returned as the selected index.</p>
+   */
+  public static final int YES = 0;
+
+  /**
+   * <p>NO option.</p>
+   *
+   * <p>If an <code>optionType</code> was specified to this
+   * <code>ConfirmationCallback</code>, this option may be specified as a
+   * <code>defaultOption</code> or returned as the selected index.</p>
+   */
+  public static final int NO = 1;
+
+  /**
+   * <p>CANCEL option.</p>
+   *
+   * <p>If an <code>optionType</code> was specified to this
+   * <code>ConfirmationCallback</code>, this option may be specified as a
+   * <code>defaultOption</code> or returned as the selected index.</p>
+   */
+  public static final int CANCEL = 2;
+
+  /**
+   * <p>OK option.</p>
+   *
+   * <p>If an <code>optionType</code> was specified to this
+   * <code>ConfirmationCallback</code>, this option may be specified as a
+   * <code>defaultOption</code> or returned as the selected index.</p>
+   */
+  public static final int OK = 3;
+
+  /** INFORMATION message type. */
+  public static final int INFORMATION = 0;
+
+  /** WARNING message type. */
+  public static final int WARNING = 1;
+
+  /** ERROR message type. */
+  public static final int ERROR = 2;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String prompt;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private int messageType;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private int optionType;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private int defaultOption;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String[] options = null;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private int selection;
+
+  // Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * <p>Construct a <code>ConfirmationCallback</code> with a message type, an
+   * option type and a default option.</p>
+   *
+   * <p>Underlying security services use this constructor if they require
+   * either a YES/NO, YES/NO/CANCEL or OK/CANCEL confirmation.</p>
+   *
+   * @param messageType the message type (INFORMATION, WARNING or ERROR).
+   * @param optionType the option type (YES_NO_OPTION, YES_NO_CANCEL_OPTION or
+   * OK_CANCEL_OPTION).
+   * @param defaultOption the default option from the provided optionType (YES,
+   * NO, CANCEL or OK).
+   * @throws IllegalArgumentException if <code>messageType</code> is not either
+   * <code>INFORMATION</code>, <code>WARNING</code>, or <code>ERROR</code>, if
+   * <code>optionType</code> is not either <code>YES_NO_OPTION</code>,
+   * <code>YES_NO_CANCEL_OPTION</code>, or <code>OK_CANCEL_OPTION</code>, or if
+   * <code>defaultOption</code> does not correspond to one of the options in
+   * <code>optionType</code>.
+   */
+  public ConfirmationCallback(int messageType, int optionType, int defaultOption)
+    throws IllegalArgumentException
+  {
+    super();
+
+    setMessageType(messageType);
+    setOptionType(optionType, defaultOption);
+    this.defaultOption = defaultOption;
+  }
+
+  /**
+   * <p>Construct a <code>ConfirmationCallback</code> with a message type, a
+   * list of options and a default option.</p>
+   *
+   * <p>Underlying security services use this constructor if they require a
+   * confirmation different from the available preset confirmations provided
+   * (for example, CONTINUE/ABORT or STOP/GO). The confirmation options are
+   * listed in the <code>options</code> array, and are displayed by the
+   * {@link CallbackHandler} implementation in a manner consistent with the
+   * way preset options are displayed.</p>
+   *
+   * @param messageType the message type (INFORMATION, WARNING or ERROR).
+   * @param options the list of confirmation options.
+   * @param defaultOption the default option, represented as an index into the
+   * <code>options</code> array.
+   * @throws IllegalArgumentException if <code>messageType</code> is not either
+   * <code>INFORMATION</code>, <code>WARNING</code>, or <code>ERROR</code>, if
+   * <code>options</code> is <code>null</code>, if <code>options</code> has a
+   * length of <code>0</code>, if any element from <code>options</code> is
+   * <code>null</code>, if any element from <code>options</code> has a length
+   * of <code>0</code>, or if <code>defaultOption</code> does not lie within
+   * the array boundaries of <code>options</code>.
+   */
+  public ConfirmationCallback(int messageType, String[] options, int defaultOption)
+  {
+    super();
+
+    setMessageType(messageType);
+    setOptions(options, defaultOption);
+    this.defaultOption = defaultOption;
+  }
+
+  /**
+   * <p>Construct a <code>ConfirmationCallback</code> with a prompt, message
+   * type, an option type and a default option.</p>
+   *
+   * <p>Underlying security services use this constructor if they require
+   * either a YES/NO, YES/NO/CANCEL or OK/CANCEL confirmation.</p>
+   *
+   * @param prompt the prompt used to describe the list of options.
+   * @param messageType the message type (INFORMATION, WARNING or ERROR).
+   * @param optionType the option type (YES_NO_OPTION, YES_NO_CANCEL_OPTION or
+   * OK_CANCEL_OPTION).
+   * @param defaultOption the default option from the provided optionType (YES,
+   * NO, CANCEL or OK).
+   * @throws IllegalArgumentException if <code>prompt</code> is <code>null</code>,
+   * if <code>prompt</code> has a length of <code>0</code>, if
+   * <code>messageType</code> is not either <code>INFORMATION</code>,
+   * <code>WARNING</code>, or <code>ERROR</code>, if <code>optionType</code> is
+   * not either <code>YES_NO_OPTION</code>, <code>YES_NO_CANCEL_OPTION</code>,
+   * or <code>OK_CANCEL_OPTION</code>, or if <code>defaultOption</code> does
+   * not correspond to one of the options in <code>optionType</code>.
+   */
+  public ConfirmationCallback(String prompt, int messageType, int optionType,
+                              int defaultOption)
+  {
+    super();
+
+    setPrompt(prompt);
+    setMessageType(messageType);
+    setOptionType(optionType, defaultOption);
+    this.defaultOption = defaultOption;
+  }
+
+  /**
+   * <p>Construct a <code>ConfirmationCallback</code> with a prompt, message
+   * type, a list of options and a default option.</p>
+   *
+   * <p>Underlying security services use this constructor if they require a
+   * confirmation different from the available preset confirmations provided
+   * (for example, CONTINUE/ABORT or STOP/GO). The confirmation options are
+   * listed in the <code>options</code> array, and are displayed by the
+   * {@link CallbackHandler} implementation in a manner consistent with the
+   * way preset options are displayed.</p>
+   *
+   * @param prompt the prompt used to describe the list of options.
+   * @param messageType the message type (INFORMATION, WARNING or ERROR).
+   * @param options the list of confirmation options.
+   * @param defaultOption the default option, represented as an index into the
+   * <code>options</code> array.
+   * @throws IllegalArgumentException if <code>prompt</code> is <code>null</code>,
+   * if <code>prompt</code> has a length of <code>0</code>, if
+   * <code>messageType</code> is not either <code>INFORMATION</code>,
+   * <code>WARNING</code>, or <code>ERROR</code>, if <code>options</code> is
+   * <code>null</code>, if <code>options</code> has a length of <code>0</code>,
+   * if any element from <code>options</code> is <code>null</code>, if any
+   * element from <code>options</code> has a length of <code>0</code>, or if
+   * <code>defaultOption</code> does not lie within the array boundaries of
+   * <code>options</code>.
+   */
+  public ConfirmationCallback(String prompt, int messageType, String[] options,
+                              int defaultOption)
+  {
+    super();
+
+    setPrompt(prompt);
+    setMessageType(messageType);
+    setOptions(options, defaultOption);
+    this.defaultOption = defaultOption;
+  }
+
+  // Class methods
+  // -------------------------------------------------------------------------
+
+  // Instance methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Get the prompt.
+   *
+   * @return the prompt, or <code>null</code> if this
+   * <code>ConfirmationCallback</code> was instantiated without a prompt.
+   */
+  public String getPrompt()
+  {
+    return prompt;
+  }
+
+  /**
+   * Get the message type.
+   *
+   * @return the message type (INFORMATION, WARNING or ERROR).
+   */
+  public int getMessageType()
+  {
+    return messageType;
+  }
+
+  /**
+   * <p>Get the option type.</p>
+   *
+   * <p>If this method returns {@link #UNSPECIFIED_OPTION}, then this
+   * <code>ConfirmationCallback</code> was instantiated with <code>options</code>
+   * instead of an <code>optionType</code>. In this case, invoke the
+   * {@link #getOptions()} method to determine which confirmation options to
+   * display.</p>
+   *
+   * @return the option type (YES_NO_OPTION, YES_NO_CANCEL_OPTION or
+   * OK_CANCEL_OPTION), or UNSPECIFIED_OPTION if this
+   * <code>ConfirmationCallback</code> was instantiated with <code>options</code>
+   * instead of an <code>optionType</code>.
+   */
+  public int getOptionType()
+  {
+    if (options != null)
+      {
+        return UNSPECIFIED_OPTION;
+      }
+    return optionType;
+  }
+
+  /**
+   * Get the confirmation options.
+   *
+   * @return the list of confirmation options, or <code>null</code> if this
+   * <code>ConfirmationCallback</code> was instantiated with an
+   * <code>optionType</code> instead of <code>options</code>.
+   */
+  public String[] getOptions()
+  {
+    return options;
+  }
+
+  /**
+   * Get the default option.
+   *
+   * @return the default option, represented as <code>YES</code>, <code>NO</code>,
+   * <code>OK</code> or <code>CANCEL</code> if an <code>optionType</code> was
+   * specified to the constructor of this <code>ConfirmationCallback</code>.
+   * Otherwise, this method returns the default option as an index into the
+   * <code>options</code> array specified to the constructor of this
+   * <code>ConfirmationCallback</code>.
+   */
+  public int getDefaultOption()
+  {
+    return defaultOption;
+  }
+
+  /**
+   * Set the selected confirmation option.
+   *
+   * @param selection the selection represented as <code>YES</code>,
+   * <code>NO</code>, <code>OK</code> or <code>CANCEL</code> if an
+   * <code>optionType</code> was specified to the constructor of this
+   * <code>ConfirmationCallback</code>. Otherwise, the <code>selection</code>
+   * represents the index into the <code>options</code> array specified to the
+   * constructor of this <code>ConfirmationCallback</code>.
+   * @see #getSelectedIndex()
+   */
+  public void setSelectedIndex(int selection)
+  {
+    if (options != null)
+      {
+        setOptions(options, selection);
+      }
+    else
+      {
+        setOptionType(optionType, selection);
+      }
+  }
+
+  /**
+   * Get the selected confirmation option.
+   *
+   * @return the selected confirmation option represented as <code>YES</code>,
+   * <code>NO</code>, <code>OK</code> or <code>CANCEL</code> if an
+   * <code>optionType</code> was specified to the constructor of this
+   * <code>ConfirmationCallback</code>. Otherwise, this method returns the
+   * selected confirmation option as an index into the <code>options</code>
+   * array specified to the constructor of this <code>ConfirmationCallback</code>.
+   * @see #setSelectedIndex(int)
+   */
+  public int getSelectedIndex()
+  {
+    return this.selection;
+  }
+
+  private void setMessageType(int messageType) throws IllegalArgumentException
+  {
+    switch (messageType)
+      {
+      case INFORMATION:
+      case WARNING:
+      case ERROR: this.messageType = messageType; break;
+      default: throw new IllegalArgumentException("illegal message type");
+      }
+  }
+
+  private void setOptionType(int optionType, int selectedOption)
+    throws IllegalArgumentException
+  {
+    switch (optionType)
+      {
+      case YES_NO_OPTION:
+        this.optionType = optionType;
+        switch (selectedOption)
+          {
+          case YES:
+          case NO: this.selection = selectedOption; break;
+          default: throw new IllegalArgumentException("invalid option");
+          }
+        break;
+      case YES_NO_CANCEL_OPTION:
+        this.optionType = optionType;
+        switch (selectedOption)
+          {
+          case YES:
+          case NO:
+          case CANCEL: this.selection = selectedOption; break;
+          default: throw new IllegalArgumentException("invalid option");
+          }
+        break;
+      case OK_CANCEL_OPTION:
+        this.optionType = optionType;
+        switch (selectedOption)
+          {
+          case OK:
+          case CANCEL: this.selection = selectedOption; break;
+          default: throw new IllegalArgumentException("invalid option");
+          }
+        break;
+      default:
+        throw new IllegalArgumentException("illegal option type");
+      }
+  }
+
+  private void setOptions(String[] options, int selectedOption)
+    throws IllegalArgumentException
+  {
+    if ((selectedOption < 0) || (selectedOption > options.length - 1))
+      {
+        throw new IllegalArgumentException("invalid selection");
+      }
+    if ((options == null) || (options.length == 0))
+      {
+        throw new IllegalArgumentException("options is null or empty");
+      }
+    for (int i = 0; i < options.length; i++)
+      {
+        if ((options[i] == null) || (options[i].length() == 0))
+          {
+            throw new IllegalArgumentException("options[" + i + "] is null or empty");
+          }
+      }
+    this.options = options;
+    this.selection = selectedOption;
+  }
+
+  private void setPrompt(String prompt) throws IllegalArgumentException
+  {
+    if ((prompt == null) || (prompt.length() == 0))
+      {
+        throw new IllegalArgumentException("prompt is null or empty");
+      }
+    this.prompt = prompt;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/callback/LanguageCallback.java b/libjava/classpath/javax/security/auth/callback/LanguageCallback.java
new file mode 100644
index 000000000..e0190e6cc
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/LanguageCallback.java
@@ -0,0 +1,100 @@
+/* LanguageCallback.java -- callback for language choices.
+   Copyright (C) 2003, 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.callback;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+/**
+ * Underlying security services instantiate and pass a <code>LanguageCallback</code>
+ * to the <code>handle()</code> method of a {@link CallbackHandler} to retrieve
+ * the {@link Locale} used for localizing text.
+ *
+ * @see CallbackHandler
+ */
+public class LanguageCallback implements Callback, Serializable
+{
+
+  // Constants and variables
+  // -------------------------------------------------------------------------
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private Locale locale;
+
+  // Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /** Construct a <code>LanguageCallback</code>. */
+  public LanguageCallback()
+  {
+    super();
+  }
+
+  // Class methods
+  // -------------------------------------------------------------------------
+
+  // Instance methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Set the retrieved Locale.
+   *
+   * @param locale the retrieved Locale.
+   * @see #getLocale()
+   */
+  public void setLocale(Locale locale)
+  {
+    this.locale = locale;
+  }
+
+  /**
+   * Get the retrieved Locale.
+   *
+   * @return the retrieved Locale, or <code>null</code> if no Locale could be
+   * retrieved.
+   * @see #setLocale(Locale)
+   */
+  public Locale getLocale()
+  {
+    return locale;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/callback/NameCallback.java b/libjava/classpath/javax/security/auth/callback/NameCallback.java
new file mode 100644
index 000000000..4b8bf1c69
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/NameCallback.java
@@ -0,0 +1,178 @@
+/* NameCallback.java -- callback for user names.
+   Copyright (C) 2003, 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.callback;
+
+import java.io.Serializable;
+
+/**
+ * Underlying security services instantiate and pass a <code>NameCallback</code>
+ * to the <code>handle()</code> method of a {@link CallbackHandler} to retrieve
+ * name information.
+ *
+ * @see CallbackHandler
+ */
+public class NameCallback implements Callback, Serializable
+{
+
+  // Constants and variables
+  // -------------------------------------------------------------------------
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String prompt;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String defaultName;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String inputName;
+
+  // Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * Construct a <code>NameCallback</code> with a prompt.
+   *
+   * @param prompt the prompt used to request the name.
+   * @throws IllegalArgumentException if <code>prompt</code> is <code>null</code>
+   * or if <code>prompt</code> has a length of <code>0</code>.
+   */
+  public NameCallback(String prompt)
+  {
+    super();
+
+    setPrompt(prompt);
+  }
+
+  /**
+   * Construct a <code>NameCallback</code> with a prompt and default name.
+   *
+   * @param prompt the prompt used to request the information.
+   * @param defaultName the name to be used as the default name displayed with
+   * the prompt.
+   * @throws IllegalArgumentException if <code>prompt</code> is <code>null</code>
+   * or if <code>prompt</code> has a length of <code>0</code>, if
+   * <code>defaultName</code> is <code>null</code>, or if <code>defaultName</code>
+   * has a length of <code>0</code>.
+   */
+  public NameCallback(String prompt, String defaultName)
+    throws IllegalArgumentException
+  {
+    super();
+
+    setPrompt(prompt);
+    setDefaultName(defaultName);
+  }
+
+  // Class methods
+  // -------------------------------------------------------------------------
+
+  // Instance methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Get the prompt.
+   *
+   * @return the prompt.
+   */
+  public String getPrompt()
+  {
+    return prompt;
+  }
+
+  /**
+   * Get the default name.
+   *
+   * @return the default name, or <code>null</code> if this
+   * <code>NameCallback</code> was not instantiated with a
+   * <code>defaultName</code>.
+   */
+  public String getDefaultName()
+  {
+    return defaultName;
+  }
+
+  /**
+   * Set the retrieved name.
+   *
+   * @param name the retrieved name (which may be <code>null</code>).
+   * @see #getName()
+   */
+  public void setName(String name)
+  {
+    this.inputName = name;
+  }
+
+  /**
+   * Get the retrieved name.
+   *
+   * @return the retrieved name (which may be <code>null</code>)
+   * @see #setName(String)
+   */
+  public String getName()
+  {
+    return inputName;
+  }
+
+  private void setPrompt(String prompt) throws IllegalArgumentException
+  {
+    if ((prompt == null) || (prompt.length() == 0))
+      {
+        throw new IllegalArgumentException("invalid prompt");
+      }
+    this.prompt = prompt;
+  }
+
+  private void setDefaultName(String defaultName) throws IllegalArgumentException
+  {
+    if ((defaultName == null) || (defaultName.length() == 0))
+      {
+        throw new IllegalArgumentException("invalid default name");
+      }
+    this.defaultName = defaultName;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/callback/PasswordCallback.java b/libjava/classpath/javax/security/auth/callback/PasswordCallback.java
new file mode 100644
index 000000000..6309aacba
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/PasswordCallback.java
@@ -0,0 +1,168 @@
+/* PasswordCallback.java -- callback for passwords.
+   Copyright (C) 2003, 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.callback;
+
+import java.io.Serializable;
+
+/**
+ * Underlying security services instantiate and pass a <code>PasswordCallback</code>
+ * to the <code>handle()</code> method of a {@link CallbackHandler} to retrieve
+ * password information.
+ *
+ * @see CallbackHandler,
+ */
+public class PasswordCallback implements Callback, Serializable
+{
+
+  // Constants and variables
+  // -------------------------------------------------------------------------
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String prompt;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private boolean echoOn;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private char[] inputPassword;
+
+  // Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * Construct a <code>PasswordCallback</code> with a prompt and a boolean
+   * specifying whether the password should be displayed as it is being typed.
+   *
+   * @param prompt the prompt used to request the password.
+   * @param echoOn <code>true</code> if the password should be displayed as it
+   * is being typed.
+   * @throws IllegalArgumentException if <code>prompt</code> is <code>null</code>
+   * or if <code>prompt</code> has a length of <code>0</code>.
+   */
+  public PasswordCallback(String prompt, boolean echoOn)
+  {
+    super();
+
+    setPrompt(prompt);
+    this.echoOn = echoOn;
+  }
+
+  // Class methods
+  // -------------------------------------------------------------------------
+
+  // Instance methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Get the prompt.
+   *
+   * @return the prompt.
+   */
+  public String getPrompt()
+  {
+    return prompt;
+  }
+
+  /**
+   * Return whether the password should be displayed as it is being typed.
+   *
+   * @return the whether the password should be displayed as it is being typed.
+   */
+  public boolean isEchoOn()
+  {
+    return echoOn;
+  }
+
+  /**
+   * <p>Set the retrieved password.</p>
+   *
+   * <p>This method makes a copy of the input password before storing it.</p>
+   *
+   * @param password the retrieved password, which may be <code>null</code>.
+   * @see #getPassword()
+   */
+  public void setPassword(char[] password)
+  {
+    inputPassword = (password == null ? null : (char[]) password.clone());
+  }
+
+  /**
+   * <p>Get the retrieved password.</p>
+   *
+   * <p>This method returns a copy of the retrieved password.</p>
+   *
+   * @return the retrieved password, which may be <code>null</code>.
+   * @see #setPassword(char[])
+   */
+  public char[] getPassword()
+  {
+    return (inputPassword == null ? null : (char[]) inputPassword.clone());
+  }
+
+  /** Clear the retrieved password. */
+  public void clearPassword()
+  {
+    if (inputPassword != null)
+      {
+        for (int i = 0; i < inputPassword.length; i++)
+          {
+            inputPassword[i] = '\0';
+          }
+        inputPassword = null;
+      }
+  }
+
+  private void setPrompt(String prompt) throws IllegalArgumentException
+  {
+    if ((prompt == null) || (prompt.length() == 0))
+      {
+        throw new IllegalArgumentException("invalid prompt");
+      }
+    this.prompt = prompt;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/callback/TextInputCallback.java b/libjava/classpath/javax/security/auth/callback/TextInputCallback.java
new file mode 100644
index 000000000..1fe071327
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/TextInputCallback.java
@@ -0,0 +1,177 @@
+/* TextInputCallback.java -- callbacks for user input.
+   Copyright (C) 2003, 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.callback;
+
+import java.io.Serializable;
+
+/**
+ * Underlying security services instantiate and pass a <code>TextInputCallback</code>
+ * to the <code>handle()</code> method of a {@link CallbackHandler} to retrieve
+ * generic text information.
+ *
+ * @see CallbackHandler
+ */
+public class TextInputCallback implements Callback, Serializable
+{
+
+  // Constants and variables
+  // -------------------------------------------------------------------------
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String prompt;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String defaultText;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String inputText;
+
+  // Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * Construct a <code>TextInputCallback</code> with a prompt.
+   *
+   * @param prompt the prompt used to request the information.
+   * @throws IllegalArgumentException if <code>prompt</code> is <code>null</code>
+   * or if <code>prompt</code> has a length of <code>0</code>.
+   */
+  public TextInputCallback(String prompt) throws IllegalArgumentException
+  {
+    super();
+
+    setPrompt(prompt);
+  }
+
+  /**
+   * Construct a <code>TextInputCallback</code> with a prompt and default
+   * input value.
+   *
+   * @param prompt the prompt used to request the information.
+   * @param defaultText the text to be used as the default text displayed with
+   * the prompt.
+   * @throws IllegalArgumentException if <code>prompt</code> is <code>null</code>,
+   * if <code>prompt</code> has a length of <code>0</code>, if
+   * <code>defaultText</code> is <code>null</code> or if <code>defaultText</code>
+   * has a length of <code>0</code>.
+   */
+  public TextInputCallback(String prompt, String defaultText)
+    throws IllegalArgumentException
+  {
+    super();
+
+    setPrompt(prompt);
+    setDefaultText(defaultText);
+  }
+
+  // Class methods
+  // -------------------------------------------------------------------------
+
+  // Instance methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Get the prompt.
+   *
+   * @return the prompt.
+   */
+  public String getPrompt()
+  {
+    return prompt;
+  }
+
+  /**
+   * Get the default text.
+   *
+   * @return the default text, or <code>null</code> if this
+   * <code>TextInputCallback</code> was not instantiated with
+   * <code>defaultText</code>.
+   */
+  public String getDefaultText()
+  {
+    return defaultText;
+  }
+
+  /**
+   * Set the retrieved text.
+   *
+   * @param text the retrieved text, which may be <code>null</code>.
+   */
+  public void setText(String text)
+  {
+    this.inputText = text;
+  }
+
+  /**
+   * Get the retrieved text.
+   *
+   * @return the retrieved text, which may be <code>null</code>.
+   */
+  public String getText()
+  {
+    return inputText;
+  }
+
+  private void setPrompt(String prompt) throws IllegalArgumentException
+  {
+    if ((prompt == null) || (prompt.length() == 0))
+      {
+        throw new IllegalArgumentException("invalid prompt");
+      }
+    this.prompt = prompt;
+  }
+
+  private void setDefaultText(String defaultText) throws IllegalArgumentException
+  {
+    if ((defaultText == null) || (defaultText.length() == 0))
+      {
+        throw new IllegalArgumentException("invalid default text");
+      }
+    this.defaultText = defaultText;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/callback/TextOutputCallback.java b/libjava/classpath/javax/security/auth/callback/TextOutputCallback.java
new file mode 100644
index 000000000..0ab3a040f
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/TextOutputCallback.java
@@ -0,0 +1,140 @@
+/* TextOutputCallback.java -- callback for text output.
+   Copyright (C) 2003 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.callback;
+
+import java.io.Serializable;
+
+/**
+ * <p>Underlying security services instantiate and pass a
+ * <code>TextOutputCallback</code> to the <code>handle()</code> method of a
+ * {@link CallbackHandler} to display information messages, warning messages and
+ * error messages.</p>
+ *
+ * @see CallbackHandler
+ */
+public class TextOutputCallback implements Callback, Serializable
+{
+
+  // Constants and variables
+  // -------------------------------------------------------------------------
+
+  /** Information message */
+  public static final int INFORMATION = 0;
+
+  /** Warning message */
+  public static final int WARNING = 1;
+
+  /** Error message */
+  public static final int ERROR = 2;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private int messageType;
+
+  /**
+   * @serial
+   * @since 1.4
+   */
+  private String message;
+
+  // Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * <p>Construct a <code>TextOutputCallback</code> with a message type and
+   * message to be displayed.</p>
+   *
+   * @param messageType the message type (INFORMATION, WARNING or ERROR).
+   * @param message the message to be displayed.
+   * @throws IllegalArgumentException if <code>messageType</code> is not either
+   * <code>INFORMATION</code>, <code>WARNING</code> or <code>ERROR</code>, if
+   * <code>message</code> is <code>null</code>, or if <code>message</code> has
+   * a length of <code>0</code>.
+   */
+  public TextOutputCallback(int messageType, String message)
+    throws IllegalArgumentException
+  {
+    switch (messageType)
+      {
+      case INFORMATION:
+      case WARNING:
+      case ERROR: this.messageType = messageType; break;
+      default: throw new IllegalArgumentException("invalid message type");
+      }
+
+    setMessage(message);
+  }
+
+  // Class methods
+  // -------------------------------------------------------------------------
+
+  // Instance methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * <p>Returns the message's <code>messageType</code>.</p>
+   *
+   * @return the message type (INFORMATION, WARNING or ERROR).
+   */
+  public int getMessageType()
+  {
+    return messageType;
+  }
+
+  /**
+   * <p>Returns the <code>message</code> to be displayed.</p>
+   *
+   * @return the message to be displayed.
+   */
+  public String getMessage()
+  {
+    return message;
+  }
+
+  private void setMessage(String message) throws IllegalArgumentException
+  {
+    if ((message == null) || (message.length() == 0))
+      {
+        throw new IllegalArgumentException("invalid message");
+      }
+    this.message = message;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/callback/UnsupportedCallbackException.java b/libjava/classpath/javax/security/auth/callback/UnsupportedCallbackException.java
new file mode 100644
index 000000000..f5308b9ea
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/UnsupportedCallbackException.java
@@ -0,0 +1,101 @@
+/* UnsupportedCallbackException.java -- signals an unsupported callback type.
+   Copyright (C) 2003, 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.callback;
+
+/**
+ * Signals that a {@link CallbackHandler} does not recognize a particular
+ * {@link Callback}.
+ *
+ */
+public class UnsupportedCallbackException extends Exception
+{
+
+  // Constants and variables
+  // -------------------------------------------------------------------------
+
+  /** @serial */
+  private Callback callback;
+
+  // Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * Constructs an <code>UnsupportedCallbackException</code> with no detail
+   * message.
+   *
+   * @param callback the unrecognized {@link Callback}.
+   */
+  public UnsupportedCallbackException(Callback callback)
+  {
+    super();
+
+    this.callback = callback;
+  }
+
+  /**
+   * Constructs an <code>UnsupportedCallbackException</code> with the specified
+   * detail message. A detail message is a {@link String} that describes this
+   * particular exception.
+   *
+   * @param callback the unrecognized {@link Callback}.
+   * @param msg the detail message.
+   */
+  public UnsupportedCallbackException(Callback callback, String msg)
+  {
+    super(msg);
+
+    this.callback = callback;
+  }
+
+  // Class methods
+  // -------------------------------------------------------------------------
+
+  // Instance methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Get the unrecognized {@link Callback}.
+   *
+   * @return the unrecognized {@link Callback}.
+   */
+  public Callback getCallback()
+  {
+    return this.callback;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/callback/package.html b/libjava/classpath/javax/security/auth/callback/package.html
new file mode 100644
index 000000000..f927f1c30
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/callback/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.security.auth.callback package.
+   Copyright (C) 2004 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. -->
+
+<html>
+<head><title>GNU Classpath - javax.security.auth.callback</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
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);
+      }
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/AccountException.java b/libjava/classpath/javax/security/auth/login/AccountException.java
new file mode 100644
index 000000000..32f739a31
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/AccountException.java
@@ -0,0 +1,64 @@
+/* AccountException.java -- generic account exception
+   Copyright (C) 2005 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.login;
+
+/**
+ * This is the base class for various account-related exceptions.
+ * @since 1.5
+ */
+public class AccountException extends LoginException
+{
+  private static final long serialVersionUID = -2112878680072211787L;
+
+  /**
+   * Create a new exception object.
+   */
+  public AccountException()
+  {
+  }
+
+  /**
+   * Create a new exception with the indicated detail message.
+   * @param message the detail message
+   */
+  public AccountException(String message)
+  {
+    super(message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/AccountExpiredException.java b/libjava/classpath/javax/security/auth/login/AccountExpiredException.java
new file mode 100644
index 000000000..c2b61c6e0
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/AccountExpiredException.java
@@ -0,0 +1,64 @@
+/* AccountExpiredException.java
+   Copyright (C) 2004 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.login;
+
+/**
+ * An exception that signals that an attempt was made to login to an account
+ * that has expired.
+ */
+public class AccountExpiredException extends AccountException
+{
+
+  // Constant.
+  // -------------------------------------------------------------------------
+
+  private static final long serialVersionUID = -6064064890162661560L;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  public AccountExpiredException()
+  {
+  }
+
+  public AccountExpiredException (String message)
+  {
+    super (message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/AccountLockedException.java b/libjava/classpath/javax/security/auth/login/AccountLockedException.java
new file mode 100644
index 000000000..bcb8b4f8d
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/AccountLockedException.java
@@ -0,0 +1,64 @@
+/* AccountLockedException.java -- exception indicating locked account
+   Copyright (C) 2005 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.login;
+
+/**
+ * An exception indicating that an account is locked.
+ * @since 1.5
+ */
+public class AccountLockedException extends AccountException
+{
+  private static final long serialVersionUID = 8280345554014066334L;
+
+  /**
+   * Create a new exception object.
+   */
+  public AccountLockedException()
+  {
+  }
+
+  /**
+   * Create a new exception with the indicated detail message.
+   * @param message the detail message
+   */
+  public AccountLockedException(String message)
+  {
+    super(message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/AccountNotFoundException.java b/libjava/classpath/javax/security/auth/login/AccountNotFoundException.java
new file mode 100644
index 000000000..e74ca0163
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/AccountNotFoundException.java
@@ -0,0 +1,64 @@
+/* AccountNotFoundException.java -- exception indicating account not found
+   Copyright (C) 2005 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.login;
+
+/**
+ * An exception indicating that an account was not found.
+ * @since 1.5
+ */
+public class AccountNotFoundException extends AccountException
+{
+  private static final long serialVersionUID = 1498349563916294614L;
+
+  /**
+   * Create a new exception object.
+   */
+  public AccountNotFoundException()
+  {
+  }
+
+  /**
+   * Create a new exception with the given detail message.
+   * @param message the detail message
+   */
+  public AccountNotFoundException(String message)
+  {
+    super(message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/AppConfigurationEntry.java b/libjava/classpath/javax/security/auth/login/AppConfigurationEntry.java
new file mode 100644
index 000000000..044c9105b
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/AppConfigurationEntry.java
@@ -0,0 +1,143 @@
+/* AppConfigurationEntry.java
+   Copyright (C) 2004, 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.login;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AppConfigurationEntry
+{
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private final String loginModuleName;
+  private final LoginModuleControlFlag controlFlag;
+  private final Map options;
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  public AppConfigurationEntry (final String loginModuleName,
+                                final LoginModuleControlFlag controlFlag,
+                                final Map<String, ?> options)
+  {
+    if (loginModuleName == null || loginModuleName.length() == 0)
+      throw new IllegalArgumentException ("module name cannot be null nor empty");
+
+    if (LoginModuleControlFlag.OPTIONAL != controlFlag &&
+        LoginModuleControlFlag.REQUIRED != controlFlag &&
+        LoginModuleControlFlag.REQUISITE != controlFlag &&
+        LoginModuleControlFlag.SUFFICIENT != controlFlag)
+      throw new IllegalArgumentException ("invalid controlFlag");
+
+    if (options == null)
+      throw new IllegalArgumentException ("options cannot be null");
+
+    this.loginModuleName = loginModuleName;
+    this.controlFlag = controlFlag;
+    this.options = Collections.unmodifiableMap (new HashMap (options));
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public LoginModuleControlFlag getControlFlag()
+  {
+    return controlFlag;
+  }
+
+  public String getLoginModuleName()
+  {
+    return loginModuleName;
+  }
+
+  public Map<String, ?> getOptions()
+  {
+    return options;
+  }
+
+  // Object methods ----------------------------------------------------------
+
+  public String toString()
+  {
+
+    return loginModuleName + "\t"
+        + String.valueOf(controlFlag) + "\t"
+        + String.valueOf(options);
+  }
+
+  // Inner class.
+  // -------------------------------------------------------------------------
+
+  public static class LoginModuleControlFlag
+  {
+
+    // Constants.
+    // -----------------------------------------------------------------------
+
+    public static final LoginModuleControlFlag OPTIONAL = new LoginModuleControlFlag();
+    public static final LoginModuleControlFlag REQUIRED = new LoginModuleControlFlag();
+    public static final LoginModuleControlFlag REQUISITE = new LoginModuleControlFlag();
+    public static final LoginModuleControlFlag SUFFICIENT = new LoginModuleControlFlag();
+
+    // Constructor.
+    // -----------------------------------------------------------------------
+
+    private LoginModuleControlFlag()
+    {
+    }
+
+    // Instance methods.
+    // -----------------------------------------------------------------------
+
+    public String toString()
+    {
+      if (this == LoginModuleControlFlag.REQUIRED)
+        return "REQUIRED";
+      if (this == LoginModuleControlFlag.REQUISITE)
+        return "REQUISITE";
+      if (this == LoginModuleControlFlag.SUFFICIENT)
+        return "SUFFICIENT";
+      if (this == LoginModuleControlFlag.OPTIONAL)
+        return "OPTIONAL";
+      return "???";
+    }
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/Configuration.java b/libjava/classpath/javax/security/auth/login/Configuration.java
new file mode 100644
index 000000000..fe56f8a59
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/Configuration.java
@@ -0,0 +1,121 @@
+/* Configuration.java
+   Copyright (C) 2004, 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.login;
+
+import gnu.javax.security.auth.login.GnuConfiguration;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Security;
+
+import javax.security.auth.AuthPermission;
+
+public abstract class Configuration
+{
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private static Configuration config;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  protected Configuration()
+  {
+  }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  public static synchronized Configuration getConfiguration()
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkPermission (new AuthPermission ("getLoginConfiguration"));
+    return getConfig();
+  }
+
+  public static synchronized void setConfiguration (Configuration config)
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkPermission (new AuthPermission ("setLoginConfiguration"));
+    Configuration.config = config;
+  }
+
+  // Abstract methods.
+  // -------------------------------------------------------------------------
+
+  public abstract AppConfigurationEntry[] getAppConfigurationEntry (String applicationName);
+
+  public abstract void refresh();
+
+  // Package-private methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Get the current configuration, bypassing security checks.
+   */
+  static Configuration getConfig()
+  {
+    if (config == null)
+      {
+        String conf = (String) AccessController.doPrivileged
+          (new PrivilegedAction()
+            {
+              public Object run()
+              {
+                return Security.getProperty ("login.configuration.provider");
+              }
+            });
+        try
+          {
+            if (conf != null)
+              config = (Configuration) Class.forName (conf).newInstance();
+            else
+              config = new GnuConfiguration();
+          }
+        catch (Exception x)
+          {
+            config = new GnuConfiguration();
+          }
+      }
+    return config;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/CredentialException.java b/libjava/classpath/javax/security/auth/login/CredentialException.java
new file mode 100644
index 000000000..980adde9e
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/CredentialException.java
@@ -0,0 +1,64 @@
+/* CredentialException.java -- generic credential exception
+   Copyright (C) 2005 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.login;
+
+/**
+ * This is the base class for various credential-related exceptions.
+ * @since 1.5
+ */
+public class CredentialException extends LoginException
+{
+  private static final long serialVersionUID = -4772893876810601859L;
+
+  /**
+   * Create a new exception object.
+   */
+  public CredentialException()
+  {
+  }
+
+  /**
+   * Create a new exception with the given detail message.
+   * @param message the detail message
+   */
+  public CredentialException(String message)
+  {
+    super(message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/CredentialExpiredException.java b/libjava/classpath/javax/security/auth/login/CredentialExpiredException.java
new file mode 100644
index 000000000..9827a3d86
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/CredentialExpiredException.java
@@ -0,0 +1,64 @@
+/* CredentialExpiredException.java
+   Copyright (C) 2004 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.login;
+
+/**
+ * An exception that signals an attempt to login with a credential that
+ * has expired.
+ */
+public class CredentialExpiredException extends CredentialException
+{
+
+  // Constant.
+  // -------------------------------------------------------------------------
+
+  private static final long serialVersionUID = -5344739593859737937L;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  public CredentialExpiredException()
+  {
+  }
+
+  public CredentialExpiredException (String message)
+  {
+    super (message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/CredentialNotFoundException.java b/libjava/classpath/javax/security/auth/login/CredentialNotFoundException.java
new file mode 100644
index 000000000..08ac115e3
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/CredentialNotFoundException.java
@@ -0,0 +1,65 @@
+/* CredentialNotFoundException.java -- exception thrown when credentials
+   expire
+   Copyright (C) 2005 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.login;
+
+/**
+ * An exception that indicates that a credential was not found.
+ * @since 1.5
+ */
+public class CredentialNotFoundException extends CredentialException
+{
+  private static final long serialVersionUID = -7779934467214319475L;
+
+  /**
+   * Create a new exception.
+   */
+  public CredentialNotFoundException()
+  {
+  }
+
+  /**
+   * Create a new exception with the given detail message.
+   * @param message the detail message
+   */
+  public CredentialNotFoundException(String message)
+  {
+    super(message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/FailedLoginException.java b/libjava/classpath/javax/security/auth/login/FailedLoginException.java
new file mode 100644
index 000000000..db975fbdd
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/FailedLoginException.java
@@ -0,0 +1,63 @@
+/* FailedLoginException.java
+   Copyright (C) 2004 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.login;
+
+/**
+ * An exception that signals that an attempt to login was unsuccessful.
+ */
+public class FailedLoginException extends LoginException
+{
+
+  // Constant.
+  // -------------------------------------------------------------------------
+
+  private static final long serialVersionUID = 802556922354616286L;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  public FailedLoginException()
+  {
+  }
+
+  public FailedLoginException (String message)
+  {
+    super (message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/LoginContext.java b/libjava/classpath/javax/security/auth/login/LoginContext.java
new file mode 100644
index 000000000..b2e4b97b6
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/LoginContext.java
@@ -0,0 +1,265 @@
+/* LoginContext.java
+   Copyright (C) 2004, 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.login;
+
+import gnu.java.security.action.GetSecurityPropertyAction;
+
+import java.security.AccessController;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.spi.LoginModule;
+
+public class LoginContext
+{
+
+  private static final String OTHER = "other";
+
+  private final String name;
+  private final CallbackHandler cbHandler;
+  private final Subject subject;
+  private final AppConfigurationEntry[] entries;
+  private final LoginModule[] modules;
+  private final Map sharedState;
+
+  public LoginContext (final String name) throws LoginException
+  {
+    this (name, new Subject(), defaultHandler());
+  }
+
+  public LoginContext (final String name, final CallbackHandler cbHandler)
+    throws LoginException
+  {
+    this (name, new Subject(), cbHandler);
+  }
+
+  public LoginContext (final String name, final Subject subject)
+    throws LoginException
+  {
+    this (name, subject, defaultHandler());
+  }
+
+  public LoginContext (final String name, final Subject subject,
+                       final CallbackHandler cbHandler)
+    throws LoginException
+  {
+    this (name, subject, cbHandler, null);
+  }
+
+  /** @since 1.5 */
+  public LoginContext (final String name, final Subject subject,
+                       final CallbackHandler cbHandler,
+                       Configuration config)
+    throws LoginException
+  {
+    this.name = name;
+    this.subject = subject;
+    this.cbHandler = cbHandler;
+    if (config == null)
+      config = Configuration.getConfig();
+    AppConfigurationEntry[] entries = config.getAppConfigurationEntry (name);
+    if (entries == null)
+      entries = config.getAppConfigurationEntry (OTHER);
+    if (entries == null)
+      throw new LoginException ("no configured modules for application "
+                                + name);
+    this.entries = entries;
+    modules = new LoginModule[entries.length];
+    sharedState = new HashMap();
+    for (int i = 0; i < entries.length; i++)
+      modules[i] = lookupModule (entries[i], subject, sharedState);
+  }
+
+  /**
+   * Returns the authenticated subject, or the parameter passed to one
+   * of the constructors. <code>null</code> is returned if the previous
+   * login attempt failed and there was no subject provided.
+   *
+   * @return The subject, or null.
+   */
+  public Subject getSubject()
+  {
+    return subject;
+  }
+
+  /**
+   * Logs a subject in, using all login modules configured for this
+   * application. This method will call the {@link LoginModule#login()}
+   * method of each module configured for this application, stopping
+   * if a REQUISITE module fails or if a SUFFICIENT module succeeds. If
+   * the overall login attempt fails, a {@link LoginException} will be
+   * thrown.
+   *
+   * @throws LoginException If logging in fails.
+   */
+  public void login() throws LoginException
+  {
+    boolean failure = false;
+    for (int i = 0; i < modules.length; i++)
+      {
+        try
+          {
+            boolean result = modules[i].login();
+            if (!result)
+              {
+                if (entries[i].getControlFlag() ==
+                    AppConfigurationEntry.LoginModuleControlFlag.REQUISITE)
+                  throw new LoginException ("REQUISITE module " + entries[i].getLoginModuleName()
+                                            + " failed");
+                else if (entries[i].getControlFlag() ==
+                         AppConfigurationEntry.LoginModuleControlFlag.REQUIRED)
+                  failure = true;
+              }
+            else
+              {
+                if (entries[i].getControlFlag() ==
+                    AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT)
+                  break;
+              }
+          }
+        catch (LoginException le)
+          {
+            if (entries[i].getControlFlag() !=
+                AppConfigurationEntry.LoginModuleControlFlag.REQUISITE)
+              continue;
+            for (int j = 0; j < modules.length; j++)
+              modules[i].abort();
+            throw le;
+          }
+      }
+    if (failure)
+      throw new LoginException ("not all REQUIRED modules succeeded");
+
+    for (int i = 0; i < modules.length; i++)
+      modules[i].commit();
+  }
+
+  /**
+   * Logs a subject out, cleaning up any state that may be in memory.
+   *
+   * @throws LoginException If logging out fails.
+   */
+  public void logout() throws LoginException
+  {
+    for (int i = 0; i < modules.length; i++)
+      modules[i].logout();
+  }
+
+  // Own methods.
+
+  /**
+   * Fetch the default callback handler, based on the
+   * auth.login.defaultCallbackHandler property, or null if it is not
+   * set.
+   */
+  private static CallbackHandler defaultHandler()
+  {
+    GetSecurityPropertyAction act =
+      new GetSecurityPropertyAction ("auth.login.defaultCallbackHandler");
+    String classname = (String) AccessController.doPrivileged (act);
+    if (classname != null)
+      {
+        try
+          {
+            return (CallbackHandler) Class.forName (classname).newInstance();
+          }
+        catch (ClassNotFoundException cnfe)
+          {
+            return null;
+          }
+        catch (ClassCastException cce)
+          {
+            return null;
+          }
+        catch (IllegalAccessException iae)
+          {
+            return null;
+          }
+        catch (InstantiationException ie)
+          {
+            return null;
+          }
+      }
+    return null;
+  }
+
+  private LoginModule lookupModule (AppConfigurationEntry entry,
+                                    Subject subject, Map sharedState)
+    throws LoginException
+  {
+    LoginModule module = null;
+    Exception cause = null;
+    try
+      {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        Class c = Class.forName(entry.getLoginModuleName(), true, cl);
+        module = (LoginModule) c.newInstance();
+      }
+    catch (ClassNotFoundException cnfe)
+      {
+        cause = cnfe;
+      }
+    catch (ClassCastException cce)
+      {
+        cause = cce;
+      }
+    catch (IllegalAccessException iae)
+      {
+        cause = iae;
+      }
+    catch (InstantiationException ie)
+      {
+        cause = ie;
+      }
+
+    if (cause != null)
+      {
+        LoginException le = new LoginException ("could not load module "
+                                                + entry.getLoginModuleName());
+        le.initCause (cause);
+        throw le;
+      }
+
+    module.initialize (subject, cbHandler, sharedState, entry.getOptions());
+    return module;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/LoginException.java b/libjava/classpath/javax/security/auth/login/LoginException.java
new file mode 100644
index 000000000..46ec33aed
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/LoginException.java
@@ -0,0 +1,65 @@
+/* LoginException.java
+   Copyright (C) 2004 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.login;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * A general exception during authentication and authorization.
+ */
+public class LoginException extends GeneralSecurityException
+{
+
+  // Constant.
+  // -------------------------------------------------------------------------
+
+  private static final long serialVersionUID = -4679091624035232488L;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  public LoginException()
+  {
+  }
+
+  public LoginException (String message)
+  {
+    super (message);
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/NullConfiguration.java b/libjava/classpath/javax/security/auth/login/NullConfiguration.java
new file mode 100644
index 000000000..a3f0c9943
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/NullConfiguration.java
@@ -0,0 +1,62 @@
+/* NullConfiguration.java -- no-op default login configuration.
+   Copyright (C) 2004 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.login;
+
+final class NullConfiguration extends Configuration
+{
+
+  // Contructor.
+  // -------------------------------------------------------------------------
+
+  NullConfiguration()
+  {
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  public AppConfigurationEntry[] getAppConfigurationEntry (String applicationName)
+  {
+    return null;
+  }
+
+  public void refresh()
+  {
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/login/package.html b/libjava/classpath/javax/security/auth/login/package.html
new file mode 100644
index 000000000..dcb7710cc
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/login/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.security.auth.login package.
+   Copyright (C) 2004 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. -->
+
+<html>
+<head><title>GNU Classpath - javax.security.auth.login</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/javax/security/auth/package.html b/libjava/classpath/javax/security/auth/package.html
new file mode 100644
index 000000000..9888552c9
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.security.auth package.
+   Copyright (C) 2004 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. -->
+
+<html>
+<head><title>GNU Classpath - javax.security.auth</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/javax/security/auth/spi/LoginModule.java b/libjava/classpath/javax/security/auth/spi/LoginModule.java
new file mode 100644
index 000000000..197cd692e
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/spi/LoginModule.java
@@ -0,0 +1,122 @@
+/* LoginModule.java -- interface for login implementations.
+   Copyright (C) 2004  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.spi;
+
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+
+/**
+ * The base interface for login methods in the Java Authentication and
+ * Authorization Service (JAAS).
+ *
+ * <p>This interface is used by service providers that implement login
+ * services, and is used internally by the JAAS system. It is not useful
+ * to application programmers, who should use the {@link
+ * javax.security.auth.login.LoginContext} instead.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public interface LoginModule
+{
+  /**
+   * Abort the current login attempt. This is called after {@link #login()}
+   * if the overall login attempt fails (that is, if one of the other login
+   * modules that is REQUIRED or REQUISITE fails). This method should clean
+   * up this module's saved state, if any.
+   *
+   * @return True if the abort succeeded, or false if this module should
+   * be ignored.
+   * @throws LoginException If the abort fails.
+   */
+  boolean abort() throws LoginException;
+
+  /**
+   * Commit the current login attempt. This is called after {@link
+   * #login()} if the overall login attempt succeeds (that is, all
+   * methods have satisfied all REQUIRED, REQUISITE, SUFFICIENT and
+   * OPTIONAL module requirements).
+   *
+   * @return True if the commit succeeded, or false if this module
+   * should be ignored.
+   * @throws LoginException If the commit fails.
+   */
+  boolean commit() throws LoginException;
+
+  /**
+   * Initializes this login module. This method is called when the
+   * instance implementing this interface is instantiated, and should
+   * perform any initialization based on the given parameters.
+   * Implementations should ignore state variables and options they do
+   * not recognize.
+   *
+   * @param subject The subject being authenticated.
+   * @param handler The callback handler for user input.
+   * @param sharedState A mapping that is shared between all login
+   * modules.
+   * @param options A mapping of options given to this module.
+   */
+  void initialize(Subject subject, CallbackHandler handler,
+                  Map<String, ?> sharedState, Map<String, ?> options);
+
+  /**
+   * Authenticates a subject to the system. This is the primary
+   * mechanism by which subjects are authenticated, and typically
+   * implementations will ask for credentials (for example, a user
+   * name and password) which will then be verified.
+   *
+   * @return True if the subject was authenticated, or false if this
+   * module should be ignored.
+   * @throws LoginException If this method fails.
+   */
+  boolean login() throws LoginException;
+
+  /**
+   * Logs a subject out. This is primarily used for modules that must
+   * destroy or remove the authentication state associated with a
+   * logged-in subject.
+   *
+   * @return True if the logout succeeds, or false if this module
+   * should be ignored.
+   * @throws LoginException If this method fails.
+   */
+  boolean logout() throws LoginException;
+}
diff --git a/libjava/classpath/javax/security/auth/spi/package.html b/libjava/classpath/javax/security/auth/spi/package.html
new file mode 100644
index 000000000..9f3de395e
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/spi/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.security.auth.spi package.
+   Copyright (C) 2004 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. -->
+
+<html>
+<head><title>GNU Classpath - javax.security.auth.spi</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/javax/security/auth/x500/X500Principal.java b/libjava/classpath/javax/security/auth/x500/X500Principal.java
new file mode 100644
index 000000000..0a1e8c665
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/x500/X500Principal.java
@@ -0,0 +1,556 @@
+/* X500Principal.java -- X.500 principal.
+   Copyright (C) 2003, 2004, 2005 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.x500;
+
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.security.OID;
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERReader;
+import gnu.java.security.der.DERValue;
+
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.NotActiveException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Reader;
+import java.io.Serializable;
+import java.io.StringReader;
+
+import java.security.Principal;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+public final class X500Principal implements Principal, Serializable
+{
+  private static final long serialVersionUID = -500463348111345721L;
+
+  // Constants and fields.
+  // ------------------------------------------------------------------------
+
+  public static final String CANONICAL = "CANONICAL";
+  public static final String RFC1779 = "RFC1779";
+  public static final String RFC2253 = "RFC2253";
+
+  private static final OID CN         = new OID("2.5.4.3");
+  private static final OID C          = new OID("2.5.4.6");
+  private static final OID L          = new OID("2.5.4.7");
+  private static final OID ST         = new OID("2.5.4.8");
+  private static final OID STREET     = new OID("2.5.4.9");
+  private static final OID O          = new OID("2.5.4.10");
+  private static final OID OU         = new OID("2.5.4.11");
+  private static final OID DC         = new OID("0.9.2342.19200300.100.1.25");
+  private static final OID UID        = new OID("0.9.2342.19200300.100.1.1");
+
+  private transient List components;
+  private transient Map currentRdn;
+  private transient boolean fixed;
+  private transient byte[] encoded;
+
+  // Constructors.
+  // ------------------------------------------------------------------------
+
+  private X500Principal()
+  {
+    components = new LinkedList();
+    currentRdn = new LinkedHashMap();
+    components.add (currentRdn);
+  }
+
+  public X500Principal (String name)
+  {
+    this();
+    if (name == null)
+      throw new NullPointerException();
+    try
+      {
+        parseString (name);
+      }
+    catch (IOException ioe)
+      {
+        IllegalArgumentException iae = new IllegalArgumentException("malformed name");
+        iae.initCause (ioe);
+        throw iae;
+      }
+  }
+
+  public X500Principal (byte[] encoded)
+  {
+    this(new ByteArrayInputStream (encoded));
+  }
+
+  public X500Principal (InputStream encoded)
+  {
+    this();
+    try
+      {
+        parseDer (encoded);
+      }
+    catch (IOException ioe)
+      {
+        throw new IllegalArgumentException (ioe.toString());
+      }
+  }
+
+  // Instance methods.
+  // ------------------------------------------------------------------------
+
+  public int hashCode()
+  {
+    int result = size();
+    for (int i = 0; i < size(); ++i)
+      {
+        Map m = (Map) components.get(i);
+        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
+          {
+            Map.Entry e = (Map.Entry) it2.next();
+            // We don't bother looking at the value of the entry.
+            result = result * 31 + ((OID) e.getKey()).hashCode();
+          }
+      }
+    return result;
+  }
+
+  public boolean equals(Object o)
+  {
+    if (!(o instanceof X500Principal))
+      return false;
+    if (size() != ((X500Principal) o).size())
+      return false;
+    for (int i = 0; i < size(); i++)
+      {
+        Map m = (Map) components.get (i);
+        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
+          {
+            Map.Entry e = (Map.Entry) it2.next();
+            OID oid = (OID) e.getKey();
+            String v1 = (String) e.getValue();
+            String v2 = ((X500Principal) o).getComponent (oid, i);
+            if (v2 == null)
+              return false;
+            if (!compressWS (v1).equalsIgnoreCase (compressWS (v2)))
+              return false;
+          }
+      }
+    return true;
+  }
+
+  public byte[] getEncoded()
+  {
+    if (encoded == null)
+      encodeDer();
+    return (byte[]) encoded.clone();
+  }
+
+  public String getName()
+  {
+    return getName (RFC2253);
+  }
+
+  public String getName (final String format)
+  {
+    boolean rfc2253 = RFC2253.equalsIgnoreCase (format) ||
+      CANONICAL.equalsIgnoreCase (format);
+    boolean rfc1779 = RFC1779.equalsIgnoreCase (format);
+    boolean canon   = CANONICAL.equalsIgnoreCase (format);
+    if (! (rfc2253 || rfc1779 || canon))
+      throw new IllegalArgumentException ("unsupported format " + format);
+    CPStringBuilder str = new CPStringBuilder();
+    for (Iterator it = components.iterator(); it.hasNext(); )
+      {
+        Map m = (Map) it.next();
+        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
+          {
+            Map.Entry entry = (Map.Entry) it2.next();
+            OID oid = (OID) entry.getKey();
+            String value = (String) entry.getValue();
+            if (oid.equals (CN))
+              str.append ("CN");
+            else if (oid.equals (C))
+              str.append ("C");
+            else if (oid.equals (L))
+              str.append ("L");
+            else if (oid.equals (ST))
+              str.append ("ST");
+            else if (oid.equals (STREET))
+              str.append ("STREET");
+            else if (oid.equals (O))
+              str.append ("O");
+            else if (oid.equals (OU))
+              str.append ("OU");
+            else if (oid.equals (DC) && rfc2253)
+              str.append ("DC");
+            else if (oid.equals (UID) && rfc2253)
+              str.append ("UID");
+            else
+              str.append (oid.toString());
+            str.append('=');
+            str.append(value);
+            if (it2.hasNext())
+              str.append('+');
+          }
+        if (it.hasNext())
+          str.append(',');
+      }
+    if (canon)
+      return str.toString().toUpperCase (Locale.US).toLowerCase (Locale.US);
+    return str.toString();
+  }
+
+  public String toString()
+  {
+    return getName (RFC2253);
+  }
+
+  // Serialization methods.
+  // ------------------------------------------------------------------------
+
+  private void writeObject (ObjectOutputStream out) throws IOException
+  {
+    if (encoded != null)
+      encodeDer();
+    out.writeObject (encoded);
+  }
+
+  private void readObject (ObjectInputStream in)
+    throws IOException, NotActiveException, ClassNotFoundException
+  {
+    byte[] buf = (byte[]) in.readObject();
+    parseDer (new ByteArrayInputStream (buf));
+  }
+
+  // Own methods.
+  // -------------------------------------------------------------------------
+
+  private int size()
+  {
+    return components.size();
+  }
+
+  private String getComponent(OID oid, int rdn)
+  {
+    if (rdn >= size())
+      return null;
+    return (String) ((Map) components.get (rdn)).get (oid);
+  }
+
+  private void encodeDer()
+  {
+    ArrayList name = new ArrayList(components.size());
+    for (Iterator it = components.iterator(); it.hasNext(); )
+      {
+        Map m = (Map) it.next();
+        if (m.isEmpty())
+          continue;
+        Set rdn = new HashSet();
+        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
+          {
+            Map.Entry e = (Map.Entry) it2.next();
+            ArrayList atav = new ArrayList(2);
+            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, e.getKey()));
+            atav.add(new DERValue(DER.UTF8_STRING, e.getValue()));
+            rdn.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, atav));
+          }
+        name.add(new DERValue(DER.SET|DER.CONSTRUCTED, rdn));
+      }
+    DERValue val = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, name);
+    encoded = val.getEncoded();
+  }
+
+  private int sep;
+
+  private void parseString(String str) throws IOException
+  {
+    Reader in = new StringReader(str);
+    while (true)
+      {
+        String key = readAttributeType(in);
+        if (key == null)
+          break;
+        String value = readAttributeValue(in);
+        putComponent(key, value);
+        if (sep == ',')
+          newRelativeDistinguishedName();
+        if (sep == -1)
+          break;
+      }
+  }
+
+  private String readAttributeType(Reader in) throws IOException
+  {
+    CPStringBuilder buf = new CPStringBuilder();
+    int ch;
+    while ((ch = in.read()) != '=')
+      {
+        if (ch == -1)
+          {
+            if (buf.length() > 0)
+              throw new EOFException("partial name read: " + buf);
+            return null;
+          }
+        if (ch > 127)
+          throw new IOException("Invalid char: " + (char) ch);
+        if (Character.isLetterOrDigit((char) ch) || ch == '-' || ch == '.')
+          buf.append((char) ch);
+        else
+          throw new IOException("Invalid char: " + (char) ch);
+      }
+    return buf.toString();
+  }
+
+  private String readAttributeValue(Reader in) throws IOException
+  {
+    CPStringBuilder buf = new CPStringBuilder();
+    int ch = in.read();
+    if (ch == '#')
+      {
+        while (true)
+          {
+            ch = in.read();
+            if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
+                || Character.isDigit((char) ch))
+              buf.append((char) ch);
+            else if (ch == '+' || ch == ',')
+              {
+                sep = ch;
+                String hex = buf.toString();
+                return new String(toByteArray(hex));
+              }
+            else
+              throw new IOException("illegal character: " + (char) ch);
+          }
+      }
+    else if (ch == '"')
+      {
+        while (true)
+          {
+            ch = in.read();
+            if (ch == '"')
+              break;
+            else if (ch == '\\')
+              {
+                ch = in.read();
+                if (ch == -1)
+                  throw new EOFException();
+                if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
+                    || Character.isDigit((char) ch))
+                  {
+                    int i = Character.digit((char) ch, 16) << 4;
+                    ch = in.read();
+                    if (!(('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
+                          || Character.isDigit((char) ch)))
+                      throw new IOException("illegal hex char");
+                    i |= Character.digit((char) ch, 16);
+                    buf.append((char) i);
+                  }
+                else
+                  buf.append((char) ch);
+              }
+            else
+              buf.append((char) ch);
+          }
+        sep = in.read();
+        if (sep != '+' && sep != ',')
+          throw new IOException("illegal character: " + (char) ch);
+        return buf.toString();
+      }
+    else
+      {
+        while (true)
+          {
+            switch (ch)
+              {
+              case '+':
+              case ',':
+                sep = ch;
+                return buf.toString();
+              case '\\':
+                ch = in.read();
+                if (ch == -1)
+                  throw new EOFException();
+                if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
+                    || Character.isDigit((char) ch))
+                  {
+                    int i = Character.digit((char) ch, 16) << 4;
+                    ch = in.read();
+                    if (!(('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
+                          || Character.isDigit((char) ch)))
+                      throw new IOException("illegal hex char");
+                    i |= Character.digit((char) ch, 16);
+                    buf.append((char) i);
+                  }
+                else
+                  buf.append((char) ch);
+                break;
+              case '=':
+              case '<':
+              case '>':
+              case '#':
+              case ';':
+                throw new IOException("illegal character: " + (char) ch);
+              case -1:
+                sep = -1;
+                return buf.toString ();
+              default:
+                buf.append((char) ch);
+              }
+            ch = in.read ();
+          }
+      }
+  }
+
+  private void parseDer (InputStream encoded) throws IOException
+  {
+    DERReader der = new DERReader (encoded);
+    DERValue name = der.read();
+    if (!name.isConstructed())
+      throw new IOException ("malformed Name");
+    this.encoded = name.getEncoded();
+    int len = 0;
+    while (len < name.getLength())
+      {
+        DERValue rdn = der.read();
+        if (!rdn.isConstructed())
+          throw new IOException ("badly formed RDNSequence");
+        int len2 = 0;
+        while (len2 < rdn.getLength())
+          {
+            DERValue atav = der.read();
+            if (!atav.isConstructed())
+              throw new IOException ("badly formed AttributeTypeAndValue");
+            DERValue val = der.read();
+            if (val.getTag() != DER.OBJECT_IDENTIFIER)
+              throw new IOException ("badly formed AttributeTypeAndValue");
+            OID oid = (OID) val.getValue();
+            val = der.read();
+            if (!(val.getValue() instanceof String))
+              throw new IOException ("badly formed AttributeTypeAndValue");
+            String value = (String) val.getValue();
+            putComponent(oid, value);
+            len2 += atav.getEncodedLength();
+          }
+        len += rdn.getEncodedLength();
+        if (len < name.getLength())
+          newRelativeDistinguishedName();
+      }
+  }
+
+  private void newRelativeDistinguishedName()
+  {
+    currentRdn = new LinkedHashMap();
+    components.add(currentRdn);
+  }
+
+  private void putComponent(OID oid, String value)
+  {
+    currentRdn.put(oid, value);
+  }
+
+  private void putComponent(String name, String value)
+  {
+    name = name.trim().toLowerCase();
+    if (name.equals("cn"))
+      putComponent(CN, value);
+    else if (name.equals("c"))
+      putComponent(C, value);
+    else if (name.equals("l"))
+      putComponent(L, value);
+    else if (name.equals("street"))
+      putComponent(STREET, value);
+    else if (name.equals("st"))
+      putComponent(ST, value);
+    else if (name.equals ("o"))
+      putComponent (O, value);
+    else if (name.equals ("ou"))
+      putComponent (OU, value);
+    else if (name.equals("dc"))
+      putComponent(DC, value);
+    else if (name.equals("uid"))
+      putComponent(UID, value);
+    else
+      putComponent(new OID(name), value);
+  }
+
+  private static String compressWS(String str)
+  {
+    CPStringBuilder buf = new CPStringBuilder();
+    char lastChar = 0;
+    for (int i = 0; i < str.length(); i++)
+      {
+        char c = str.charAt(i);
+        if (Character.isWhitespace(c))
+          {
+            if (!Character.isWhitespace(lastChar))
+              buf.append(' ');
+          }
+        else
+          buf.append(c);
+        lastChar = c;
+      }
+    return buf.toString().trim();
+  }
+
+  private static byte[] toByteArray (String str)
+  {
+    int limit = str.length();
+    byte[] result = new byte[((limit + 1) / 2)];
+    int i = 0, j = 0;
+    if ((limit % 2) == 1)
+      {
+        result[j++] = (byte) Character.digit (str.charAt(i++), 16);
+      }
+    while (i < limit)
+      {
+        result[j  ]  = (byte) (Character.digit (str.charAt(i++), 16) << 4);
+        result[j++] |= (byte)  Character.digit (str.charAt(i++), 16);
+      }
+    return result;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/x500/X500PrivateCredential.java b/libjava/classpath/javax/security/auth/x500/X500PrivateCredential.java
new file mode 100644
index 000000000..8cba93c6f
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/x500/X500PrivateCredential.java
@@ -0,0 +1,149 @@
+/* X500PrivateCredential.java -- certificate and private key pair.
+   Copyright (C) 2003, 2004  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.x500;
+
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.Destroyable;
+
+/**
+ * A pairing of a {@link X509Certificate} and its corresponding {@link
+ * PrivateKey}, with an optional keystore alias.
+ */
+public final class X500PrivateCredential implements Destroyable
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  private PrivateKey key;
+  private X509Certificate certificate;
+  private String alias;
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Creates a new private credential with no associated keystore alias.
+   *
+   * @param certificate The X.509 certificate.
+   * @param key The private key.
+   * @throws IllegalArgumentException If either parameter is null.
+   */
+  public X500PrivateCredential (X509Certificate certificate, PrivateKey key)
+  {
+    if (certificate == null || key == null)
+      throw new IllegalArgumentException();
+    this.certificate = certificate;
+    this.key = key;
+  }
+
+  /**
+   * Creates a new private credential with a keystore alias.
+   *
+   * @param certificate The X.509 certificate.
+   * @param key The private key.
+   * @param alias The keystore alias for this credential.
+   * @throws IllegalArgumentException If any parameter is null.
+   */
+  public X500PrivateCredential (X509Certificate certificate, PrivateKey key,
+                                String alias)
+  {
+    this (certificate, key);
+    if (alias == null)
+      throw new IllegalArgumentException();
+    this.alias = alias;
+  }
+
+  // Instance methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Returns the certificate of this credential.
+   *
+   * @return The certificate of this credential.
+   */
+  public X509Certificate getCertificate()
+  {
+    return certificate;
+  }
+
+  /**
+   * Returns the private key of this credential.
+   *
+   * @return The private key of this credential.
+   */
+  public PrivateKey getPrivateKey()
+  {
+    return key;
+  }
+
+  /**
+   * Returns the keystore alias of this credential, or null if not present.
+   *
+   * @return The keystore alias, or null.
+   */
+  public String getAlias()
+  {
+    return alias;
+  }
+
+  /**
+   * Destroy the sensitive data of this credential, setting the certificate,
+   * private key, and keystore alias to null.
+   */
+  public void destroy()
+  {
+    certificate = null;
+    key = null;
+    alias = null;
+  }
+
+  /**
+   * Tells whether or not this credential has been destroyed, and that
+   * the certificate and private key fields are null.
+   *
+   * @return True if this object has been destroyed.
+   */
+  public boolean isDestroyed()
+  {
+    return certificate == null && key == null;
+  }
+}
diff --git a/libjava/classpath/javax/security/auth/x500/package.html b/libjava/classpath/javax/security/auth/x500/package.html
new file mode 100644
index 000000000..449be814f
--- /dev/null
+++ b/libjava/classpath/javax/security/auth/x500/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.security.auth.x500 package.
+   Copyright (C) 2004 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. -->
+
+<html>
+<head><title>GNU Classpath - javax.security.auth.x500</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
-- 
cgit v1.2.3