feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
172
jdkSrc/jdk8/javax/security/auth/AuthPermission.java
Normal file
172
jdkSrc/jdk8/javax/security/auth/AuthPermission.java
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth;
|
||||
|
||||
/**
|
||||
* This class is for authentication permissions.
|
||||
* An AuthPermission contains a name
|
||||
* (also referred to as a "target name")
|
||||
* but no actions list; you either have the named permission
|
||||
* or you don't.
|
||||
*
|
||||
* <p> The target name is the name of a security configuration parameter
|
||||
* (see below). Currently the AuthPermission object is used to
|
||||
* guard access to the Policy, Subject, LoginContext,
|
||||
* and Configuration objects.
|
||||
*
|
||||
* <p> The possible target names for an Authentication Permission are:
|
||||
*
|
||||
* <pre>
|
||||
* doAs - allow the caller to invoke the
|
||||
* {@code Subject.doAs} methods.
|
||||
*
|
||||
* doAsPrivileged - allow the caller to invoke the
|
||||
* {@code Subject.doAsPrivileged} methods.
|
||||
*
|
||||
* getSubject - allow for the retrieval of the
|
||||
* Subject(s) associated with the
|
||||
* current Thread.
|
||||
*
|
||||
* getSubjectFromDomainCombiner - allow for the retrieval of the
|
||||
* Subject associated with the
|
||||
* a {@code SubjectDomainCombiner}.
|
||||
*
|
||||
* setReadOnly - allow the caller to set a Subject
|
||||
* to be read-only.
|
||||
*
|
||||
* modifyPrincipals - allow the caller to modify the {@code Set}
|
||||
* of Principals associated with a
|
||||
* {@code Subject}
|
||||
*
|
||||
* modifyPublicCredentials - allow the caller to modify the
|
||||
* {@code Set} of public credentials
|
||||
* associated with a {@code Subject}
|
||||
*
|
||||
* modifyPrivateCredentials - allow the caller to modify the
|
||||
* {@code Set} of private credentials
|
||||
* associated with a {@code Subject}
|
||||
*
|
||||
* refreshCredential - allow code to invoke the {@code refresh}
|
||||
* method on a credential which implements
|
||||
* the {@code Refreshable} interface.
|
||||
*
|
||||
* destroyCredential - allow code to invoke the {@code destroy}
|
||||
* method on a credential {@code object}
|
||||
* which implements the {@code Destroyable}
|
||||
* interface.
|
||||
*
|
||||
* createLoginContext.{name} - allow code to instantiate a
|
||||
* {@code LoginContext} with the
|
||||
* specified <i>name</i>. <i>name</i>
|
||||
* is used as the index into the installed login
|
||||
* {@code Configuration}
|
||||
* (that returned by
|
||||
* {@code Configuration.getConfiguration()}).
|
||||
* <i>name</i> can be wildcarded (set to '*')
|
||||
* to allow for any name.
|
||||
*
|
||||
* getLoginConfiguration - allow for the retrieval of the system-wide
|
||||
* login Configuration.
|
||||
*
|
||||
* createLoginConfiguration.{type} - allow code to obtain a Configuration
|
||||
* object via
|
||||
* {@code Configuration.getInstance}.
|
||||
*
|
||||
* setLoginConfiguration - allow for the setting of the system-wide
|
||||
* login Configuration.
|
||||
*
|
||||
* refreshLoginConfiguration - allow for the refreshing of the system-wide
|
||||
* login Configuration.
|
||||
* </pre>
|
||||
*
|
||||
* <p> The following target name has been deprecated in favor of
|
||||
* {@code createLoginContext.{name}}.
|
||||
*
|
||||
* <pre>
|
||||
* createLoginContext - allow code to instantiate a
|
||||
* {@code LoginContext}.
|
||||
* </pre>
|
||||
*
|
||||
* <p> {@code javax.security.auth.Policy} has been
|
||||
* deprecated in favor of {@code java.security.Policy}.
|
||||
* Therefore, the following target names have also been deprecated:
|
||||
*
|
||||
* <pre>
|
||||
* getPolicy - allow the caller to retrieve the system-wide
|
||||
* Subject-based access control policy.
|
||||
*
|
||||
* setPolicy - allow the caller to set the system-wide
|
||||
* Subject-based access control policy.
|
||||
*
|
||||
* refreshPolicy - allow the caller to refresh the system-wide
|
||||
* Subject-based access control policy.
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public final class AuthPermission extends
|
||||
java.security.BasicPermission {
|
||||
|
||||
private static final long serialVersionUID = 5806031445061587174L;
|
||||
|
||||
/**
|
||||
* Creates a new AuthPermission with the specified name.
|
||||
* The name is the symbolic name of the AuthPermission.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param name the name of the AuthPermission
|
||||
*
|
||||
* @throws NullPointerException if {@code name} is {@code null}.
|
||||
* @throws IllegalArgumentException if {@code name} is empty.
|
||||
*/
|
||||
public AuthPermission(String name) {
|
||||
// for backwards compatibility --
|
||||
// createLoginContext is deprecated in favor of createLoginContext.*
|
||||
super("createLoginContext".equals(name) ?
|
||||
"createLoginContext.*" : name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AuthPermission object with the specified name.
|
||||
* The name is the symbolic name of the AuthPermission, and the
|
||||
* actions String is currently unused and should be null.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param name the name of the AuthPermission <p>
|
||||
*
|
||||
* @param actions should be null.
|
||||
*
|
||||
* @throws NullPointerException if {@code name} is {@code null}.
|
||||
* @throws IllegalArgumentException if {@code name} is empty.
|
||||
*/
|
||||
public AuthPermission(String name, String actions) {
|
||||
// for backwards compatibility --
|
||||
// createLoginContext is deprecated in favor of createLoginContext.*
|
||||
super("createLoginContext".equals(name) ?
|
||||
"createLoginContext.*" : name, actions);
|
||||
}
|
||||
}
|
||||
60
jdkSrc/jdk8/javax/security/auth/DestroyFailedException.java
Normal file
60
jdkSrc/jdk8/javax/security/auth/DestroyFailedException.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth;
|
||||
|
||||
/**
|
||||
* Signals that a {@code destroy} operation failed.
|
||||
*
|
||||
* <p> This exception is thrown by credentials implementing
|
||||
* the {@code Destroyable} interface when the {@code destroy}
|
||||
* method fails.
|
||||
*
|
||||
*/
|
||||
public class DestroyFailedException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -7790152857282749162L;
|
||||
|
||||
/**
|
||||
* Constructs a DestroyFailedException with no detail message. A detail
|
||||
* message is a String that describes this particular exception.
|
||||
*/
|
||||
public DestroyFailedException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DestroyFailedException with the specified detail
|
||||
* message. A detail message is a String that describes this particular
|
||||
* exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public DestroyFailedException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
68
jdkSrc/jdk8/javax/security/auth/Destroyable.java
Normal file
68
jdkSrc/jdk8/javax/security/auth/Destroyable.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth;
|
||||
|
||||
/**
|
||||
* Objects such as credentials may optionally implement this interface
|
||||
* to provide the capability to destroy its contents.
|
||||
*
|
||||
* @see javax.security.auth.Subject
|
||||
*/
|
||||
public interface Destroyable {
|
||||
|
||||
/**
|
||||
* Destroy this {@code Object}.
|
||||
*
|
||||
* <p> Sensitive information associated with this {@code Object}
|
||||
* is destroyed or cleared. Subsequent calls to certain methods
|
||||
* on this {@code Object} will result in an
|
||||
* {@code IllegalStateException} being thrown.
|
||||
*
|
||||
* <p>
|
||||
* The default implementation throws {@code DestroyFailedException}.
|
||||
*
|
||||
* @exception DestroyFailedException if the destroy operation fails. <p>
|
||||
*
|
||||
* @exception SecurityException if the caller does not have permission
|
||||
* to destroy this {@code Object}.
|
||||
*/
|
||||
public default void destroy() throws DestroyFailedException {
|
||||
throw new DestroyFailedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this {@code Object} has been destroyed.
|
||||
*
|
||||
* <p>
|
||||
* The default implementation returns false.
|
||||
*
|
||||
* @return true if this {@code Object} has been destroyed,
|
||||
* false otherwise.
|
||||
*/
|
||||
public default boolean isDestroyed() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
362
jdkSrc/jdk8/javax/security/auth/Policy.java
Normal file
362
jdkSrc/jdk8/javax/security/auth/Policy.java
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth;
|
||||
|
||||
import java.security.Security;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Objects;
|
||||
import sun.security.util.Debug;
|
||||
|
||||
/**
|
||||
* <p> This is an abstract class for representing the system policy for
|
||||
* Subject-based authorization. A subclass implementation
|
||||
* of this class provides a means to specify a Subject-based
|
||||
* access control {@code Policy}.
|
||||
*
|
||||
* <p> A {@code Policy} object can be queried for the set of
|
||||
* Permissions granted to code running as a
|
||||
* {@code Principal} in the following manner:
|
||||
*
|
||||
* <pre>
|
||||
* policy = Policy.getPolicy();
|
||||
* PermissionCollection perms = policy.getPermissions(subject,
|
||||
* codeSource);
|
||||
* </pre>
|
||||
*
|
||||
* The {@code Policy} object consults the local policy and returns
|
||||
* and appropriate {@code Permissions} object with the
|
||||
* Permissions granted to the Principals associated with the
|
||||
* provided <i>subject</i>, and granted to the code specified
|
||||
* by the provided <i>codeSource</i>.
|
||||
*
|
||||
* <p> A {@code Policy} contains the following information.
|
||||
* Note that this example only represents the syntax for the default
|
||||
* {@code Policy} implementation. Subclass implementations of this class
|
||||
* may implement alternative syntaxes and may retrieve the
|
||||
* {@code Policy} from any source such as files, databases,
|
||||
* or servers.
|
||||
*
|
||||
* <p> Each entry in the {@code Policy} is represented as
|
||||
* a <b><i>grant</i></b> entry. Each <b><i>grant</i></b> entry
|
||||
* specifies a codebase, code signers, and Principals triplet,
|
||||
* as well as the Permissions granted to that triplet.
|
||||
*
|
||||
* <pre>
|
||||
* grant CodeBase ["URL"], Signedby ["signers"],
|
||||
* Principal [Principal_Class] "Principal_Name" {
|
||||
* Permission Permission_Class ["Target_Name"]
|
||||
* [, "Permission_Actions"]
|
||||
* [, signedBy "SignerName"];
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* The CodeBase and Signedby components of the triplet name/value pairs
|
||||
* are optional. If they are not present, then any any codebase will match,
|
||||
* and any signer (including unsigned code) will match.
|
||||
* For Example,
|
||||
*
|
||||
* <pre>
|
||||
* grant CodeBase "foo.com", Signedby "foo",
|
||||
* Principal com.sun.security.auth.SolarisPrincipal "duke" {
|
||||
* permission java.io.FilePermission "/home/duke", "read, write";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* This <b><i>grant</i></b> entry specifies that code from "foo.com",
|
||||
* signed by "foo', and running as a {@code SolarisPrincipal} with the
|
||||
* name, duke, has one {@code Permission}. This {@code Permission}
|
||||
* permits the executing code to read and write files in the directory,
|
||||
* "/home/duke".
|
||||
*
|
||||
* <p> To "run" as a particular {@code Principal},
|
||||
* code invokes the {@code Subject.doAs(subject, ...)} method.
|
||||
* After invoking that method, the code runs as all the Principals
|
||||
* associated with the specified {@code Subject}.
|
||||
* Note that this {@code Policy} (and the Permissions
|
||||
* granted in this {@code Policy}) only become effective
|
||||
* after the call to {@code Subject.doAs} has occurred.
|
||||
*
|
||||
* <p> Multiple Principals may be listed within one <b><i>grant</i></b> entry.
|
||||
* All the Principals in the grant entry must be associated with
|
||||
* the {@code Subject} provided to {@code Subject.doAs}
|
||||
* for that {@code Subject} to be granted the specified Permissions.
|
||||
*
|
||||
* <pre>
|
||||
* grant Principal com.sun.security.auth.SolarisPrincipal "duke",
|
||||
* Principal com.sun.security.auth.SolarisNumericUserPrincipal "0" {
|
||||
* permission java.io.FilePermission "/home/duke", "read, write";
|
||||
* permission java.net.SocketPermission "duke.com", "connect";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* This entry grants any code running as both "duke" and "0"
|
||||
* permission to read and write files in duke's home directory,
|
||||
* as well as permission to make socket connections to "duke.com".
|
||||
*
|
||||
* <p> Note that non Principal-based grant entries are not permitted
|
||||
* in this {@code Policy}. Therefore, grant entries such as:
|
||||
*
|
||||
* <pre>
|
||||
* grant CodeBase "foo.com", Signedby "foo" {
|
||||
* permission java.io.FilePermission "/tmp/scratch", "read, write";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* are rejected. Such permission must be listed in the
|
||||
* {@code java.security.Policy}.
|
||||
*
|
||||
* <p> The default {@code Policy} implementation can be changed by
|
||||
* setting the value of the {@code auth.policy.provider} security property to
|
||||
* the fully qualified name of the desired {@code Policy} implementation class.
|
||||
*
|
||||
* @deprecated as of JDK version 1.4 -- Replaced by java.security.Policy.
|
||||
* java.security.Policy has a method:
|
||||
* <pre>
|
||||
* public PermissionCollection getPermissions
|
||||
* (java.security.ProtectionDomain pd)
|
||||
*
|
||||
* </pre>
|
||||
* and ProtectionDomain has a constructor:
|
||||
* <pre>
|
||||
* public ProtectionDomain
|
||||
* (CodeSource cs,
|
||||
* PermissionCollection permissions,
|
||||
* ClassLoader loader,
|
||||
* Principal[] principals)
|
||||
* </pre>
|
||||
*
|
||||
* These two APIs provide callers the means to query the
|
||||
* Policy for Principal-based Permission entries.
|
||||
*
|
||||
* @see java.security.Security security properties
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class Policy {
|
||||
|
||||
private static Policy policy;
|
||||
private final static String AUTH_POLICY =
|
||||
"sun.security.provider.AuthPolicyFile";
|
||||
|
||||
private final java.security.AccessControlContext acc =
|
||||
java.security.AccessController.getContext();
|
||||
|
||||
// true if a custom (not AUTH_POLICY) system-wide policy object is set
|
||||
private static boolean isCustomPolicy;
|
||||
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
*/
|
||||
protected Policy() { }
|
||||
|
||||
/**
|
||||
* Returns the installed Policy object.
|
||||
* This method first calls
|
||||
* {@code SecurityManager.checkPermission} with the
|
||||
* {@code AuthPermission("getPolicy")} permission
|
||||
* to ensure the caller has permission to get the Policy object.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the installed Policy. The return value cannot be
|
||||
* {@code null}.
|
||||
*
|
||||
* @exception java.lang.SecurityException if the current thread does not
|
||||
* have permission to get the Policy object.
|
||||
*
|
||||
* @see #setPolicy
|
||||
*/
|
||||
public static Policy getPolicy() {
|
||||
java.lang.SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) sm.checkPermission(new AuthPermission("getPolicy"));
|
||||
return getPolicyNoCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the installed Policy object, skipping the security check.
|
||||
*
|
||||
* @return the installed Policy.
|
||||
*
|
||||
*/
|
||||
static Policy getPolicyNoCheck() {
|
||||
if (policy == null) {
|
||||
|
||||
synchronized(Policy.class) {
|
||||
|
||||
if (policy == null) {
|
||||
String policy_class = null;
|
||||
policy_class = AccessController.doPrivileged
|
||||
(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return java.security.Security.getProperty
|
||||
("auth.policy.provider");
|
||||
}
|
||||
});
|
||||
if (policy_class == null) {
|
||||
policy_class = AUTH_POLICY;
|
||||
}
|
||||
|
||||
try {
|
||||
final String finalClass = policy_class;
|
||||
|
||||
Policy untrustedImpl = AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Policy>() {
|
||||
public Policy run() throws ClassNotFoundException,
|
||||
InstantiationException,
|
||||
IllegalAccessException {
|
||||
Class<? extends Policy> implClass = Class.forName(
|
||||
finalClass, false,
|
||||
Thread.currentThread().getContextClassLoader()
|
||||
).asSubclass(Policy.class);
|
||||
return implClass.newInstance();
|
||||
}
|
||||
});
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() {
|
||||
setPolicy(untrustedImpl);
|
||||
isCustomPolicy = !finalClass.equals(AUTH_POLICY);
|
||||
return null;
|
||||
}
|
||||
}, Objects.requireNonNull(untrustedImpl.acc)
|
||||
);
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException
|
||||
(sun.security.util.ResourcesMgr.getString
|
||||
("unable.to.instantiate.Subject.based.policy"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return policy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the system-wide Policy object. This method first calls
|
||||
* {@code SecurityManager.checkPermission} with the
|
||||
* {@code AuthPermission("setPolicy")}
|
||||
* permission to ensure the caller has permission to set the Policy.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param policy the new system Policy object.
|
||||
*
|
||||
* @exception java.lang.SecurityException if the current thread does not
|
||||
* have permission to set the Policy.
|
||||
*
|
||||
* @see #getPolicy
|
||||
*/
|
||||
public static void setPolicy(Policy policy) {
|
||||
java.lang.SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) sm.checkPermission(new AuthPermission("setPolicy"));
|
||||
Policy.policy = policy;
|
||||
// all non-null policy objects are assumed to be custom
|
||||
isCustomPolicy = policy != null ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a custom (not AUTH_POLICY) system-wide policy object
|
||||
* has been set or installed. This method is called by
|
||||
* SubjectDomainCombiner to provide backwards compatibility for
|
||||
* developers that provide their own javax.security.auth.Policy
|
||||
* implementations.
|
||||
*
|
||||
* @return true if a custom (not AUTH_POLICY) system-wide policy object
|
||||
* has been set; false otherwise
|
||||
*/
|
||||
static boolean isCustomPolicySet(Debug debug) {
|
||||
if (policy != null) {
|
||||
if (debug != null && isCustomPolicy) {
|
||||
debug.println("Providing backwards compatibility for " +
|
||||
"javax.security.auth.policy implementation: " +
|
||||
policy.toString());
|
||||
}
|
||||
return isCustomPolicy;
|
||||
}
|
||||
// check if custom policy has been set using auth.policy.provider prop
|
||||
String policyClass = java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return Security.getProperty("auth.policy.provider");
|
||||
}
|
||||
});
|
||||
if (policyClass != null && !policyClass.equals(AUTH_POLICY)) {
|
||||
if (debug != null) {
|
||||
debug.println("Providing backwards compatibility for " +
|
||||
"javax.security.auth.policy implementation: " +
|
||||
policyClass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the Permissions granted to the Principals associated with
|
||||
* the specified {@code CodeSource}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param subject the {@code Subject}
|
||||
* whose associated Principals,
|
||||
* in conjunction with the provided
|
||||
* {@code CodeSource}, determines the Permissions
|
||||
* returned by this method. This parameter
|
||||
* may be {@code null}. <p>
|
||||
*
|
||||
* @param cs the code specified by its {@code CodeSource}
|
||||
* that determines, in conjunction with the provided
|
||||
* {@code Subject}, the Permissions
|
||||
* returned by this method. This parameter may be
|
||||
* {@code null}.
|
||||
*
|
||||
* @return the Collection of Permissions granted to all the
|
||||
* {@code Subject} and code specified in
|
||||
* the provided <i>subject</i> and <i>cs</i>
|
||||
* parameters.
|
||||
*/
|
||||
public abstract java.security.PermissionCollection getPermissions
|
||||
(Subject subject,
|
||||
java.security.CodeSource cs);
|
||||
|
||||
/**
|
||||
* Refresh and reload the Policy.
|
||||
*
|
||||
* <p>This method causes this object to refresh/reload its current
|
||||
* Policy. This is implementation-dependent.
|
||||
* For example, if the Policy object is stored in
|
||||
* a file, calling {@code refresh} will cause the file to be re-read.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @exception SecurityException if the caller does not have permission
|
||||
* to refresh the Policy.
|
||||
*/
|
||||
public abstract void refresh();
|
||||
}
|
||||
561
jdkSrc/jdk8/javax/security/auth/PrivateCredentialPermission.java
Normal file
561
jdkSrc/jdk8/javax/security/auth/PrivateCredentialPermission.java
Normal file
@@ -0,0 +1,561 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth;
|
||||
|
||||
import java.util.*;
|
||||
import java.text.MessageFormat;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Principal;
|
||||
import sun.security.util.ResourcesMgr;
|
||||
|
||||
/**
|
||||
* This class is used to protect access to private Credentials
|
||||
* belonging to a particular {@code Subject}. The {@code Subject}
|
||||
* is represented by a Set of Principals.
|
||||
*
|
||||
* <p> The target name of this {@code Permission} specifies
|
||||
* a Credential class name, and a Set of Principals.
|
||||
* The only valid value for this Permission's actions is, "read".
|
||||
* The target name must abide by the following syntax:
|
||||
*
|
||||
* <pre>
|
||||
* CredentialClass {PrincipalClass "PrincipalName"}*
|
||||
* </pre>
|
||||
*
|
||||
* For example, the following permission grants access to the
|
||||
* com.sun.PrivateCredential owned by Subjects which have
|
||||
* a com.sun.Principal with the name, "duke". Note that although
|
||||
* this example, as well as all the examples below, do not contain
|
||||
* Codebase, SignedBy, or Principal information in the grant statement
|
||||
* (for simplicity reasons), actual policy configurations should
|
||||
* specify that information when appropriate.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* grant {
|
||||
* permission javax.security.auth.PrivateCredentialPermission
|
||||
* "com.sun.PrivateCredential com.sun.Principal \"duke\"",
|
||||
* "read";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* If CredentialClass is "*", then access is granted to
|
||||
* all private Credentials belonging to the specified
|
||||
* {@code Subject}.
|
||||
* If "PrincipalName" is "*", then access is granted to the
|
||||
* specified Credential owned by any {@code Subject} that has the
|
||||
* specified {@code Principal} (the actual PrincipalName doesn't matter).
|
||||
* For example, the following grants access to the
|
||||
* a.b.Credential owned by any {@code Subject} that has
|
||||
* an a.b.Principal.
|
||||
*
|
||||
* <pre>
|
||||
* grant {
|
||||
* permission javax.security.auth.PrivateCredentialPermission
|
||||
* "a.b.Credential a.b.Principal "*"",
|
||||
* "read";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* If both the PrincipalClass and "PrincipalName" are "*",
|
||||
* then access is granted to the specified Credential owned by
|
||||
* any {@code Subject}.
|
||||
*
|
||||
* <p> In addition, the PrincipalClass/PrincipalName pairing may be repeated:
|
||||
*
|
||||
* <pre>
|
||||
* grant {
|
||||
* permission javax.security.auth.PrivateCredentialPermission
|
||||
* "a.b.Credential a.b.Principal "duke" c.d.Principal "dukette"",
|
||||
* "read";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* The above grants access to the private Credential, "a.b.Credential",
|
||||
* belonging to a {@code Subject} with at least two associated Principals:
|
||||
* "a.b.Principal" with the name, "duke", and "c.d.Principal", with the name,
|
||||
* "dukette".
|
||||
*
|
||||
*/
|
||||
public final class PrivateCredentialPermission extends Permission {
|
||||
|
||||
private static final long serialVersionUID = 5284372143517237068L;
|
||||
|
||||
private static final CredOwner[] EMPTY_PRINCIPALS = new CredOwner[0];
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
private String credentialClass;
|
||||
|
||||
/**
|
||||
* @serial The Principals associated with this permission.
|
||||
* The set contains elements of type,
|
||||
* {@code PrivateCredentialPermission.CredOwner}.
|
||||
*/
|
||||
private Set<Principal> principals; // ignored - kept around for compatibility
|
||||
private transient CredOwner[] credOwners;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
private boolean testing = false;
|
||||
|
||||
/**
|
||||
* Create a new {@code PrivateCredentialPermission}
|
||||
* with the specified {@code credentialClass} and Principals.
|
||||
*/
|
||||
PrivateCredentialPermission(String credentialClass,
|
||||
Set<Principal> principals) {
|
||||
|
||||
super(credentialClass);
|
||||
this.credentialClass = credentialClass;
|
||||
|
||||
synchronized(principals) {
|
||||
if (principals.size() == 0) {
|
||||
this.credOwners = EMPTY_PRINCIPALS;
|
||||
} else {
|
||||
this.credOwners = new CredOwner[principals.size()];
|
||||
int index = 0;
|
||||
Iterator<Principal> i = principals.iterator();
|
||||
while (i.hasNext()) {
|
||||
Principal p = i.next();
|
||||
this.credOwners[index++] = new CredOwner
|
||||
(p.getClass().getName(),
|
||||
p.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code PrivateCredentialPermission}
|
||||
* with the specified {@code name}. The {@code name}
|
||||
* specifies both a Credential class and a {@code Principal} Set.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param name the name specifying the Credential class and
|
||||
* {@code Principal} Set. <p>
|
||||
*
|
||||
* @param actions the actions specifying that the Credential can be read.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code name} does not conform
|
||||
* to the correct syntax or if {@code actions} is not "read".
|
||||
*/
|
||||
public PrivateCredentialPermission(String name, String actions) {
|
||||
super(name);
|
||||
|
||||
if (!"read".equalsIgnoreCase(actions))
|
||||
throw new IllegalArgumentException
|
||||
(ResourcesMgr.getString("actions.can.only.be.read."));
|
||||
init(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Class name of the Credential associated with this
|
||||
* {@code PrivateCredentialPermission}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the Class name of the Credential associated with this
|
||||
* {@code PrivateCredentialPermission}.
|
||||
*/
|
||||
public String getCredentialClass() {
|
||||
return credentialClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code Principal} classes and names
|
||||
* associated with this {@code PrivateCredentialPermission}.
|
||||
* The information is returned as a two-dimensional array (array[x][y]).
|
||||
* The 'x' value corresponds to the number of {@code Principal}
|
||||
* class and name pairs. When (y==0), it corresponds to
|
||||
* the {@code Principal} class value, and when (y==1),
|
||||
* it corresponds to the {@code Principal} name value.
|
||||
* For example, array[0][0] corresponds to the class name of
|
||||
* the first {@code Principal} in the array. array[0][1]
|
||||
* corresponds to the {@code Principal} name of the
|
||||
* first {@code Principal} in the array.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the {@code Principal} class and names associated
|
||||
* with this {@code PrivateCredentialPermission}.
|
||||
*/
|
||||
public String[][] getPrincipals() {
|
||||
|
||||
if (credOwners == null || credOwners.length == 0) {
|
||||
return new String[0][0];
|
||||
}
|
||||
|
||||
String[][] pArray = new String[credOwners.length][2];
|
||||
for (int i = 0; i < credOwners.length; i++) {
|
||||
pArray[i][0] = credOwners[i].principalClass;
|
||||
pArray[i][1] = credOwners[i].principalName;
|
||||
}
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this {@code PrivateCredentialPermission} implies
|
||||
* the specified {@code Permission}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* This method returns true if:
|
||||
* <ul>
|
||||
* <li> <i>p</i> is an instanceof PrivateCredentialPermission and
|
||||
* <li> the target name for <i>p</i> is implied by this object's
|
||||
* target name. For example:
|
||||
* <pre>
|
||||
* [* P1 "duke"] implies [a.b.Credential P1 "duke"].
|
||||
* [C1 P1 "duke"] implies [C1 P1 "duke" P2 "dukette"].
|
||||
* [C1 P2 "dukette"] implies [C1 P1 "duke" P2 "dukette"].
|
||||
* </pre>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param p the {@code Permission} to check against.
|
||||
*
|
||||
* @return true if this {@code PrivateCredentialPermission} implies
|
||||
* the specified {@code Permission}, false if not.
|
||||
*/
|
||||
public boolean implies(Permission p) {
|
||||
|
||||
if (p == null || !(p instanceof PrivateCredentialPermission))
|
||||
return false;
|
||||
|
||||
PrivateCredentialPermission that = (PrivateCredentialPermission)p;
|
||||
|
||||
if (!impliesCredentialClass(credentialClass, that.credentialClass))
|
||||
return false;
|
||||
|
||||
return impliesPrincipalSet(credOwners, that.credOwners);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks two {@code PrivateCredentialPermission} objects for
|
||||
* equality. Checks that <i>obj</i> is a
|
||||
* {@code PrivateCredentialPermission},
|
||||
* and has the same credential class as this object,
|
||||
* as well as the same Principals as this object.
|
||||
* The order of the Principals in the respective Permission's
|
||||
* target names is not relevant.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param obj the object we are testing for equality with this object.
|
||||
*
|
||||
* @return true if obj is a {@code PrivateCredentialPermission},
|
||||
* has the same credential class as this object,
|
||||
* and has the same Principals as this object.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
if (! (obj instanceof PrivateCredentialPermission))
|
||||
return false;
|
||||
|
||||
PrivateCredentialPermission that = (PrivateCredentialPermission)obj;
|
||||
|
||||
return (this.implies(that) && that.implies(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this object.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return this.credentialClass.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "canonical string representation" of the actions.
|
||||
* This method always returns the String, "read".
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the actions (always returns "read").
|
||||
*/
|
||||
public String getActions() {
|
||||
return "read";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a homogeneous collection of PrivateCredentialPermissions
|
||||
* in a {@code PermissionCollection}.
|
||||
* No such {@code PermissionCollection} is defined,
|
||||
* so this method always returns {@code null}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return null in all cases.
|
||||
*/
|
||||
public PermissionCollection newPermissionCollection() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void init(String name) {
|
||||
|
||||
if (name == null || name.trim().length() == 0) {
|
||||
throw new IllegalArgumentException("invalid empty name");
|
||||
}
|
||||
|
||||
ArrayList<CredOwner> pList = new ArrayList<>();
|
||||
StringTokenizer tokenizer = new StringTokenizer(name, " ", true);
|
||||
String principalClass = null;
|
||||
String principalName = null;
|
||||
|
||||
if (testing)
|
||||
System.out.println("whole name = " + name);
|
||||
|
||||
// get the Credential Class
|
||||
credentialClass = tokenizer.nextToken();
|
||||
if (testing)
|
||||
System.out.println("Credential Class = " + credentialClass);
|
||||
|
||||
if (tokenizer.hasMoreTokens() == false) {
|
||||
MessageFormat form = new MessageFormat(ResourcesMgr.getString
|
||||
("permission.name.name.syntax.invalid."));
|
||||
Object[] source = {name};
|
||||
throw new IllegalArgumentException
|
||||
(form.format(source) + ResourcesMgr.getString
|
||||
("Credential.Class.not.followed.by.a.Principal.Class.and.Name"));
|
||||
}
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
|
||||
// skip delimiter
|
||||
tokenizer.nextToken();
|
||||
|
||||
// get the Principal Class
|
||||
principalClass = tokenizer.nextToken();
|
||||
if (testing)
|
||||
System.out.println(" Principal Class = " + principalClass);
|
||||
|
||||
if (tokenizer.hasMoreTokens() == false) {
|
||||
MessageFormat form = new MessageFormat(ResourcesMgr.getString
|
||||
("permission.name.name.syntax.invalid."));
|
||||
Object[] source = {name};
|
||||
throw new IllegalArgumentException
|
||||
(form.format(source) + ResourcesMgr.getString
|
||||
("Principal.Class.not.followed.by.a.Principal.Name"));
|
||||
}
|
||||
|
||||
// skip delimiter
|
||||
tokenizer.nextToken();
|
||||
|
||||
// get the Principal Name
|
||||
principalName = tokenizer.nextToken();
|
||||
|
||||
if (!principalName.startsWith("\"")) {
|
||||
MessageFormat form = new MessageFormat(ResourcesMgr.getString
|
||||
("permission.name.name.syntax.invalid."));
|
||||
Object[] source = {name};
|
||||
throw new IllegalArgumentException
|
||||
(form.format(source) + ResourcesMgr.getString
|
||||
("Principal.Name.must.be.surrounded.by.quotes"));
|
||||
}
|
||||
|
||||
if (!principalName.endsWith("\"")) {
|
||||
|
||||
// we have a name with spaces in it --
|
||||
// keep parsing until we find the end quote,
|
||||
// and keep the spaces in the name
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
principalName = principalName + tokenizer.nextToken();
|
||||
if (principalName.endsWith("\""))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!principalName.endsWith("\"")) {
|
||||
MessageFormat form = new MessageFormat
|
||||
(ResourcesMgr.getString
|
||||
("permission.name.name.syntax.invalid."));
|
||||
Object[] source = {name};
|
||||
throw new IllegalArgumentException
|
||||
(form.format(source) + ResourcesMgr.getString
|
||||
("Principal.Name.missing.end.quote"));
|
||||
}
|
||||
}
|
||||
|
||||
if (testing)
|
||||
System.out.println("\tprincipalName = '" + principalName + "'");
|
||||
|
||||
principalName = principalName.substring
|
||||
(1, principalName.length() - 1);
|
||||
|
||||
if (principalClass.equals("*") &&
|
||||
!principalName.equals("*")) {
|
||||
throw new IllegalArgumentException(ResourcesMgr.getString
|
||||
("PrivateCredentialPermission.Principal.Class.can.not.be.a.wildcard.value.if.Principal.Name.is.not.a.wildcard.value"));
|
||||
}
|
||||
|
||||
if (testing)
|
||||
System.out.println("\tprincipalName = '" + principalName + "'");
|
||||
|
||||
pList.add(new CredOwner(principalClass, principalName));
|
||||
}
|
||||
|
||||
this.credOwners = new CredOwner[pList.size()];
|
||||
pList.toArray(this.credOwners);
|
||||
}
|
||||
|
||||
private boolean impliesCredentialClass(String thisC, String thatC) {
|
||||
|
||||
// this should never happen
|
||||
if (thisC == null || thatC == null)
|
||||
return false;
|
||||
|
||||
if (testing)
|
||||
System.out.println("credential class comparison: " +
|
||||
thisC + "/" + thatC);
|
||||
|
||||
if (thisC.equals("*"))
|
||||
return true;
|
||||
|
||||
/**
|
||||
* XXX let's not enable this for now --
|
||||
* if people want it, we'll enable it later
|
||||
*/
|
||||
/*
|
||||
if (thisC.endsWith("*")) {
|
||||
String cClass = thisC.substring(0, thisC.length() - 2);
|
||||
return thatC.startsWith(cClass);
|
||||
}
|
||||
*/
|
||||
|
||||
return thisC.equals(thatC);
|
||||
}
|
||||
|
||||
private boolean impliesPrincipalSet(CredOwner[] thisP, CredOwner[] thatP) {
|
||||
|
||||
// this should never happen
|
||||
if (thisP == null || thatP == null)
|
||||
return false;
|
||||
|
||||
if (thatP.length == 0)
|
||||
return true;
|
||||
|
||||
if (thisP.length == 0)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < thisP.length; i++) {
|
||||
boolean foundMatch = false;
|
||||
for (int j = 0; j < thatP.length; j++) {
|
||||
if (thisP[i].implies(thatP[j])) {
|
||||
foundMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this object from a stream (i.e., deserializes it)
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s) throws
|
||||
java.io.IOException,
|
||||
ClassNotFoundException {
|
||||
|
||||
s.defaultReadObject();
|
||||
|
||||
// perform new initialization from the permission name
|
||||
|
||||
if (getName().indexOf(" ") == -1 && getName().indexOf("\"") == -1) {
|
||||
|
||||
// name only has a credential class specified
|
||||
credentialClass = getName();
|
||||
credOwners = EMPTY_PRINCIPALS;
|
||||
|
||||
} else {
|
||||
|
||||
// perform regular initialization
|
||||
init(getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @serial include
|
||||
*/
|
||||
static class CredOwner implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5607449830436408266L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
String principalClass;
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
String principalName;
|
||||
|
||||
CredOwner(String principalClass, String principalName) {
|
||||
this.principalClass = principalClass;
|
||||
this.principalName = principalName;
|
||||
}
|
||||
|
||||
public boolean implies(Object obj) {
|
||||
if (obj == null || !(obj instanceof CredOwner))
|
||||
return false;
|
||||
|
||||
CredOwner that = (CredOwner)obj;
|
||||
|
||||
if (principalClass.equals("*") ||
|
||||
principalClass.equals(that.principalClass)) {
|
||||
|
||||
if (principalName.equals("*") ||
|
||||
principalName.equals(that.principalName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX no code yet to support a.b.*
|
||||
*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
MessageFormat form = new MessageFormat(ResourcesMgr.getString
|
||||
("CredOwner.Principal.Class.class.Principal.Name.name"));
|
||||
Object[] source = {principalClass, principalName};
|
||||
return (form.format(source));
|
||||
}
|
||||
}
|
||||
}
|
||||
60
jdkSrc/jdk8/javax/security/auth/RefreshFailedException.java
Normal file
60
jdkSrc/jdk8/javax/security/auth/RefreshFailedException.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth;
|
||||
|
||||
/**
|
||||
* Signals that a {@code refresh} operation failed.
|
||||
*
|
||||
* <p> This exception is thrown by credentials implementing
|
||||
* the {@code Refreshable} interface when the {@code refresh}
|
||||
* method fails.
|
||||
*
|
||||
*/
|
||||
public class RefreshFailedException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 5058444488565265840L;
|
||||
|
||||
/**
|
||||
* Constructs a RefreshFailedException with no detail message. A detail
|
||||
* message is a String that describes this particular exception.
|
||||
*/
|
||||
public RefreshFailedException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RefreshFailedException with the specified detail
|
||||
* message. A detail message is a String that describes this particular
|
||||
* exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public RefreshFailedException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
62
jdkSrc/jdk8/javax/security/auth/Refreshable.java
Normal file
62
jdkSrc/jdk8/javax/security/auth/Refreshable.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth;
|
||||
|
||||
/**
|
||||
* Objects such as credentials may optionally implement this
|
||||
* interface to provide the capability to refresh itself.
|
||||
* For example, a credential with a particular time-restricted lifespan
|
||||
* may implement this interface to allow callers to refresh the time period
|
||||
* for which it is valid.
|
||||
*
|
||||
* @see javax.security.auth.Subject
|
||||
*/
|
||||
public interface Refreshable {
|
||||
|
||||
/**
|
||||
* Determine if this {@code Object} is current.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return true if this {@code Object} is currently current,
|
||||
* false otherwise.
|
||||
*/
|
||||
boolean isCurrent();
|
||||
|
||||
/**
|
||||
* Update or extend the validity period for this
|
||||
* {@code Object}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @exception SecurityException if the caller does not have permission
|
||||
* to update or extend the validity period for this
|
||||
* {@code Object}. <p>
|
||||
*
|
||||
* @exception RefreshFailedException if the refresh attempt failed.
|
||||
*/
|
||||
void refresh() throws RefreshFailedException;
|
||||
}
|
||||
1467
jdkSrc/jdk8/javax/security/auth/Subject.java
Normal file
1467
jdkSrc/jdk8/javax/security/auth/Subject.java
Normal file
File diff suppressed because it is too large
Load Diff
583
jdkSrc/jdk8/javax/security/auth/SubjectDomainCombiner.java
Normal file
583
jdkSrc/jdk8/javax/security/auth/SubjectDomainCombiner.java
Normal file
@@ -0,0 +1,583 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.Permission;
|
||||
import java.security.Permissions;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Policy;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.security.Security;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.lang.ref.WeakReference;
|
||||
import sun.misc.SharedSecrets;
|
||||
import sun.misc.JavaSecurityProtectionDomainAccess;
|
||||
|
||||
/**
|
||||
* A {@code SubjectDomainCombiner} updates ProtectionDomains
|
||||
* with Principals from the {@code Subject} associated with this
|
||||
* {@code SubjectDomainCombiner}.
|
||||
*
|
||||
*/
|
||||
public class SubjectDomainCombiner implements java.security.DomainCombiner {
|
||||
|
||||
private Subject subject;
|
||||
private WeakKeyValueMap<ProtectionDomain, ProtectionDomain> cachedPDs =
|
||||
new WeakKeyValueMap<>();
|
||||
private Set<Principal> principalSet;
|
||||
private Principal[] principals;
|
||||
|
||||
private static final sun.security.util.Debug debug =
|
||||
sun.security.util.Debug.getInstance("combiner",
|
||||
"\t[SubjectDomainCombiner]");
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
// Note: check only at classloading time, not dynamically during combine()
|
||||
private static final boolean useJavaxPolicy =
|
||||
javax.security.auth.Policy.isCustomPolicySet(debug);
|
||||
|
||||
// Relevant only when useJavaxPolicy is true
|
||||
private static final boolean allowCaching =
|
||||
(useJavaxPolicy && cachePolicy());
|
||||
|
||||
private static final JavaSecurityProtectionDomainAccess pdAccess =
|
||||
SharedSecrets.getJavaSecurityProtectionDomainAccess();
|
||||
|
||||
/**
|
||||
* Associate the provided {@code Subject} with this
|
||||
* {@code SubjectDomainCombiner}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param subject the {@code Subject} to be associated with
|
||||
* with this {@code SubjectDomainCombiner}.
|
||||
*/
|
||||
public SubjectDomainCombiner(Subject subject) {
|
||||
this.subject = subject;
|
||||
|
||||
if (subject.isReadOnly()) {
|
||||
principalSet = subject.getPrincipals();
|
||||
principals = principalSet.toArray
|
||||
(new Principal[principalSet.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@code Subject} associated with this
|
||||
* {@code SubjectDomainCombiner}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the {@code Subject} associated with this
|
||||
* {@code SubjectDomainCombiner}, or {@code null}
|
||||
* if no {@code Subject} is associated with this
|
||||
* {@code SubjectDomainCombiner}.
|
||||
*
|
||||
* @exception SecurityException if the caller does not have permission
|
||||
* to get the {@code Subject} associated with this
|
||||
* {@code SubjectDomainCombiner}.
|
||||
*/
|
||||
public Subject getSubject() {
|
||||
java.lang.SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new AuthPermission
|
||||
("getSubjectFromDomainCombiner"));
|
||||
}
|
||||
return subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the relevant ProtectionDomains with the Principals
|
||||
* from the {@code Subject} associated with this
|
||||
* {@code SubjectDomainCombiner}.
|
||||
*
|
||||
* <p> A new {@code ProtectionDomain} instance is created
|
||||
* for each {@code ProtectionDomain} in the
|
||||
* <i>currentDomains</i> array. Each new {@code ProtectionDomain}
|
||||
* instance is created using the {@code CodeSource},
|
||||
* {@code Permission}s and {@code ClassLoader}
|
||||
* from the corresponding {@code ProtectionDomain} in
|
||||
* <i>currentDomains</i>, as well as with the Principals from
|
||||
* the {@code Subject} associated with this
|
||||
* {@code SubjectDomainCombiner}.
|
||||
*
|
||||
* <p> All of the newly instantiated ProtectionDomains are
|
||||
* combined into a new array. The ProtectionDomains from the
|
||||
* <i>assignedDomains</i> array are appended to this new array,
|
||||
* and the result is returned.
|
||||
*
|
||||
* <p> Note that optimizations such as the removal of duplicate
|
||||
* ProtectionDomains may have occurred.
|
||||
* In addition, caching of ProtectionDomains may be permitted.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param currentDomains the ProtectionDomains associated with the
|
||||
* current execution Thread, up to the most recent
|
||||
* privileged {@code ProtectionDomain}.
|
||||
* The ProtectionDomains are are listed in order of execution,
|
||||
* with the most recently executing {@code ProtectionDomain}
|
||||
* residing at the beginning of the array. This parameter may
|
||||
* be {@code null} if the current execution Thread
|
||||
* has no associated ProtectionDomains.<p>
|
||||
*
|
||||
* @param assignedDomains the ProtectionDomains inherited from the
|
||||
* parent Thread, or the ProtectionDomains from the
|
||||
* privileged <i>context</i>, if a call to
|
||||
* AccessController.doPrivileged(..., <i>context</i>)
|
||||
* had occurred This parameter may be {@code null}
|
||||
* if there were no ProtectionDomains inherited from the
|
||||
* parent Thread, or from the privileged <i>context</i>.
|
||||
*
|
||||
* @return a new array consisting of the updated ProtectionDomains,
|
||||
* or {@code null}.
|
||||
*/
|
||||
public ProtectionDomain[] combine(ProtectionDomain[] currentDomains,
|
||||
ProtectionDomain[] assignedDomains) {
|
||||
if (debug != null) {
|
||||
if (subject == null) {
|
||||
debug.println("null subject");
|
||||
} else {
|
||||
final Subject s = subject;
|
||||
AccessController.doPrivileged
|
||||
(new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
debug.println(s.toString());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
printInputDomains(currentDomains, assignedDomains);
|
||||
}
|
||||
|
||||
if (currentDomains == null || currentDomains.length == 0) {
|
||||
// No need to optimize assignedDomains because it should
|
||||
// have been previously optimized (when it was set).
|
||||
|
||||
// Note that we are returning a direct reference
|
||||
// to the input array - since ACC does not clone
|
||||
// the arrays when it calls combiner.combine,
|
||||
// multiple ACC instances may share the same
|
||||
// array instance in this case
|
||||
|
||||
return assignedDomains;
|
||||
}
|
||||
|
||||
// optimize currentDomains
|
||||
//
|
||||
// No need to optimize assignedDomains because it should
|
||||
// have been previously optimized (when it was set).
|
||||
|
||||
currentDomains = optimize(currentDomains);
|
||||
if (debug != null) {
|
||||
debug.println("after optimize");
|
||||
printInputDomains(currentDomains, assignedDomains);
|
||||
}
|
||||
|
||||
if (currentDomains == null && assignedDomains == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// maintain backwards compatibility for developers who provide
|
||||
// their own custom javax.security.auth.Policy implementations
|
||||
if (useJavaxPolicy) {
|
||||
return combineJavaxPolicy(currentDomains, assignedDomains);
|
||||
}
|
||||
|
||||
int cLen = (currentDomains == null ? 0 : currentDomains.length);
|
||||
int aLen = (assignedDomains == null ? 0 : assignedDomains.length);
|
||||
|
||||
// the ProtectionDomains for the new AccessControlContext
|
||||
// that we will return
|
||||
ProtectionDomain[] newDomains = new ProtectionDomain[cLen + aLen];
|
||||
|
||||
boolean allNew = true;
|
||||
synchronized(cachedPDs) {
|
||||
if (!subject.isReadOnly() &&
|
||||
!subject.getPrincipals().equals(principalSet)) {
|
||||
|
||||
// if the Subject was mutated, clear the PD cache
|
||||
Set<Principal> newSet = subject.getPrincipals();
|
||||
synchronized(newSet) {
|
||||
principalSet = new java.util.HashSet<Principal>(newSet);
|
||||
}
|
||||
principals = principalSet.toArray
|
||||
(new Principal[principalSet.size()]);
|
||||
cachedPDs.clear();
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Subject mutated - clearing cache");
|
||||
}
|
||||
}
|
||||
|
||||
ProtectionDomain subjectPd;
|
||||
for (int i = 0; i < cLen; i++) {
|
||||
ProtectionDomain pd = currentDomains[i];
|
||||
|
||||
subjectPd = cachedPDs.getValue(pd);
|
||||
|
||||
if (subjectPd == null) {
|
||||
if (pdAccess.getStaticPermissionsField(pd)) {
|
||||
// Need to keep static ProtectionDomain objects static
|
||||
subjectPd = new ProtectionDomain(pd.getCodeSource(),
|
||||
pd.getPermissions());
|
||||
} else {
|
||||
subjectPd = new ProtectionDomain(pd.getCodeSource(),
|
||||
pd.getPermissions(),
|
||||
pd.getClassLoader(),
|
||||
principals);
|
||||
}
|
||||
cachedPDs.putValue(pd, subjectPd);
|
||||
} else {
|
||||
allNew = false;
|
||||
}
|
||||
newDomains[i] = subjectPd;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("updated current: ");
|
||||
for (int i = 0; i < cLen; i++) {
|
||||
debug.println("\tupdated[" + i + "] = " +
|
||||
printDomain(newDomains[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// now add on the assigned domains
|
||||
if (aLen > 0) {
|
||||
System.arraycopy(assignedDomains, 0, newDomains, cLen, aLen);
|
||||
|
||||
// optimize the result (cached PDs might exist in assignedDomains)
|
||||
if (!allNew) {
|
||||
newDomains = optimize(newDomains);
|
||||
}
|
||||
}
|
||||
|
||||
// if aLen == 0 || allNew, no need to further optimize newDomains
|
||||
|
||||
if (debug != null) {
|
||||
if (newDomains == null || newDomains.length == 0) {
|
||||
debug.println("returning null");
|
||||
} else {
|
||||
debug.println("combinedDomains: ");
|
||||
for (int i = 0; i < newDomains.length; i++) {
|
||||
debug.println("newDomain " + i + ": " +
|
||||
printDomain(newDomains[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return the new ProtectionDomains
|
||||
if (newDomains == null || newDomains.length == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return newDomains;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the javax.security.auth.Policy implementation
|
||||
*/
|
||||
private ProtectionDomain[] combineJavaxPolicy(
|
||||
ProtectionDomain[] currentDomains,
|
||||
ProtectionDomain[] assignedDomains) {
|
||||
|
||||
if (!allowCaching) {
|
||||
java.security.AccessController.doPrivileged
|
||||
(new PrivilegedAction<Void>() {
|
||||
@SuppressWarnings("deprecation")
|
||||
public Void run() {
|
||||
// Call refresh only caching is disallowed
|
||||
javax.security.auth.Policy.getPolicy().refresh();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
int cLen = (currentDomains == null ? 0 : currentDomains.length);
|
||||
int aLen = (assignedDomains == null ? 0 : assignedDomains.length);
|
||||
|
||||
// the ProtectionDomains for the new AccessControlContext
|
||||
// that we will return
|
||||
ProtectionDomain[] newDomains = new ProtectionDomain[cLen + aLen];
|
||||
|
||||
synchronized(cachedPDs) {
|
||||
if (!subject.isReadOnly() &&
|
||||
!subject.getPrincipals().equals(principalSet)) {
|
||||
|
||||
// if the Subject was mutated, clear the PD cache
|
||||
Set<Principal> newSet = subject.getPrincipals();
|
||||
synchronized(newSet) {
|
||||
principalSet = new java.util.HashSet<Principal>(newSet);
|
||||
}
|
||||
principals = principalSet.toArray
|
||||
(new Principal[principalSet.size()]);
|
||||
cachedPDs.clear();
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("Subject mutated - clearing cache");
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < cLen; i++) {
|
||||
ProtectionDomain pd = currentDomains[i];
|
||||
ProtectionDomain subjectPd = cachedPDs.getValue(pd);
|
||||
|
||||
if (subjectPd == null) {
|
||||
if (pdAccess.getStaticPermissionsField(pd)) {
|
||||
// keep static ProtectionDomain objects static
|
||||
subjectPd = new ProtectionDomain(pd.getCodeSource(),
|
||||
pd.getPermissions());
|
||||
} else {
|
||||
// XXX
|
||||
// we must first add the original permissions.
|
||||
// that way when we later add the new JAAS permissions,
|
||||
// any unresolved JAAS-related permissions will
|
||||
// automatically get resolved.
|
||||
|
||||
// get the original perms
|
||||
Permissions perms = new Permissions();
|
||||
PermissionCollection coll = pd.getPermissions();
|
||||
java.util.Enumeration<Permission> e;
|
||||
if (coll != null) {
|
||||
synchronized (coll) {
|
||||
e = coll.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
Permission newPerm =
|
||||
e.nextElement();
|
||||
perms.add(newPerm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get perms from the policy
|
||||
final java.security.CodeSource finalCs = pd.getCodeSource();
|
||||
final Subject finalS = subject;
|
||||
PermissionCollection newPerms =
|
||||
java.security.AccessController.doPrivileged
|
||||
(new PrivilegedAction<PermissionCollection>() {
|
||||
@SuppressWarnings("deprecation")
|
||||
public PermissionCollection run() {
|
||||
return
|
||||
javax.security.auth.Policy.getPolicy().getPermissions
|
||||
(finalS, finalCs);
|
||||
}
|
||||
});
|
||||
|
||||
// add the newly granted perms,
|
||||
// avoiding duplicates
|
||||
synchronized (newPerms) {
|
||||
e = newPerms.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
Permission newPerm = e.nextElement();
|
||||
if (!perms.implies(newPerm)) {
|
||||
perms.add(newPerm);
|
||||
if (debug != null)
|
||||
debug.println (
|
||||
"Adding perm " + newPerm + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
subjectPd = new ProtectionDomain
|
||||
(finalCs, perms, pd.getClassLoader(), principals);
|
||||
}
|
||||
if (allowCaching)
|
||||
cachedPDs.putValue(pd, subjectPd);
|
||||
}
|
||||
newDomains[i] = subjectPd;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("updated current: ");
|
||||
for (int i = 0; i < cLen; i++) {
|
||||
debug.println("\tupdated[" + i + "] = " + newDomains[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// now add on the assigned domains
|
||||
if (aLen > 0) {
|
||||
System.arraycopy(assignedDomains, 0, newDomains, cLen, aLen);
|
||||
}
|
||||
|
||||
if (debug != null) {
|
||||
if (newDomains == null || newDomains.length == 0) {
|
||||
debug.println("returning null");
|
||||
} else {
|
||||
debug.println("combinedDomains: ");
|
||||
for (int i = 0; i < newDomains.length; i++) {
|
||||
debug.println("newDomain " + i + ": " +
|
||||
newDomains[i].toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return the new ProtectionDomains
|
||||
if (newDomains == null || newDomains.length == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return newDomains;
|
||||
}
|
||||
}
|
||||
|
||||
private static ProtectionDomain[] optimize(ProtectionDomain[] domains) {
|
||||
if (domains == null || domains.length == 0)
|
||||
return null;
|
||||
|
||||
ProtectionDomain[] optimized = new ProtectionDomain[domains.length];
|
||||
ProtectionDomain pd;
|
||||
int num = 0;
|
||||
for (int i = 0; i < domains.length; i++) {
|
||||
|
||||
// skip domains with AllPermission
|
||||
// XXX
|
||||
//
|
||||
// if (domains[i].implies(ALL_PERMISSION))
|
||||
// continue;
|
||||
|
||||
// skip System Domains
|
||||
if ((pd = domains[i]) != null) {
|
||||
|
||||
// remove duplicates
|
||||
boolean found = false;
|
||||
for (int j = 0; j < num && !found; j++) {
|
||||
found = (optimized[j] == pd);
|
||||
}
|
||||
if (!found) {
|
||||
optimized[num++] = pd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// resize the array if necessary
|
||||
if (num > 0 && num < domains.length) {
|
||||
ProtectionDomain[] downSize = new ProtectionDomain[num];
|
||||
System.arraycopy(optimized, 0, downSize, 0, downSize.length);
|
||||
optimized = downSize;
|
||||
}
|
||||
|
||||
return ((num == 0 || optimized.length == 0) ? null : optimized);
|
||||
}
|
||||
|
||||
private static boolean cachePolicy() {
|
||||
String s = AccessController.doPrivileged
|
||||
(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return Security.getProperty("cache.auth.policy");
|
||||
}
|
||||
});
|
||||
if (s != null) {
|
||||
return Boolean.parseBoolean(s);
|
||||
}
|
||||
|
||||
// cache by default
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void printInputDomains(ProtectionDomain[] currentDomains,
|
||||
ProtectionDomain[] assignedDomains) {
|
||||
if (currentDomains == null || currentDomains.length == 0) {
|
||||
debug.println("currentDomains null or 0 length");
|
||||
} else {
|
||||
for (int i = 0; currentDomains != null &&
|
||||
i < currentDomains.length; i++) {
|
||||
if (currentDomains[i] == null) {
|
||||
debug.println("currentDomain " + i + ": SystemDomain");
|
||||
} else {
|
||||
debug.println("currentDomain " + i + ": " +
|
||||
printDomain(currentDomains[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (assignedDomains == null || assignedDomains.length == 0) {
|
||||
debug.println("assignedDomains null or 0 length");
|
||||
} else {
|
||||
debug.println("assignedDomains = ");
|
||||
for (int i = 0; assignedDomains != null &&
|
||||
i < assignedDomains.length; i++) {
|
||||
if (assignedDomains[i] == null) {
|
||||
debug.println("assignedDomain " + i + ": SystemDomain");
|
||||
} else {
|
||||
debug.println("assignedDomain " + i + ": " +
|
||||
printDomain(assignedDomains[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String printDomain(final ProtectionDomain pd) {
|
||||
if (pd == null) {
|
||||
return "null";
|
||||
}
|
||||
return AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return pd.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A HashMap that has weak keys and values.
|
||||
*
|
||||
* Key objects in this map are the "current" ProtectionDomain instances
|
||||
* received via the combine method. Each "current" PD is mapped to a
|
||||
* new PD instance that holds both the contents of the "current" PD,
|
||||
* as well as the principals from the Subject associated with this combiner.
|
||||
*
|
||||
* The newly created "principal-based" PD values must be stored as
|
||||
* WeakReferences since they contain strong references to the
|
||||
* corresponding key object (the "current" non-principal-based PD),
|
||||
* which will prevent the key from being GC'd. Specifically,
|
||||
* a "principal-based" PD contains strong references to the CodeSource,
|
||||
* signer certs, PermissionCollection and ClassLoader objects
|
||||
* in the "current PD".
|
||||
*/
|
||||
private static class WeakKeyValueMap<K,V> extends
|
||||
WeakHashMap<K,WeakReference<V>> {
|
||||
|
||||
public V getValue(K key) {
|
||||
WeakReference<V> wr = super.get(key);
|
||||
if (wr != null) {
|
||||
return wr.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public V putValue(K key, V value) {
|
||||
WeakReference<V> wr = super.put(key, new WeakReference<V>(value));
|
||||
if (wr != null) {
|
||||
return wr.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
jdkSrc/jdk8/javax/security/auth/callback/Callback.java
Normal file
52
jdkSrc/jdk8/javax/security/auth/callback/Callback.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.security.auth.callback;
|
||||
|
||||
/**
|
||||
* <p> Implementations of this interface are passed to a
|
||||
* {@code 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> {@code Callback} implementations do not retrieve or
|
||||
* display the information requested by underlying security services.
|
||||
* {@code Callback} 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.
|
||||
*
|
||||
* @see javax.security.auth.callback.CallbackHandler
|
||||
* @see javax.security.auth.callback.ChoiceCallback
|
||||
* @see javax.security.auth.callback.ConfirmationCallback
|
||||
* @see javax.security.auth.callback.LanguageCallback
|
||||
* @see javax.security.auth.callback.NameCallback
|
||||
* @see javax.security.auth.callback.PasswordCallback
|
||||
* @see javax.security.auth.callback.TextInputCallback
|
||||
* @see javax.security.auth.callback.TextOutputCallback
|
||||
*/
|
||||
public interface Callback { }
|
||||
150
jdkSrc/jdk8/javax/security/auth/callback/CallbackHandler.java
Normal file
150
jdkSrc/jdk8/javax/security/auth/callback/CallbackHandler.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.callback;
|
||||
|
||||
/**
|
||||
* <p> An application implements a {@code CallbackHandler} 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> CallbackHandlers 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> Underlying security services make requests for different types
|
||||
* of information by passing individual Callbacks to the
|
||||
* {@code CallbackHandler}. The {@code CallbackHandler}
|
||||
* implementation decides how to retrieve and display information
|
||||
* depending on the Callbacks passed to it. For example,
|
||||
* if the underlying service needs a username and password to
|
||||
* authenticate a user, it uses a {@code NameCallback} and
|
||||
* {@code PasswordCallback}. The {@code CallbackHandler}
|
||||
* can then choose to prompt for a username and password serially,
|
||||
* or to prompt for both in a single window.
|
||||
*
|
||||
* <p> A default {@code CallbackHandler} class implementation
|
||||
* may be specified by setting the value of the
|
||||
* {@code auth.login.defaultCallbackHandler} security property.
|
||||
*
|
||||
* <p> If the security property is set to the fully qualified name of a
|
||||
* {@code CallbackHandler} implementation class,
|
||||
* then a {@code LoginContext} will load the specified
|
||||
* {@code CallbackHandler} and pass it to the underlying LoginModules.
|
||||
* The {@code LoginContext} only loads the default handler
|
||||
* if it was not provided one.
|
||||
*
|
||||
* <p> All default handler implementations must provide a public
|
||||
* zero-argument constructor.
|
||||
*
|
||||
* @see java.security.Security security properties
|
||||
*/
|
||||
public interface CallbackHandler {
|
||||
|
||||
/**
|
||||
* <p> Retrieve or display the information requested in the
|
||||
* provided Callbacks.
|
||||
*
|
||||
* <p> The {@code handle} method implementation checks the
|
||||
* instance(s) of the {@code Callback} object(s) passed in
|
||||
* to retrieve or display the requested information.
|
||||
* The following example is provided to help demonstrate what an
|
||||
* {@code handle} method implementation might look like.
|
||||
* This example code is for guidance only. Many details,
|
||||
* including proper error handling, are left out for simplicity.
|
||||
*
|
||||
* <pre>{@code
|
||||
* 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 {@code Callback} objects provided
|
||||
* by an underlying security service which contains
|
||||
* the information requested to be retrieved or displayed.
|
||||
*
|
||||
* @exception java.io.IOException if an input or output error occurs. <p>
|
||||
*
|
||||
* @exception UnsupportedCallbackException if the implementation of this
|
||||
* method does not support one or more of the Callbacks
|
||||
* specified in the {@code callbacks} parameter.
|
||||
*/
|
||||
void handle(Callback[] callbacks)
|
||||
throws java.io.IOException, UnsupportedCallbackException;
|
||||
}
|
||||
248
jdkSrc/jdk8/javax/security/auth/callback/ChoiceCallback.java
Normal file
248
jdkSrc/jdk8/javax/security/auth/callback/ChoiceCallback.java
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.callback;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
/**
|
||||
* <p> Underlying security services instantiate and pass a
|
||||
* {@code ChoiceCallback} to the {@code handle}
|
||||
* method of a {@code CallbackHandler} to display a list of choices
|
||||
* and to retrieve the selected choice(s).
|
||||
*
|
||||
* @see javax.security.auth.callback.CallbackHandler
|
||||
*/
|
||||
public class ChoiceCallback implements Callback, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3975664071579892167L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private final 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 final int defaultChoice;
|
||||
/**
|
||||
* @serial whether multiple selections are allowed from the list of
|
||||
* choices
|
||||
* @since 1.4
|
||||
*/
|
||||
private final boolean multipleSelectionsAllowed;
|
||||
/**
|
||||
* @serial the selected choices, represented as indexes into the
|
||||
* {@code choices} list.
|
||||
* @since 1.4
|
||||
*/
|
||||
private int[] selections;
|
||||
|
||||
/**
|
||||
* Construct a {@code ChoiceCallback} 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.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param prompt the prompt used to describe the list of choices. <p>
|
||||
*
|
||||
* @param choices the list of choices. <p>
|
||||
*
|
||||
* @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} array. <p>
|
||||
*
|
||||
* @param multipleSelectionsAllowed boolean specifying whether or
|
||||
* not multiple selections can be made from the
|
||||
* list of choices.
|
||||
*
|
||||
* @exception IllegalArgumentException if {@code prompt} is null,
|
||||
* if {@code prompt} has a length of 0,
|
||||
* if {@code choices} is null,
|
||||
* if {@code choices} has a length of 0,
|
||||
* if any element from {@code choices} is null,
|
||||
* if any element from {@code choices}
|
||||
* has a length of 0 or if {@code defaultChoice}
|
||||
* does not fall within the array boundaries of
|
||||
* {@code choices}.
|
||||
*/
|
||||
public ChoiceCallback(String prompt, String[] choices,
|
||||
int defaultChoice, boolean multipleSelectionsAllowed) {
|
||||
|
||||
if (prompt == null || prompt.length() == 0 ||
|
||||
choices == null || choices.length == 0 ||
|
||||
defaultChoice < 0 || defaultChoice >= choices.length)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.prompt = prompt;
|
||||
this.defaultChoice = defaultChoice;
|
||||
this.multipleSelectionsAllowed = multipleSelectionsAllowed;
|
||||
|
||||
this.choices = choices.clone();
|
||||
for (int i = 0; i < choices.length; i++) {
|
||||
if (choices[i] == null || choices[i].length() == 0)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prompt.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the prompt.
|
||||
*/
|
||||
public String getPrompt() {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of choices.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the list of choices.
|
||||
*/
|
||||
public String[] getChoices() {
|
||||
return choices.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the defaultChoice.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the defaultChoice, represented as an index into
|
||||
* the {@code choices} list.
|
||||
*/
|
||||
public int getDefaultChoice() {
|
||||
return defaultChoice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the boolean determining whether multiple selections from
|
||||
* the {@code choices} list are allowed.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return whether multiple selections are allowed.
|
||||
*/
|
||||
public boolean allowMultipleSelections() {
|
||||
return multipleSelectionsAllowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the selected choice.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param selection the selection represented as an index into the
|
||||
* {@code choices} list.
|
||||
*
|
||||
* @see #getSelectedIndexes
|
||||
*/
|
||||
public void setSelectedIndex(int selection) {
|
||||
this.selections = new int[1];
|
||||
this.selections[0] = selection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the selected choices.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param selections the selections represented as indexes into the
|
||||
* {@code choices} list.
|
||||
*
|
||||
* @exception UnsupportedOperationException if multiple selections are
|
||||
* not allowed, as determined by
|
||||
* {@code allowMultipleSelections}.
|
||||
*
|
||||
* @see #getSelectedIndexes
|
||||
*/
|
||||
public void setSelectedIndexes(int[] selections) {
|
||||
if (!multipleSelectionsAllowed)
|
||||
throw new UnsupportedOperationException();
|
||||
this.selections = selections == null ? null : selections.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected choices.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the selected choices, represented as indexes into the
|
||||
* {@code choices} list.
|
||||
*
|
||||
* @see #setSelectedIndexes
|
||||
*/
|
||||
public int[] getSelectedIndexes() {
|
||||
return selections == null ? null : selections.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the state of this object from the stream.
|
||||
*
|
||||
* @param stream the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
|
||||
if ((prompt == null) || prompt.isEmpty() ||
|
||||
(choices == null) || (choices.length == 0) ||
|
||||
(defaultChoice < 0) || (defaultChoice >= choices.length)) {
|
||||
throw new InvalidObjectException(
|
||||
"Missing/invalid prompt/choices");
|
||||
}
|
||||
|
||||
choices = choices.clone();
|
||||
for (int i = 0; i < choices.length; i++) {
|
||||
if ((choices[i] == null) || choices[i].isEmpty())
|
||||
throw new InvalidObjectException("Null/empty choices");
|
||||
}
|
||||
|
||||
if (selections != null) {
|
||||
selections = selections.clone();
|
||||
if (!multipleSelectionsAllowed && (selections.length != 1)) {
|
||||
throw new InvalidObjectException(
|
||||
"Multiple selections not allowed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.callback;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
/**
|
||||
* <p> Underlying security services instantiate and pass a
|
||||
* {@code ConfirmationCallback} to the {@code handle}
|
||||
* method of a {@code CallbackHandler} to ask for YES/NO,
|
||||
* OK/CANCEL, YES/NO/CANCEL or other similar confirmations.
|
||||
*
|
||||
* @see javax.security.auth.callback.CallbackHandler
|
||||
*/
|
||||
public class ConfirmationCallback implements Callback, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -9095656433782481624L;
|
||||
|
||||
/**
|
||||
* Unspecified option type.
|
||||
*
|
||||
* <p> The {@code getOptionType} method returns this
|
||||
* value if this {@code ConfirmationCallback} was instantiated
|
||||
* with {@code options} instead of an {@code optionType}.
|
||||
*/
|
||||
public static final int UNSPECIFIED_OPTION = -1;
|
||||
|
||||
/**
|
||||
* YES/NO confirmation option.
|
||||
*
|
||||
* <p> An underlying security service specifies this as the
|
||||
* {@code optionType} to a {@code ConfirmationCallback}
|
||||
* constructor if it requires a confirmation which can be answered
|
||||
* with either {@code YES} or {@code NO}.
|
||||
*/
|
||||
public static final int YES_NO_OPTION = 0;
|
||||
|
||||
/**
|
||||
* YES/NO/CANCEL confirmation confirmation option.
|
||||
*
|
||||
* <p> An underlying security service specifies this as the
|
||||
* {@code optionType} to a {@code ConfirmationCallback}
|
||||
* constructor if it requires a confirmation which can be answered
|
||||
* with either {@code YES}, {@code NO} or {@code CANCEL}.
|
||||
*/
|
||||
public static final int YES_NO_CANCEL_OPTION = 1;
|
||||
|
||||
/**
|
||||
* OK/CANCEL confirmation confirmation option.
|
||||
*
|
||||
* <p> An underlying security service specifies this as the
|
||||
* {@code optionType} to a {@code ConfirmationCallback}
|
||||
* constructor if it requires a confirmation which can be answered
|
||||
* with either {@code OK} or {@code CANCEL}.
|
||||
*/
|
||||
public static final int OK_CANCEL_OPTION = 2;
|
||||
|
||||
/**
|
||||
* YES option.
|
||||
*
|
||||
* <p> If an {@code optionType} was specified to this
|
||||
* {@code ConfirmationCallback}, this option may be specified as a
|
||||
* {@code defaultOption} or returned as the selected index.
|
||||
*/
|
||||
public static final int YES = 0;
|
||||
|
||||
/**
|
||||
* NO option.
|
||||
*
|
||||
* <p> If an {@code optionType} was specified to this
|
||||
* {@code ConfirmationCallback}, this option may be specified as a
|
||||
* {@code defaultOption} or returned as the selected index.
|
||||
*/
|
||||
public static final int NO = 1;
|
||||
|
||||
/**
|
||||
* CANCEL option.
|
||||
*
|
||||
* <p> If an {@code optionType} was specified to this
|
||||
* {@code ConfirmationCallback}, this option may be specified as a
|
||||
* {@code defaultOption} or returned as the selected index.
|
||||
*/
|
||||
public static final int CANCEL = 2;
|
||||
|
||||
/**
|
||||
* OK option.
|
||||
*
|
||||
* <p> If an {@code optionType} was specified to this
|
||||
* {@code ConfirmationCallback}, this option may be specified as a
|
||||
* {@code defaultOption} or returned as the selected index.
|
||||
*/
|
||||
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 final String prompt;
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private final int messageType;
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private final int optionType;
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private final int defaultOption;
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private String[] options;
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private int selection;
|
||||
|
||||
/**
|
||||
* Construct a {@code ConfirmationCallback} with a
|
||||
* message type, an option type and a default option.
|
||||
*
|
||||
* <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 ({@code INFORMATION},
|
||||
* {@code WARNING} or {@code ERROR}). <p>
|
||||
*
|
||||
* @param optionType the option type ({@code YES_NO_OPTION},
|
||||
* {@code YES_NO_CANCEL_OPTION} or
|
||||
* {@code OK_CANCEL_OPTION}). <p>
|
||||
*
|
||||
* @param defaultOption the default option
|
||||
* from the provided optionType ({@code YES},
|
||||
* {@code NO}, {@code CANCEL} or
|
||||
* {@code OK}).
|
||||
*
|
||||
* @exception IllegalArgumentException if messageType is not either
|
||||
* {@code INFORMATION}, {@code WARNING},
|
||||
* or {@code ERROR}, if optionType is not either
|
||||
* {@code YES_NO_OPTION},
|
||||
* {@code YES_NO_CANCEL_OPTION}, or
|
||||
* {@code OK_CANCEL_OPTION},
|
||||
* or if {@code defaultOption}
|
||||
* does not correspond to one of the options in
|
||||
* {@code optionType}.
|
||||
*/
|
||||
public ConfirmationCallback(int messageType,
|
||||
int optionType, int defaultOption) {
|
||||
|
||||
if (messageType < INFORMATION || messageType > ERROR ||
|
||||
optionType < YES_NO_OPTION || optionType > OK_CANCEL_OPTION)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
switch (optionType) {
|
||||
case YES_NO_OPTION:
|
||||
if (defaultOption != YES && defaultOption != NO)
|
||||
throw new IllegalArgumentException();
|
||||
break;
|
||||
case YES_NO_CANCEL_OPTION:
|
||||
if (defaultOption != YES && defaultOption != NO &&
|
||||
defaultOption != CANCEL)
|
||||
throw new IllegalArgumentException();
|
||||
break;
|
||||
case OK_CANCEL_OPTION:
|
||||
if (defaultOption != OK && defaultOption != CANCEL)
|
||||
throw new IllegalArgumentException();
|
||||
break;
|
||||
}
|
||||
|
||||
this.prompt = null;
|
||||
this.messageType = messageType;
|
||||
this.optionType = optionType;
|
||||
this.options = null;
|
||||
this.defaultOption = defaultOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@code ConfirmationCallback} with a
|
||||
* message type, a list of options and a default option.
|
||||
*
|
||||
* <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} array,
|
||||
* and are displayed by the {@code CallbackHandler} implementation
|
||||
* in a manner consistent with the way preset options are displayed.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param messageType the message type ({@code INFORMATION},
|
||||
* {@code WARNING} or {@code ERROR}). <p>
|
||||
*
|
||||
* @param options the list of confirmation options. <p>
|
||||
*
|
||||
* @param defaultOption the default option, represented as an index
|
||||
* into the {@code options} array.
|
||||
*
|
||||
* @exception IllegalArgumentException if messageType is not either
|
||||
* {@code INFORMATION}, {@code WARNING},
|
||||
* or {@code ERROR}, if {@code options} is null,
|
||||
* if {@code options} has a length of 0,
|
||||
* if any element from {@code options} is null,
|
||||
* if any element from {@code options}
|
||||
* has a length of 0, or if {@code defaultOption}
|
||||
* does not lie within the array boundaries of
|
||||
* {@code options}.
|
||||
*/
|
||||
public ConfirmationCallback(int messageType,
|
||||
String[] options, int defaultOption) {
|
||||
|
||||
if (messageType < INFORMATION || messageType > ERROR ||
|
||||
options == null || options.length == 0 ||
|
||||
defaultOption < 0 || defaultOption >= options.length)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.prompt = null;
|
||||
this.messageType = messageType;
|
||||
this.optionType = UNSPECIFIED_OPTION;
|
||||
this.defaultOption = defaultOption;
|
||||
|
||||
this.options = options.clone();
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
if (options[i] == null || options[i].length() == 0)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@code ConfirmationCallback} with a prompt,
|
||||
* message type, an option type and a default option.
|
||||
*
|
||||
* <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. <p>
|
||||
*
|
||||
* @param messageType the message type ({@code INFORMATION},
|
||||
* {@code WARNING} or {@code ERROR}). <p>
|
||||
*
|
||||
* @param optionType the option type ({@code YES_NO_OPTION},
|
||||
* {@code YES_NO_CANCEL_OPTION} or
|
||||
* {@code OK_CANCEL_OPTION}). <p>
|
||||
*
|
||||
* @param defaultOption the default option
|
||||
* from the provided optionType ({@code YES},
|
||||
* {@code NO}, {@code CANCEL} or
|
||||
* {@code OK}).
|
||||
*
|
||||
* @exception IllegalArgumentException if {@code prompt} is null,
|
||||
* if {@code prompt} has a length of 0,
|
||||
* if messageType is not either
|
||||
* {@code INFORMATION}, {@code WARNING},
|
||||
* or {@code ERROR}, if optionType is not either
|
||||
* {@code YES_NO_OPTION},
|
||||
* {@code YES_NO_CANCEL_OPTION}, or
|
||||
* {@code OK_CANCEL_OPTION},
|
||||
* or if {@code defaultOption}
|
||||
* does not correspond to one of the options in
|
||||
* {@code optionType}.
|
||||
*/
|
||||
public ConfirmationCallback(String prompt, int messageType,
|
||||
int optionType, int defaultOption) {
|
||||
|
||||
if (prompt == null || prompt.length() == 0 ||
|
||||
messageType < INFORMATION || messageType > ERROR ||
|
||||
optionType < YES_NO_OPTION || optionType > OK_CANCEL_OPTION)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
switch (optionType) {
|
||||
case YES_NO_OPTION:
|
||||
if (defaultOption != YES && defaultOption != NO)
|
||||
throw new IllegalArgumentException();
|
||||
break;
|
||||
case YES_NO_CANCEL_OPTION:
|
||||
if (defaultOption != YES && defaultOption != NO &&
|
||||
defaultOption != CANCEL)
|
||||
throw new IllegalArgumentException();
|
||||
break;
|
||||
case OK_CANCEL_OPTION:
|
||||
if (defaultOption != OK && defaultOption != CANCEL)
|
||||
throw new IllegalArgumentException();
|
||||
break;
|
||||
}
|
||||
|
||||
this.prompt = prompt;
|
||||
this.messageType = messageType;
|
||||
this.optionType = optionType;
|
||||
this.options = null;
|
||||
this.defaultOption = defaultOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@code ConfirmationCallback} with a prompt,
|
||||
* message type, a list of options and a default option.
|
||||
*
|
||||
* <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} array,
|
||||
* and are displayed by the {@code 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. <p>
|
||||
*
|
||||
* @param messageType the message type ({@code INFORMATION},
|
||||
* {@code WARNING} or {@code ERROR}). <p>
|
||||
*
|
||||
* @param options the list of confirmation options. <p>
|
||||
*
|
||||
* @param defaultOption the default option, represented as an index
|
||||
* into the {@code options} array.
|
||||
*
|
||||
* @exception IllegalArgumentException if {@code prompt} is null,
|
||||
* if {@code prompt} has a length of 0,
|
||||
* if messageType is not either
|
||||
* {@code INFORMATION}, {@code WARNING},
|
||||
* or {@code ERROR}, if {@code options} is null,
|
||||
* if {@code options} has a length of 0,
|
||||
* if any element from {@code options} is null,
|
||||
* if any element from {@code options}
|
||||
* has a length of 0, or if {@code defaultOption}
|
||||
* does not lie within the array boundaries of
|
||||
* {@code options}.
|
||||
*/
|
||||
public ConfirmationCallback(String prompt, int messageType,
|
||||
String[] options, int defaultOption) {
|
||||
|
||||
if (prompt == null || prompt.length() == 0 ||
|
||||
messageType < INFORMATION || messageType > ERROR ||
|
||||
options == null || options.length == 0 ||
|
||||
defaultOption < 0 || defaultOption >= options.length)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.prompt = prompt;
|
||||
this.messageType = messageType;
|
||||
this.optionType = UNSPECIFIED_OPTION;
|
||||
this.defaultOption = defaultOption;
|
||||
|
||||
this.options = options.clone();
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
if (options[i] == null || options[i].length() == 0)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prompt.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the prompt, or null if this {@code ConfirmationCallback}
|
||||
* was instantiated without a {@code prompt}.
|
||||
*/
|
||||
public String getPrompt() {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message type.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the message type ({@code INFORMATION},
|
||||
* {@code WARNING} or {@code ERROR}).
|
||||
*/
|
||||
public int getMessageType() {
|
||||
return messageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the option type.
|
||||
*
|
||||
* <p> If this method returns {@code UNSPECIFIED_OPTION}, then this
|
||||
* {@code ConfirmationCallback} was instantiated with
|
||||
* {@code options} instead of an {@code optionType}.
|
||||
* In this case, invoke the {@code getOptions} method
|
||||
* to determine which confirmation options to display.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the option type ({@code YES_NO_OPTION},
|
||||
* {@code YES_NO_CANCEL_OPTION} or
|
||||
* {@code OK_CANCEL_OPTION}), or
|
||||
* {@code UNSPECIFIED_OPTION} if this
|
||||
* {@code ConfirmationCallback} was instantiated with
|
||||
* {@code options} instead of an {@code optionType}.
|
||||
*/
|
||||
public int getOptionType() {
|
||||
return optionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the confirmation options.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the list of confirmation options, or null if this
|
||||
* {@code ConfirmationCallback} was instantiated with
|
||||
* an {@code optionType} instead of {@code options}.
|
||||
*/
|
||||
public String[] getOptions() {
|
||||
return options == null ? null : options.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default option.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the default option, represented as
|
||||
* {@code YES}, {@code NO}, {@code OK} or
|
||||
* {@code CANCEL} if an {@code optionType}
|
||||
* was specified to the constructor of this
|
||||
* {@code ConfirmationCallback}.
|
||||
* Otherwise, this method returns the default option as
|
||||
* an index into the
|
||||
* {@code options} array specified to the constructor
|
||||
* of this {@code ConfirmationCallback}.
|
||||
*/
|
||||
public int getDefaultOption() {
|
||||
return defaultOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the selected confirmation option.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param selection the selection represented as {@code YES},
|
||||
* {@code NO}, {@code OK} or {@code CANCEL}
|
||||
* if an {@code optionType} was specified to the constructor
|
||||
* of this {@code ConfirmationCallback}.
|
||||
* Otherwise, the selection represents the index into the
|
||||
* {@code options} array specified to the constructor
|
||||
* of this {@code ConfirmationCallback}.
|
||||
*
|
||||
* @see #getSelectedIndex
|
||||
*/
|
||||
public void setSelectedIndex(int selection) {
|
||||
this.selection = selection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected confirmation option.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the selected confirmation option represented as
|
||||
* {@code YES}, {@code NO}, {@code OK} or
|
||||
* {@code CANCEL} if an {@code optionType}
|
||||
* was specified to the constructor of this
|
||||
* {@code ConfirmationCallback}.
|
||||
* Otherwise, this method returns the selected confirmation
|
||||
* option as an index into the
|
||||
* {@code options} array specified to the constructor
|
||||
* of this {@code ConfirmationCallback}.
|
||||
*
|
||||
* @see #setSelectedIndex
|
||||
*/
|
||||
public int getSelectedIndex() {
|
||||
return selection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the state of this object from the stream.
|
||||
*
|
||||
* @param stream the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
if (options != null) {
|
||||
options = options.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.callback;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* <p> Underlying security services instantiate and pass a
|
||||
* {@code LanguageCallback} to the {@code handle}
|
||||
* method of a {@code CallbackHandler} to retrieve the {@code Locale}
|
||||
* used for localizing text.
|
||||
*
|
||||
* @see javax.security.auth.callback.CallbackHandler
|
||||
*/
|
||||
public class LanguageCallback implements Callback, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2019050433478903213L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private Locale locale;
|
||||
|
||||
/**
|
||||
* Construct a {@code LanguageCallback}.
|
||||
*/
|
||||
public LanguageCallback() { }
|
||||
|
||||
/**
|
||||
* Set the retrieved {@code Locale}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param locale the retrieved {@code Locale}.
|
||||
*
|
||||
* @see #getLocale
|
||||
*/
|
||||
public void setLocale(Locale locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the retrieved {@code Locale}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the retrieved {@code Locale}, or null
|
||||
* if no {@code Locale} could be retrieved.
|
||||
*
|
||||
* @see #setLocale
|
||||
*/
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
144
jdkSrc/jdk8/javax/security/auth/callback/NameCallback.java
Normal file
144
jdkSrc/jdk8/javax/security/auth/callback/NameCallback.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.callback;
|
||||
|
||||
/**
|
||||
* <p> Underlying security services instantiate and pass a
|
||||
* {@code NameCallback} to the {@code handle}
|
||||
* method of a {@code CallbackHandler} to retrieve name information.
|
||||
*
|
||||
* @see javax.security.auth.callback.CallbackHandler
|
||||
*/
|
||||
public class NameCallback implements Callback, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3770938795909392253L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private String prompt;
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private String defaultName;
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private String inputName;
|
||||
|
||||
/**
|
||||
* Construct a {@code NameCallback} with a prompt.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param prompt the prompt used to request the name.
|
||||
*
|
||||
* @exception IllegalArgumentException if {@code prompt} is null
|
||||
* or if {@code prompt} has a length of 0.
|
||||
*/
|
||||
public NameCallback(String prompt) {
|
||||
if (prompt == null || prompt.length() == 0)
|
||||
throw new IllegalArgumentException();
|
||||
this.prompt = prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@code NameCallback} with a prompt
|
||||
* and default name.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param prompt the prompt used to request the information. <p>
|
||||
*
|
||||
* @param defaultName the name to be used as the default name displayed
|
||||
* with the prompt.
|
||||
*
|
||||
* @exception IllegalArgumentException if {@code prompt} is null,
|
||||
* if {@code prompt} has a length of 0,
|
||||
* if {@code defaultName} is null,
|
||||
* or if {@code defaultName} has a length of 0.
|
||||
*/
|
||||
public NameCallback(String prompt, String defaultName) {
|
||||
if (prompt == null || prompt.length() == 0 ||
|
||||
defaultName == null || defaultName.length() == 0)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.prompt = prompt;
|
||||
this.defaultName = defaultName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prompt.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the prompt.
|
||||
*/
|
||||
public String getPrompt() {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default name.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the default name, or null if this {@code NameCallback}
|
||||
* was not instantiated with a {@code defaultName}.
|
||||
*/
|
||||
public String getDefaultName() {
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the retrieved name.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param name the retrieved name (which may be null).
|
||||
*
|
||||
* @see #getName
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.inputName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the retrieved name.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the retrieved name (which may be null)
|
||||
*
|
||||
* @see #setName
|
||||
*/
|
||||
public String getName() {
|
||||
return inputName;
|
||||
}
|
||||
}
|
||||
192
jdkSrc/jdk8/javax/security/auth/callback/PasswordCallback.java
Normal file
192
jdkSrc/jdk8/javax/security/auth/callback/PasswordCallback.java
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.callback;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.Arrays;
|
||||
import sun.misc.Cleaner;
|
||||
|
||||
/**
|
||||
* <p> Underlying security services instantiate and pass a
|
||||
* {@code PasswordCallback} to the {@code handle}
|
||||
* method of a {@code CallbackHandler} to retrieve password information.
|
||||
*
|
||||
* @see javax.security.auth.callback.CallbackHandler
|
||||
*/
|
||||
public class PasswordCallback implements Callback, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2267422647454909926L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private final String prompt;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private final boolean echoOn;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private char[] inputPassword;
|
||||
|
||||
private transient Cleaner cleaner;
|
||||
|
||||
/**
|
||||
* Construct a {@code PasswordCallback} with a prompt
|
||||
* and a boolean specifying whether the password should be displayed
|
||||
* as it is being typed.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param prompt the prompt used to request the password. <p>
|
||||
*
|
||||
* @param echoOn true if the password should be displayed
|
||||
* as it is being typed.
|
||||
*
|
||||
* @exception IllegalArgumentException if {@code prompt} is null or
|
||||
* if {@code prompt} has a length of 0.
|
||||
*/
|
||||
public PasswordCallback(String prompt, boolean echoOn) {
|
||||
if (prompt == null || prompt.length() == 0)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.prompt = prompt;
|
||||
this.echoOn = echoOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prompt.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the prompt.
|
||||
*/
|
||||
public String getPrompt() {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the password
|
||||
* should be displayed as it is being typed.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the whether the password
|
||||
* should be displayed as it is being typed.
|
||||
*/
|
||||
public boolean isEchoOn() {
|
||||
return echoOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the retrieved password.
|
||||
*
|
||||
* <p> This method makes a copy of the input <i>password</i>
|
||||
* before storing it.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param password the retrieved password, which may be null.
|
||||
*
|
||||
* @see #getPassword
|
||||
*/
|
||||
public void setPassword(char[] password) {
|
||||
// Cleanup the last buffered password copy.
|
||||
if (cleaner != null) {
|
||||
cleaner.clean();
|
||||
cleaner = null;
|
||||
}
|
||||
|
||||
// Set the retrieved password.
|
||||
this.inputPassword = (password == null ? null : password.clone());
|
||||
|
||||
if (this.inputPassword != null) {
|
||||
cleaner = Cleaner.create(this, cleanerFor(inputPassword));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the retrieved password.
|
||||
*
|
||||
* <p> This method returns a copy of the retrieved password.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the retrieved password, which may be null.
|
||||
*
|
||||
* @see #setPassword
|
||||
*/
|
||||
public char[] getPassword() {
|
||||
return (inputPassword == null ? null : inputPassword.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the retrieved password.
|
||||
*/
|
||||
public void clearPassword() {
|
||||
// Cleanup the last retrieved password copy.
|
||||
if (cleaner != null) {
|
||||
cleaner.clean();
|
||||
cleaner = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Runnable cleanerFor(char[] password) {
|
||||
return () -> {
|
||||
Arrays.fill(password, ' ');
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the state of this object from the stream.
|
||||
*
|
||||
* @param stream the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
|
||||
if (prompt == null || prompt.isEmpty()) {
|
||||
throw new InvalidObjectException("Missing prompt");
|
||||
}
|
||||
|
||||
if (inputPassword != null) {
|
||||
inputPassword = inputPassword.clone();
|
||||
cleaner = Cleaner.create(this, cleanerFor(inputPassword));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
145
jdkSrc/jdk8/javax/security/auth/callback/TextInputCallback.java
Normal file
145
jdkSrc/jdk8/javax/security/auth/callback/TextInputCallback.java
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.callback;
|
||||
|
||||
/**
|
||||
* <p> Underlying security services instantiate and pass a
|
||||
* {@code TextInputCallback} to the {@code handle}
|
||||
* method of a {@code CallbackHandler} to retrieve generic text
|
||||
* information.
|
||||
*
|
||||
* @see javax.security.auth.callback.CallbackHandler
|
||||
*/
|
||||
public class TextInputCallback implements Callback, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8064222478852811804L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private String prompt;
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private String defaultText;
|
||||
/**
|
||||
* @serial
|
||||
* @since 1.4
|
||||
*/
|
||||
private String inputText;
|
||||
|
||||
/**
|
||||
* Construct a {@code TextInputCallback} with a prompt.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param prompt the prompt used to request the information.
|
||||
*
|
||||
* @exception IllegalArgumentException if {@code prompt} is null
|
||||
* or if {@code prompt} has a length of 0.
|
||||
*/
|
||||
public TextInputCallback(String prompt) {
|
||||
if (prompt == null || prompt.length() == 0)
|
||||
throw new IllegalArgumentException();
|
||||
this.prompt = prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@code TextInputCallback} with a prompt
|
||||
* and default input value.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param prompt the prompt used to request the information. <p>
|
||||
*
|
||||
* @param defaultText the text to be used as the default text displayed
|
||||
* with the prompt.
|
||||
*
|
||||
* @exception IllegalArgumentException if {@code prompt} is null,
|
||||
* if {@code prompt} has a length of 0,
|
||||
* if {@code defaultText} is null
|
||||
* or if {@code defaultText} has a length of 0.
|
||||
*/
|
||||
public TextInputCallback(String prompt, String defaultText) {
|
||||
if (prompt == null || prompt.length() == 0 ||
|
||||
defaultText == null || defaultText.length() == 0)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.prompt = prompt;
|
||||
this.defaultText = defaultText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prompt.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the prompt.
|
||||
*/
|
||||
public String getPrompt() {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default text.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the default text, or null if this {@code TextInputCallback}
|
||||
* was not instantiated with {@code defaultText}.
|
||||
*/
|
||||
public String getDefaultText() {
|
||||
return defaultText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the retrieved text.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param text the retrieved text, which may be null.
|
||||
*
|
||||
* @see #getText
|
||||
*/
|
||||
public void setText(String text) {
|
||||
this.inputText = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the retrieved text.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the retrieved text, which may be null.
|
||||
*
|
||||
* @see #setText
|
||||
*/
|
||||
public String getText() {
|
||||
return inputText;
|
||||
}
|
||||
}
|
||||
107
jdkSrc/jdk8/javax/security/auth/callback/TextOutputCallback.java
Normal file
107
jdkSrc/jdk8/javax/security/auth/callback/TextOutputCallback.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.callback;
|
||||
|
||||
/**
|
||||
* <p> Underlying security services instantiate and pass a
|
||||
* {@code TextOutputCallback} to the {@code handle}
|
||||
* method of a {@code CallbackHandler} to display information messages,
|
||||
* warning messages and error messages.
|
||||
*
|
||||
* @see javax.security.auth.callback.CallbackHandler
|
||||
*/
|
||||
public class TextOutputCallback implements Callback, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1689502495511663102L;
|
||||
|
||||
/** 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;
|
||||
|
||||
/**
|
||||
* Construct a TextOutputCallback with a message type and message
|
||||
* to be displayed.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param messageType the message type ({@code INFORMATION},
|
||||
* {@code WARNING} or {@code ERROR}). <p>
|
||||
*
|
||||
* @param message the message to be displayed. <p>
|
||||
*
|
||||
* @exception IllegalArgumentException if {@code messageType}
|
||||
* is not either {@code INFORMATION},
|
||||
* {@code WARNING} or {@code ERROR},
|
||||
* if {@code message} is null,
|
||||
* or if {@code message} has a length of 0.
|
||||
*/
|
||||
public TextOutputCallback(int messageType, String message) {
|
||||
if ((messageType != INFORMATION &&
|
||||
messageType != WARNING && messageType != ERROR) ||
|
||||
message == null || message.length() == 0)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.messageType = messageType;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message type.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the message type ({@code INFORMATION},
|
||||
* {@code WARNING} or {@code ERROR}).
|
||||
*/
|
||||
public int getMessageType() {
|
||||
return messageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message to be displayed.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the message to be displayed.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.callback;
|
||||
|
||||
/**
|
||||
* Signals that a {@code CallbackHandler} does not
|
||||
* recognize a particular {@code Callback}.
|
||||
*
|
||||
*/
|
||||
public class UnsupportedCallbackException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -6873556327655666839L;
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
private Callback callback;
|
||||
|
||||
/**
|
||||
* Constructs a {@code UnsupportedCallbackException}
|
||||
* with no detail message.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param callback the unrecognized {@code Callback}.
|
||||
*/
|
||||
public UnsupportedCallbackException(Callback callback) {
|
||||
super();
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a UnsupportedCallbackException with the specified detail
|
||||
* message. A detail message is a String that describes this particular
|
||||
* exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param callback the unrecognized {@code Callback}. <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public UnsupportedCallbackException(Callback callback, String msg) {
|
||||
super(msg);
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unrecognized {@code Callback}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the unrecognized {@code Callback}.
|
||||
*/
|
||||
public Callback getCallback() {
|
||||
return callback;
|
||||
}
|
||||
}
|
||||
35
jdkSrc/jdk8/javax/security/auth/callback/package-info.java
Normal file
35
jdkSrc/jdk8/javax/security/auth/callback/package-info.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This package provides the classes necessary for services
|
||||
* to interact with applications in order to retrieve
|
||||
* information (authentication data including usernames
|
||||
* or passwords, for example) or to display information
|
||||
* (error and warning messages, for example).
|
||||
*
|
||||
* @since JDK1.4
|
||||
*/
|
||||
package javax.security.auth.callback;
|
||||
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.kerberos;
|
||||
|
||||
import java.util.*;
|
||||
import java.security.Permission;
|
||||
import java.security.BasicPermission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.io.ObjectStreamField;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class is used to restrict the usage of the Kerberos
|
||||
* delegation model, ie: forwardable and proxiable tickets.
|
||||
* <p>
|
||||
* The target name of this {@code Permission} specifies a pair of
|
||||
* kerberos service principals. The first is the subordinate service principal
|
||||
* being entrusted to use the TGT. The second service principal designates
|
||||
* the target service the subordinate service principal is to
|
||||
* interact with on behalf of the initiating KerberosPrincipal. This
|
||||
* latter service principal is specified to restrict the use of a
|
||||
* proxiable ticket.
|
||||
* <p>
|
||||
* For example, to specify the "host" service use of a forwardable TGT the
|
||||
* target permission is specified as follows:
|
||||
*
|
||||
* <pre>
|
||||
* DelegationPermission("\"host/foo.example.com@EXAMPLE.COM\" \"krbtgt/EXAMPLE.COM@EXAMPLE.COM\"");
|
||||
* </pre>
|
||||
* <p>
|
||||
* To give the "backup" service a proxiable nfs service ticket the target permission
|
||||
* might be specified:
|
||||
*
|
||||
* <pre>
|
||||
* DelegationPermission("\"backup/bar.example.com@EXAMPLE.COM\" \"nfs/home.EXAMPLE.COM@EXAMPLE.COM\"");
|
||||
* </pre>
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public final class DelegationPermission extends BasicPermission
|
||||
implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 883133252142523922L;
|
||||
|
||||
private transient String subordinate, service;
|
||||
|
||||
/**
|
||||
* Create a new {@code DelegationPermission}
|
||||
* with the specified subordinate and target principals.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param principals the name of the subordinate and target principals
|
||||
*
|
||||
* @throws NullPointerException if {@code principals} is {@code null}.
|
||||
* @throws IllegalArgumentException if {@code principals} is empty.
|
||||
*/
|
||||
public DelegationPermission(String principals) {
|
||||
super(principals);
|
||||
init(principals);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code DelegationPermission}
|
||||
* with the specified subordinate and target principals.
|
||||
* <p>
|
||||
*
|
||||
* @param principals the name of the subordinate and target principals
|
||||
* <p>
|
||||
* @param actions should be null.
|
||||
*
|
||||
* @throws NullPointerException if {@code principals} is {@code null}.
|
||||
* @throws IllegalArgumentException if {@code principals} is empty.
|
||||
*/
|
||||
public DelegationPermission(String principals, String actions) {
|
||||
super(principals, actions);
|
||||
init(principals);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the DelegationPermission object.
|
||||
*/
|
||||
private void init(String target) {
|
||||
|
||||
StringTokenizer t = null;
|
||||
if (!target.startsWith("\"")) {
|
||||
throw new IllegalArgumentException
|
||||
("service principal [" + target +
|
||||
"] syntax invalid: " +
|
||||
"improperly quoted");
|
||||
} else {
|
||||
t = new StringTokenizer(target, "\"", false);
|
||||
subordinate = t.nextToken();
|
||||
if (t.countTokens() == 2) {
|
||||
t.nextToken(); // bypass whitespace
|
||||
service = t.nextToken();
|
||||
} else if (t.countTokens() > 0) {
|
||||
throw new IllegalArgumentException
|
||||
("service principal [" + t.nextToken() +
|
||||
"] syntax invalid: " +
|
||||
"improperly quoted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this Kerberos delegation permission object "implies" the
|
||||
* specified permission.
|
||||
* <P>
|
||||
* If none of the above are true, {@code implies} returns false.
|
||||
* @param p the permission to check against.
|
||||
*
|
||||
* @return true if the specified permission is implied by this object,
|
||||
* false if not.
|
||||
*/
|
||||
public boolean implies(Permission p) {
|
||||
if (!(p instanceof DelegationPermission))
|
||||
return false;
|
||||
|
||||
DelegationPermission that = (DelegationPermission) p;
|
||||
if (this.subordinate.equals(that.subordinate) &&
|
||||
this.service.equals(that.service))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks two DelegationPermission objects for equality.
|
||||
* <P>
|
||||
* @param obj the object to test for equality with this object.
|
||||
*
|
||||
* @return true if <i>obj</i> is a DelegationPermission, and
|
||||
* has the same subordinate and service principal as this.
|
||||
* DelegationPermission object.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
if (! (obj instanceof DelegationPermission))
|
||||
return false;
|
||||
|
||||
DelegationPermission that = (DelegationPermission) obj;
|
||||
return implies(that);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this object.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return getName().hashCode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a PermissionCollection object for storing
|
||||
* DelegationPermission objects.
|
||||
* <br>
|
||||
* DelegationPermission objects must be stored in a manner that
|
||||
* allows them to be inserted into the collection in any order, but
|
||||
* that also enables the PermissionCollection implies method to
|
||||
* be implemented in an efficient (and consistent) manner.
|
||||
*
|
||||
* @return a new PermissionCollection object suitable for storing
|
||||
* DelegationPermissions.
|
||||
*/
|
||||
|
||||
public PermissionCollection newPermissionCollection() {
|
||||
return new KrbDelegationPermissionCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* WriteObject is called to save the state of the DelegationPermission
|
||||
* to a stream. The actions are serialized, and the superclass
|
||||
* takes care of the name.
|
||||
*/
|
||||
private synchronized void writeObject(java.io.ObjectOutputStream s)
|
||||
throws IOException
|
||||
{
|
||||
s.defaultWriteObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the
|
||||
* DelegationPermission from a stream.
|
||||
*/
|
||||
private synchronized void readObject(java.io.ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
// Read in the action, then initialize the rest
|
||||
s.defaultReadObject();
|
||||
init(getName());
|
||||
}
|
||||
|
||||
/*
|
||||
public static void main(String args[]) throws Exception {
|
||||
DelegationPermission this_ =
|
||||
new DelegationPermission(args[0]);
|
||||
DelegationPermission that_ =
|
||||
new DelegationPermission(args[1]);
|
||||
System.out.println("-----\n");
|
||||
System.out.println("this.implies(that) = " + this_.implies(that_));
|
||||
System.out.println("-----\n");
|
||||
System.out.println("this = "+this_);
|
||||
System.out.println("-----\n");
|
||||
System.out.println("that = "+that_);
|
||||
System.out.println("-----\n");
|
||||
|
||||
KrbDelegationPermissionCollection nps =
|
||||
new KrbDelegationPermissionCollection();
|
||||
nps.add(this_);
|
||||
nps.add(new DelegationPermission("\"host/foo.example.com@EXAMPLE.COM\" \"CN=Gary Ellison/OU=JSN/O=SUNW/L=Palo Alto/ST=CA/C=US\""));
|
||||
try {
|
||||
nps.add(new DelegationPermission("host/foo.example.com@EXAMPLE.COM \"CN=Gary Ellison/OU=JSN/O=SUNW/L=Palo Alto/ST=CA/C=US\""));
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
|
||||
System.out.println("nps.implies(that) = " + nps.implies(that_));
|
||||
System.out.println("-----\n");
|
||||
|
||||
Enumeration e = nps.elements();
|
||||
|
||||
while (e.hasMoreElements()) {
|
||||
DelegationPermission x =
|
||||
(DelegationPermission) e.nextElement();
|
||||
System.out.println("nps.e = " + x);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
final class KrbDelegationPermissionCollection extends PermissionCollection
|
||||
implements java.io.Serializable {
|
||||
|
||||
// Not serialized; see serialization section at end of class.
|
||||
private transient List<Permission> perms;
|
||||
|
||||
public KrbDelegationPermissionCollection() {
|
||||
perms = new ArrayList<Permission>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check and see if this collection of permissions implies the permissions
|
||||
* expressed in "permission".
|
||||
*
|
||||
* @param permission the Permission object to compare
|
||||
*
|
||||
* @return true if "permission" is a proper subset of a permission in
|
||||
* the collection, false if not.
|
||||
*/
|
||||
public boolean implies(Permission permission) {
|
||||
if (! (permission instanceof DelegationPermission))
|
||||
return false;
|
||||
|
||||
synchronized (this) {
|
||||
for (Permission x : perms) {
|
||||
if (x.implies(permission))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a permission to the DelegationPermissions. The key for
|
||||
* the hash is the name.
|
||||
*
|
||||
* @param permission the Permission object to add.
|
||||
*
|
||||
* @exception IllegalArgumentException - if the permission is not a
|
||||
* DelegationPermission
|
||||
*
|
||||
* @exception SecurityException - if this PermissionCollection object
|
||||
* has been marked readonly
|
||||
*/
|
||||
public void add(Permission permission) {
|
||||
if (! (permission instanceof DelegationPermission))
|
||||
throw new IllegalArgumentException("invalid permission: "+
|
||||
permission);
|
||||
if (isReadOnly())
|
||||
throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
|
||||
|
||||
synchronized (this) {
|
||||
perms.add(0, permission);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an enumeration of all the DelegationPermission objects
|
||||
* in the container.
|
||||
*
|
||||
* @return an enumeration of all the DelegationPermission objects.
|
||||
*/
|
||||
public Enumeration<Permission> elements() {
|
||||
// Convert Iterator into Enumeration
|
||||
synchronized (this) {
|
||||
return Collections.enumeration(perms);
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -3383936936589966948L;
|
||||
|
||||
// Need to maintain serialization interoperability with earlier releases,
|
||||
// which had the serializable field:
|
||||
// private Vector permissions;
|
||||
/**
|
||||
* @serialField permissions java.util.Vector
|
||||
* A list of DelegationPermission objects.
|
||||
*/
|
||||
private static final ObjectStreamField[] serialPersistentFields = {
|
||||
new ObjectStreamField("permissions", Vector.class),
|
||||
};
|
||||
|
||||
/**
|
||||
* @serialData "permissions" field (a Vector containing the DelegationPermissions).
|
||||
*/
|
||||
/*
|
||||
* Writes the contents of the perms field out as a Vector for
|
||||
* serialization compatibility with earlier releases.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
// Don't call out.defaultWriteObject()
|
||||
|
||||
// Write out Vector
|
||||
Vector<Permission> permissions = new Vector<>(perms.size());
|
||||
|
||||
synchronized (this) {
|
||||
permissions.addAll(perms);
|
||||
}
|
||||
|
||||
ObjectOutputStream.PutField pfields = out.putFields();
|
||||
pfields.put("permissions", permissions);
|
||||
out.writeFields();
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads in a Vector of DelegationPermissions and saves them in the perms field.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void readObject(ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
// Don't call defaultReadObject()
|
||||
|
||||
// Read in serialized fields
|
||||
ObjectInputStream.GetField gfields = in.readFields();
|
||||
|
||||
// Get the one we want
|
||||
Vector<Permission> permissions =
|
||||
(Vector<Permission>)gfields.get("permissions", null);
|
||||
perms = new ArrayList<Permission>(permissions.size());
|
||||
perms.addAll(permissions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.kerberos;
|
||||
|
||||
import sun.security.krb5.JavaxSecurityAuthKerberosAccess;
|
||||
|
||||
class JavaxSecurityAuthKerberosAccessImpl
|
||||
implements JavaxSecurityAuthKerberosAccess {
|
||||
public sun.security.krb5.internal.ktab.KeyTab keyTabTakeSnapshot(
|
||||
KeyTab ktab) {
|
||||
return ktab.takeSnapshot();
|
||||
}
|
||||
|
||||
public KerberosPrincipal kerberosTicketGetClientAlias(KerberosTicket t) {
|
||||
return t.clientAlias;
|
||||
}
|
||||
|
||||
public void kerberosTicketSetClientAlias(KerberosTicket t, KerberosPrincipal a) {
|
||||
t.clientAlias = a;
|
||||
}
|
||||
|
||||
public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t) {
|
||||
return t.serverAlias;
|
||||
}
|
||||
|
||||
public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a) {
|
||||
t.serverAlias = a;
|
||||
}
|
||||
public KerberosTicket kerberosTicketGetProxy(KerberosTicket t) {
|
||||
return t.proxy;
|
||||
}
|
||||
public void kerberosTicketSetProxy(KerberosTicket t, KerberosTicket p) {
|
||||
t.proxy = p;
|
||||
}
|
||||
}
|
||||
304
jdkSrc/jdk8/javax/security/auth/kerberos/KerberosKey.java
Normal file
304
jdkSrc/jdk8/javax/security/auth/kerberos/KerberosKey.java
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.kerberos;
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.security.auth.Destroyable;
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
|
||||
/**
|
||||
* This class encapsulates a long term secret key for a Kerberos
|
||||
* principal.<p>
|
||||
*
|
||||
* All Kerberos JAAS login modules that obtain a principal's password and
|
||||
* generate the secret key from it should use this class.
|
||||
* Sometimes, such as when authenticating a server in
|
||||
* the absence of user-to-user authentication, the login module will store
|
||||
* an instance of this class in the private credential set of a
|
||||
* {@link javax.security.auth.Subject Subject} during the commit phase of the
|
||||
* authentication process.<p>
|
||||
*
|
||||
* A Kerberos service using a keytab to read secret keys should use
|
||||
* the {@link KeyTab} class, where latest keys can be read when needed.<p>
|
||||
*
|
||||
* It might be necessary for the application to be granted a
|
||||
* {@link javax.security.auth.PrivateCredentialPermission
|
||||
* PrivateCredentialPermission} if it needs to access the KerberosKey
|
||||
* instance from a Subject. This permission is not needed when the
|
||||
* application depends on the default JGSS Kerberos mechanism to access the
|
||||
* KerberosKey. In that case, however, the application will need an
|
||||
* appropriate
|
||||
* {@link javax.security.auth.kerberos.ServicePermission ServicePermission}.
|
||||
*
|
||||
* @author Mayank Upadhyay
|
||||
* @since 1.4
|
||||
*/
|
||||
public class KerberosKey implements SecretKey, Destroyable {
|
||||
|
||||
private static final long serialVersionUID = -4625402278148246993L;
|
||||
|
||||
/**
|
||||
* The principal that this secret key belongs to.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private KerberosPrincipal principal;
|
||||
|
||||
/**
|
||||
* the version number of this secret key
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private int versionNum;
|
||||
|
||||
/**
|
||||
* {@code KeyImpl} is serialized by writing out the ASN1 Encoded bytes
|
||||
* of the encryption key.
|
||||
* The ASN1 encoding is defined in RFC4120 and as follows:
|
||||
* <pre>
|
||||
* EncryptionKey ::= SEQUENCE {
|
||||
* keytype [0] Int32 -- actually encryption type --,
|
||||
* keyvalue [1] OCTET STRING
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private KeyImpl key;
|
||||
private transient boolean destroyed = false;
|
||||
|
||||
/**
|
||||
* Constructs a KerberosKey from the given bytes when the key type and
|
||||
* key version number are known. This can be used when reading the secret
|
||||
* key information from a Kerberos "keytab".
|
||||
*
|
||||
* @param principal the principal that this secret key belongs to
|
||||
* @param keyBytes the raw bytes for the secret key
|
||||
* @param keyType the key type for the secret key as defined by the
|
||||
* Kerberos protocol specification.
|
||||
* @param versionNum the version number of this secret key
|
||||
*/
|
||||
public KerberosKey(KerberosPrincipal principal,
|
||||
byte[] keyBytes,
|
||||
int keyType,
|
||||
int versionNum) {
|
||||
this.principal = principal;
|
||||
this.versionNum = versionNum;
|
||||
key = new KeyImpl(keyBytes, keyType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a KerberosKey from a principal's password.
|
||||
*
|
||||
* @param principal the principal that this password belongs to
|
||||
* @param password the password that should be used to compute the key
|
||||
* @param algorithm the name for the algorithm that this key will be
|
||||
* used for. This parameter may be null in which case the default
|
||||
* algorithm "DES" will be assumed.
|
||||
* @throws IllegalArgumentException if the name of the
|
||||
* algorithm passed is unsupported.
|
||||
*/
|
||||
public KerberosKey(KerberosPrincipal principal,
|
||||
char[] password,
|
||||
String algorithm) {
|
||||
|
||||
this.principal = principal;
|
||||
// Pass principal in for salt
|
||||
key = new KeyImpl(principal, password, algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the principal that this key belongs to.
|
||||
*
|
||||
* @return the principal this key belongs to.
|
||||
*/
|
||||
public final KerberosPrincipal getPrincipal() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This key is no longer valid");
|
||||
return principal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key version number.
|
||||
*
|
||||
* @return the key version number.
|
||||
*/
|
||||
public final int getVersionNumber() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This key is no longer valid");
|
||||
return versionNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key type for this long-term key.
|
||||
*
|
||||
* @return the key type.
|
||||
*/
|
||||
public final int getKeyType() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This key is no longer valid");
|
||||
return key.getKeyType();
|
||||
}
|
||||
|
||||
/*
|
||||
* Methods from java.security.Key
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the standard algorithm name for this key. For
|
||||
* example, "DES" would indicate that this key is a DES key.
|
||||
* See Appendix A in the <a href=
|
||||
* "../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture API Specification & Reference
|
||||
* </a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @return the name of the algorithm associated with this key.
|
||||
*/
|
||||
public final String getAlgorithm() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This key is no longer valid");
|
||||
return key.getAlgorithm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the encoding format for this secret key.
|
||||
*
|
||||
* @return the String "RAW"
|
||||
*/
|
||||
public final String getFormat() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This key is no longer valid");
|
||||
return key.getFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key material of this secret key.
|
||||
*
|
||||
* @return the key material
|
||||
*/
|
||||
public final byte[] getEncoded() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This key is no longer valid");
|
||||
return key.getEncoded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys this key. A call to any of its other methods after this
|
||||
* will cause an IllegalStateException to be thrown.
|
||||
*
|
||||
* @throws DestroyFailedException if some error occurs while destorying
|
||||
* this key.
|
||||
*/
|
||||
public void destroy() throws DestroyFailedException {
|
||||
if (!destroyed) {
|
||||
key.destroy();
|
||||
principal = null;
|
||||
destroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Determines if this key has been destroyed.*/
|
||||
public boolean isDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (destroyed) {
|
||||
return "Destroyed Principal";
|
||||
}
|
||||
return "KerberosKey: principal " + principal +
|
||||
", version " + versionNum +
|
||||
", key " + key.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this KerberosKey.
|
||||
*
|
||||
* @return a hashCode() for the {@code KerberosKey}
|
||||
* @since 1.6
|
||||
*/
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (isDestroyed()) {
|
||||
return result;
|
||||
}
|
||||
result = 37 * result + Arrays.hashCode(getEncoded());
|
||||
result = 37 * result + getKeyType();
|
||||
if (principal != null) {
|
||||
result = 37 * result + principal.hashCode();
|
||||
}
|
||||
return result * 37 + versionNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified Object with this KerberosKey for equality.
|
||||
* Returns true if the given object is also a
|
||||
* {@code KerberosKey} and the two
|
||||
* {@code KerberosKey} instances are equivalent.
|
||||
*
|
||||
* @param other the Object to compare to
|
||||
* @return true if the specified object is equal to this KerberosKey,
|
||||
* false otherwise. NOTE: Returns false if either of the KerberosKey
|
||||
* objects has been destroyed.
|
||||
* @since 1.6
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
|
||||
if (other == this)
|
||||
return true;
|
||||
|
||||
if (! (other instanceof KerberosKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KerberosKey otherKey = ((KerberosKey) other);
|
||||
if (isDestroyed() || otherKey.isDestroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (versionNum != otherKey.getVersionNumber() ||
|
||||
getKeyType() != otherKey.getKeyType() ||
|
||||
!Arrays.equals(getEncoded(), otherKey.getEncoded())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (principal == null) {
|
||||
if (otherKey.getPrincipal() != null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!principal.equals(otherKey.getPrincipal())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
293
jdkSrc/jdk8/javax/security/auth/kerberos/KerberosPrincipal.java
Normal file
293
jdkSrc/jdk8/javax/security/auth/kerberos/KerberosPrincipal.java
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.kerberos;
|
||||
|
||||
import java.io.*;
|
||||
import sun.security.krb5.KrbException;
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.Realm;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class encapsulates a Kerberos principal.
|
||||
*
|
||||
* @author Mayank Upadhyay
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public final class KerberosPrincipal
|
||||
implements java.security.Principal, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7374788026156829911L;
|
||||
|
||||
//name types
|
||||
|
||||
/**
|
||||
* unknown name type.
|
||||
*/
|
||||
|
||||
public static final int KRB_NT_UNKNOWN = 0;
|
||||
|
||||
/**
|
||||
* user principal name type.
|
||||
*/
|
||||
|
||||
public static final int KRB_NT_PRINCIPAL = 1;
|
||||
|
||||
/**
|
||||
* service and other unique instance (krbtgt) name type.
|
||||
*/
|
||||
public static final int KRB_NT_SRV_INST = 2;
|
||||
|
||||
/**
|
||||
* service with host name as instance (telnet, rcommands) name type.
|
||||
*/
|
||||
|
||||
public static final int KRB_NT_SRV_HST = 3;
|
||||
|
||||
/**
|
||||
* service with host as remaining components name type.
|
||||
*/
|
||||
|
||||
public static final int KRB_NT_SRV_XHST = 4;
|
||||
|
||||
/**
|
||||
* unique ID name type.
|
||||
*/
|
||||
|
||||
public static final int KRB_NT_UID = 5;
|
||||
|
||||
/**
|
||||
* Enterprise name (alias)
|
||||
*/
|
||||
static final int KRB_NT_ENTERPRISE = 10;
|
||||
|
||||
private transient String fullName;
|
||||
|
||||
private transient String realm;
|
||||
|
||||
private transient int nameType;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a KerberosPrincipal from the provided string input. The
|
||||
* name type for this principal defaults to
|
||||
* {@link #KRB_NT_PRINCIPAL KRB_NT_PRINCIPAL}
|
||||
* This string is assumed to contain a name in the format
|
||||
* that is specified in Section 2.1.1. (Kerberos Principal Name Form) of
|
||||
* <a href=http://www.ietf.org/rfc/rfc1964.txt> RFC 1964 </a>
|
||||
* (for example, <i>duke@FOO.COM</i>, where <i>duke</i>
|
||||
* represents a principal, and <i>FOO.COM</i> represents a realm).
|
||||
*
|
||||
* <p>If the input name does not contain a realm, the default realm
|
||||
* is used. The default realm can be specified either in a Kerberos
|
||||
* configuration file or via the java.security.krb5.realm
|
||||
* system property. For more information,
|
||||
* <a href="../../../../../technotes/guides/security/jgss/tutorials/index.html">
|
||||
* Kerberos Requirements </a>
|
||||
*
|
||||
* @param name the principal name
|
||||
* @throws IllegalArgumentException if name is improperly
|
||||
* formatted, if name is null, or if name does not contain
|
||||
* the realm to use and the default realm is not specified
|
||||
* in either a Kerberos configuration file or via the
|
||||
* java.security.krb5.realm system property.
|
||||
*/
|
||||
public KerberosPrincipal(String name) {
|
||||
this(name, KRB_NT_PRINCIPAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a KerberosPrincipal from the provided string and
|
||||
* name type input. The string is assumed to contain a name in the
|
||||
* format that is specified in Section 2.1 (Mandatory Name Forms) of
|
||||
* <a href=http://www.ietf.org/rfc/rfc1964.txt>RFC 1964</a>.
|
||||
* Valid name types are specified in Section 6.2 (Principal Names) of
|
||||
* <a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>.
|
||||
* The input name must be consistent with the provided name type.
|
||||
* (for example, <i>duke@FOO.COM</i>, is a valid input string for the
|
||||
* name type, KRB_NT_PRINCIPAL where <i>duke</i>
|
||||
* represents a principal, and <i>FOO.COM</i> represents a realm).
|
||||
|
||||
* <p> If the input name does not contain a realm, the default realm
|
||||
* is used. The default realm can be specified either in a Kerberos
|
||||
* configuration file or via the java.security.krb5.realm
|
||||
* system property. For more information, see
|
||||
* <a href="../../../../../technotes/guides/security/jgss/tutorials/index.html">
|
||||
* Kerberos Requirements</a>.
|
||||
*
|
||||
* @param name the principal name
|
||||
* @param nameType the name type of the principal
|
||||
* @throws IllegalArgumentException if name is improperly
|
||||
* formatted, if name is null, if the nameType is not supported,
|
||||
* or if name does not contain the realm to use and the default
|
||||
* realm is not specified in either a Kerberos configuration
|
||||
* file or via the java.security.krb5.realm system property.
|
||||
*/
|
||||
|
||||
public KerberosPrincipal(String name, int nameType) {
|
||||
|
||||
PrincipalName krb5Principal = null;
|
||||
|
||||
try {
|
||||
// Appends the default realm if it is missing
|
||||
krb5Principal = new PrincipalName(name,nameType);
|
||||
} catch (KrbException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
|
||||
// A ServicePermission with a principal in the deduced realm and
|
||||
// any action must be granted if no realm is provided by caller.
|
||||
if (krb5Principal.isRealmDeduced() && !Realm.AUTODEDUCEREALM) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
try {
|
||||
sm.checkPermission(new ServicePermission(
|
||||
"@" + krb5Principal.getRealmAsString(), "-"));
|
||||
} catch (SecurityException se) {
|
||||
// Swallow the actual exception to hide info
|
||||
throw new SecurityException("Cannot read realm info");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.nameType = nameType;
|
||||
fullName = krb5Principal.toString();
|
||||
realm = krb5Principal.getRealmString();
|
||||
}
|
||||
/**
|
||||
* Returns the realm component of this Kerberos principal.
|
||||
*
|
||||
* @return the realm component of this Kerberos principal.
|
||||
*/
|
||||
public String getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this principal. The hash code is defined to
|
||||
* be the result of the following calculation:
|
||||
* <pre>{@code
|
||||
* hashCode = getName().hashCode();
|
||||
* }</pre>
|
||||
*
|
||||
* @return a hashCode() for the {@code KerberosPrincipal}
|
||||
*/
|
||||
public int hashCode() {
|
||||
return getName().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified Object with this Principal for equality.
|
||||
* Returns true if the given object is also a
|
||||
* {@code KerberosPrincipal} and the two
|
||||
* {@code KerberosPrincipal} instances are equivalent.
|
||||
* More formally two {@code KerberosPrincipal} instances are equal
|
||||
* if the values returned by {@code getName()} are equal.
|
||||
*
|
||||
* @param other the Object to compare to
|
||||
* @return true if the Object passed in represents the same principal
|
||||
* as this one, false otherwise.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
|
||||
if (other == this)
|
||||
return true;
|
||||
|
||||
if (! (other instanceof KerberosPrincipal)) {
|
||||
return false;
|
||||
}
|
||||
String myFullName = getName();
|
||||
String otherFullName = ((KerberosPrincipal) other).getName();
|
||||
return myFullName.equals(otherFullName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the KerberosPrincipal object to a stream
|
||||
*
|
||||
* @serialData this {@code KerberosPrincipal} is serialized
|
||||
* by writing out the PrincipalName and the
|
||||
* realm in their DER-encoded form as specified in Section 5.2.2 of
|
||||
* <a href=http://www.ietf.org/rfc/rfc4120.txt> RFC4120</a>.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream oos)
|
||||
throws IOException {
|
||||
|
||||
PrincipalName krb5Principal;
|
||||
try {
|
||||
krb5Principal = new PrincipalName(fullName, nameType);
|
||||
oos.writeObject(krb5Principal.asn1Encode());
|
||||
oos.writeObject(krb5Principal.getRealm().asn1Encode());
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this object from a stream (i.e., deserializes it)
|
||||
*/
|
||||
private void readObject(ObjectInputStream ois)
|
||||
throws IOException, ClassNotFoundException {
|
||||
byte[] asn1EncPrincipal = (byte [])ois.readObject();
|
||||
byte[] encRealm = (byte [])ois.readObject();
|
||||
try {
|
||||
Realm realmObject = new Realm(new DerValue(encRealm));
|
||||
PrincipalName krb5Principal = new PrincipalName(
|
||||
new DerValue(asn1EncPrincipal), realmObject);
|
||||
realm = realmObject.toString();
|
||||
fullName = krb5Principal.toString();
|
||||
nameType = krb5Principal.getNameType();
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The returned string corresponds to the single-string
|
||||
* representation of a Kerberos Principal name as specified in
|
||||
* Section 2.1 of <a href=http://www.ietf.org/rfc/rfc1964.txt>RFC 1964</a>.
|
||||
*
|
||||
* @return the principal name.
|
||||
*/
|
||||
public String getName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name type of the KerberosPrincipal. Valid name types
|
||||
* are specified in Section 6.2 of
|
||||
* <a href=http://www.ietf.org/rfc/rfc4120.txt> RFC4120</a>.
|
||||
*
|
||||
* @return the name type.
|
||||
*/
|
||||
public int getNameType() {
|
||||
return nameType;
|
||||
}
|
||||
|
||||
// Inherits javadocs from Object
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
810
jdkSrc/jdk8/javax/security/auth/kerberos/KerberosTicket.java
Normal file
810
jdkSrc/jdk8/javax/security/auth/kerberos/KerberosTicket.java
Normal file
@@ -0,0 +1,810 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.kerberos;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Date;
|
||||
import java.util.Arrays;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Objects;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.security.auth.Refreshable;
|
||||
import javax.security.auth.Destroyable;
|
||||
import javax.security.auth.RefreshFailedException;
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
|
||||
import sun.misc.HexDumpEncoder;
|
||||
import sun.security.krb5.EncryptionKey;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class encapsulates a Kerberos ticket and associated
|
||||
* information as viewed from the client's point of view. It captures all
|
||||
* information that the Key Distribution Center (KDC) sends to the client
|
||||
* in the reply message KDC-REP defined in the Kerberos Protocol
|
||||
* Specification (<a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>).
|
||||
* <p>
|
||||
* All Kerberos JAAS login modules that authenticate a user to a KDC should
|
||||
* use this class. Where available, the login module might even read this
|
||||
* information from a ticket cache in the operating system instead of
|
||||
* directly communicating with the KDC. During the commit phase of the JAAS
|
||||
* authentication process, the JAAS login module should instantiate this
|
||||
* class and store the instance in the private credential set of a
|
||||
* {@link javax.security.auth.Subject Subject}.<p>
|
||||
*
|
||||
* It might be necessary for the application to be granted a
|
||||
* {@link javax.security.auth.PrivateCredentialPermission
|
||||
* PrivateCredentialPermission} if it needs to access a KerberosTicket
|
||||
* instance from a Subject. This permission is not needed when the
|
||||
* application depends on the default JGSS Kerberos mechanism to access the
|
||||
* KerberosTicket. In that case, however, the application will need an
|
||||
* appropriate
|
||||
* {@link javax.security.auth.kerberos.ServicePermission ServicePermission}.
|
||||
* <p>
|
||||
* Note that this class is applicable to both ticket granting tickets and
|
||||
* other regular service tickets. A ticket granting ticket is just a
|
||||
* special case of a more generalized service ticket.
|
||||
*
|
||||
* @see javax.security.auth.Subject
|
||||
* @see javax.security.auth.PrivateCredentialPermission
|
||||
* @see javax.security.auth.login.LoginContext
|
||||
* @see org.ietf.jgss.GSSCredential
|
||||
* @see org.ietf.jgss.GSSManager
|
||||
*
|
||||
* @author Mayank Upadhyay
|
||||
* @since 1.4
|
||||
*/
|
||||
public class KerberosTicket implements Destroyable, Refreshable,
|
||||
java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7395334370157380539L;
|
||||
|
||||
// XXX Make these flag indices public
|
||||
private static final int FORWARDABLE_TICKET_FLAG = 1;
|
||||
private static final int FORWARDED_TICKET_FLAG = 2;
|
||||
private static final int PROXIABLE_TICKET_FLAG = 3;
|
||||
private static final int PROXY_TICKET_FLAG = 4;
|
||||
private static final int POSTDATED_TICKET_FLAG = 6;
|
||||
private static final int RENEWABLE_TICKET_FLAG = 8;
|
||||
private static final int INITIAL_TICKET_FLAG = 9;
|
||||
|
||||
private static final int NUM_FLAGS = 32;
|
||||
|
||||
/**
|
||||
*
|
||||
* ASN.1 DER Encoding of the Ticket as defined in the
|
||||
* Kerberos Protocol Specification RFC4120.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private byte[] asn1Encoding;
|
||||
|
||||
/**
|
||||
*{@code KeyImpl} is serialized by writing out the ASN1 Encoded bytes
|
||||
* of the encryption key. The ASN1 encoding is defined in RFC4120 and as
|
||||
* follows:
|
||||
* <pre>
|
||||
* EncryptionKey ::= SEQUENCE {
|
||||
* keytype [0] Int32 -- actually encryption type --,
|
||||
* keyvalue [1] OCTET STRING
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private KeyImpl sessionKey;
|
||||
|
||||
/**
|
||||
*
|
||||
* Ticket Flags as defined in the Kerberos Protocol Specification RFC4120.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private boolean[] flags;
|
||||
|
||||
/**
|
||||
*
|
||||
* Time of initial authentication
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private Date authTime;
|
||||
|
||||
/**
|
||||
*
|
||||
* Time after which the ticket is valid.
|
||||
* @serial
|
||||
*/
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
*
|
||||
* Time after which the ticket will not be honored. (its expiration time).
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
*
|
||||
* For renewable Tickets it indicates the maximum endtime that may be
|
||||
* included in a renewal. It can be thought of as the absolute expiration
|
||||
* time for the ticket, including all renewals. This field may be null
|
||||
* for tickets that are not renewable.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private Date renewTill;
|
||||
|
||||
/**
|
||||
*
|
||||
* Client that owns the service ticket
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private KerberosPrincipal client;
|
||||
|
||||
/**
|
||||
*
|
||||
* The service for which the ticket was issued.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private KerberosPrincipal server;
|
||||
|
||||
/**
|
||||
*
|
||||
* The addresses from where the ticket may be used by the client.
|
||||
* This field may be null when the ticket is usable from any address.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private InetAddress[] clientAddresses;
|
||||
|
||||
transient KerberosPrincipal clientAlias = null;
|
||||
|
||||
transient KerberosPrincipal serverAlias = null;
|
||||
|
||||
/**
|
||||
* Evidence ticket if proxy_impersonator. This field can be accessed
|
||||
* by KerberosSecrets. It's serialized.
|
||||
*/
|
||||
KerberosTicket proxy = null;
|
||||
|
||||
private transient boolean destroyed = false;
|
||||
|
||||
/**
|
||||
* Constructs a KerberosTicket using credentials information that a
|
||||
* client either receives from a KDC or reads from a cache.
|
||||
*
|
||||
* @param asn1Encoding the ASN.1 encoding of the ticket as defined by
|
||||
* the Kerberos protocol specification.
|
||||
* @param client the client that owns this service
|
||||
* ticket
|
||||
* @param server the service that this ticket is for
|
||||
* @param sessionKey the raw bytes for the session key that must be
|
||||
* used to encrypt the authenticator that will be sent to the server
|
||||
* @param keyType the key type for the session key as defined by the
|
||||
* Kerberos protocol specification.
|
||||
* @param flags the ticket flags. Each element in this array indicates
|
||||
* the value for the corresponding bit in the ASN.1 BitString that
|
||||
* represents the ticket flags. If the number of elements in this array
|
||||
* is less than the number of flags used by the Kerberos protocol,
|
||||
* then the missing flags will be filled in with false.
|
||||
* @param authTime the time of initial authentication for the client
|
||||
* @param startTime the time after which the ticket will be valid. This
|
||||
* may be null in which case the value of authTime is treated as the
|
||||
* startTime.
|
||||
* @param endTime the time after which the ticket will no longer be
|
||||
* valid
|
||||
* @param renewTill an absolute expiration time for the ticket,
|
||||
* including all renewal that might be possible. This field may be null
|
||||
* for tickets that are not renewable.
|
||||
* @param clientAddresses the addresses from where the ticket may be
|
||||
* used by the client. This field may be null when the ticket is usable
|
||||
* from any address.
|
||||
*/
|
||||
public KerberosTicket(byte[] asn1Encoding,
|
||||
KerberosPrincipal client,
|
||||
KerberosPrincipal server,
|
||||
byte[] sessionKey,
|
||||
int keyType,
|
||||
boolean[] flags,
|
||||
Date authTime,
|
||||
Date startTime,
|
||||
Date endTime,
|
||||
Date renewTill,
|
||||
InetAddress[] clientAddresses) {
|
||||
|
||||
init(asn1Encoding, client, server, sessionKey, keyType, flags,
|
||||
authTime, startTime, endTime, renewTill, clientAddresses);
|
||||
}
|
||||
|
||||
private void init(byte[] asn1Encoding,
|
||||
KerberosPrincipal client,
|
||||
KerberosPrincipal server,
|
||||
byte[] sessionKey,
|
||||
int keyType,
|
||||
boolean[] flags,
|
||||
Date authTime,
|
||||
Date startTime,
|
||||
Date endTime,
|
||||
Date renewTill,
|
||||
InetAddress[] clientAddresses) {
|
||||
if (sessionKey == null)
|
||||
throw new IllegalArgumentException("Session key for ticket"
|
||||
+ " cannot be null");
|
||||
init(asn1Encoding, client, server,
|
||||
new KeyImpl(sessionKey, keyType), flags, authTime,
|
||||
startTime, endTime, renewTill, clientAddresses);
|
||||
}
|
||||
|
||||
private void init(byte[] asn1Encoding,
|
||||
KerberosPrincipal client,
|
||||
KerberosPrincipal server,
|
||||
KeyImpl sessionKey,
|
||||
boolean[] flags,
|
||||
Date authTime,
|
||||
Date startTime,
|
||||
Date endTime,
|
||||
Date renewTill,
|
||||
InetAddress[] clientAddresses) {
|
||||
if (asn1Encoding == null)
|
||||
throw new IllegalArgumentException("ASN.1 encoding of ticket"
|
||||
+ " cannot be null");
|
||||
this.asn1Encoding = asn1Encoding.clone();
|
||||
|
||||
if (client == null)
|
||||
throw new IllegalArgumentException("Client name in ticket"
|
||||
+ " cannot be null");
|
||||
this.client = client;
|
||||
|
||||
if (server == null)
|
||||
throw new IllegalArgumentException("Server name in ticket"
|
||||
+ " cannot be null");
|
||||
this.server = server;
|
||||
|
||||
// Caller needs to make sure `sessionKey` will not be null
|
||||
this.sessionKey = sessionKey;
|
||||
|
||||
if (flags != null) {
|
||||
if (flags.length >= NUM_FLAGS)
|
||||
this.flags = flags.clone();
|
||||
else {
|
||||
this.flags = new boolean[NUM_FLAGS];
|
||||
// Fill in whatever we have
|
||||
for (int i = 0; i < flags.length; i++)
|
||||
this.flags[i] = flags[i];
|
||||
}
|
||||
} else
|
||||
this.flags = new boolean[NUM_FLAGS];
|
||||
|
||||
if (this.flags[RENEWABLE_TICKET_FLAG] && renewTill != null) {
|
||||
this.renewTill = new Date(renewTill.getTime());
|
||||
}
|
||||
|
||||
if (authTime != null) {
|
||||
this.authTime = new Date(authTime.getTime());
|
||||
}
|
||||
if (startTime != null) {
|
||||
this.startTime = new Date(startTime.getTime());
|
||||
} else {
|
||||
this.startTime = this.authTime;
|
||||
}
|
||||
|
||||
if (endTime == null)
|
||||
throw new IllegalArgumentException("End time for ticket validity"
|
||||
+ " cannot be null");
|
||||
this.endTime = new Date(endTime.getTime());
|
||||
|
||||
if (clientAddresses != null)
|
||||
this.clientAddresses = clientAddresses.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the client principal associated with this ticket.
|
||||
*
|
||||
* @return the client principal.
|
||||
*/
|
||||
public final KerberosPrincipal getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the service principal associated with this ticket.
|
||||
*
|
||||
* @return the service principal.
|
||||
*/
|
||||
public final KerberosPrincipal getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the session key associated with this ticket.
|
||||
*
|
||||
* @return the session key.
|
||||
*/
|
||||
public final SecretKey getSessionKey() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This ticket is no longer valid");
|
||||
return sessionKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key type of the session key associated with this
|
||||
* ticket as defined by the Kerberos Protocol Specification.
|
||||
*
|
||||
* @return the key type of the session key associated with this
|
||||
* ticket.
|
||||
*
|
||||
* @see #getSessionKey()
|
||||
*/
|
||||
public final int getSessionKeyType() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This ticket is no longer valid");
|
||||
return sessionKey.getKeyType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this ticket is forwardable.
|
||||
*
|
||||
* @return true if this ticket is forwardable, false if not.
|
||||
*/
|
||||
public final boolean isForwardable() {
|
||||
return flags == null? false: flags[FORWARDABLE_TICKET_FLAG];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this ticket had been forwarded or was issued based on
|
||||
* authentication involving a forwarded ticket-granting ticket.
|
||||
*
|
||||
* @return true if this ticket had been forwarded or was issued based on
|
||||
* authentication involving a forwarded ticket-granting ticket,
|
||||
* false otherwise.
|
||||
*/
|
||||
public final boolean isForwarded() {
|
||||
return flags == null? false: flags[FORWARDED_TICKET_FLAG];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this ticket is proxiable.
|
||||
*
|
||||
* @return true if this ticket is proxiable, false if not.
|
||||
*/
|
||||
public final boolean isProxiable() {
|
||||
return flags == null? false: flags[PROXIABLE_TICKET_FLAG];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines is this ticket is a proxy-ticket.
|
||||
*
|
||||
* @return true if this ticket is a proxy-ticket, false if not.
|
||||
*/
|
||||
public final boolean isProxy() {
|
||||
return flags == null? false: flags[PROXY_TICKET_FLAG];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines is this ticket is post-dated.
|
||||
*
|
||||
* @return true if this ticket is post-dated, false if not.
|
||||
*/
|
||||
public final boolean isPostdated() {
|
||||
return flags == null? false: flags[POSTDATED_TICKET_FLAG];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines is this ticket is renewable. If so, the {@link #refresh()
|
||||
* refresh} method can be called, assuming the validity period for
|
||||
* renewing is not already over.
|
||||
*
|
||||
* @return true if this ticket is renewable, false if not.
|
||||
*/
|
||||
public final boolean isRenewable() {
|
||||
return flags == null? false: flags[RENEWABLE_TICKET_FLAG];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this ticket was issued using the Kerberos AS-Exchange
|
||||
* protocol, and not issued based on some ticket-granting ticket.
|
||||
*
|
||||
* @return true if this ticket was issued using the Kerberos AS-Exchange
|
||||
* protocol, false if not.
|
||||
*/
|
||||
public final boolean isInitial() {
|
||||
return flags == null? false: flags[INITIAL_TICKET_FLAG];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flags associated with this ticket. Each element in the
|
||||
* returned array indicates the value for the corresponding bit in the
|
||||
* ASN.1 BitString that represents the ticket flags.
|
||||
*
|
||||
* @return the flags associated with this ticket.
|
||||
*/
|
||||
public final boolean[] getFlags() {
|
||||
return (flags == null? null: flags.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time that the client was authenticated.
|
||||
*
|
||||
* @return the time that the client was authenticated
|
||||
* or null if not set.
|
||||
*/
|
||||
public final java.util.Date getAuthTime() {
|
||||
return (authTime == null) ? null : (Date)authTime.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start time for this ticket's validity period.
|
||||
*
|
||||
* @return the start time for this ticket's validity period
|
||||
* or null if not set.
|
||||
*/
|
||||
public final java.util.Date getStartTime() {
|
||||
return (startTime == null) ? null : (Date)startTime.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expiration time for this ticket's validity period.
|
||||
*
|
||||
* @return the expiration time for this ticket's validity period.
|
||||
*/
|
||||
public final java.util.Date getEndTime() {
|
||||
return (endTime == null) ? null : (Date) endTime.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the latest expiration time for this ticket, including all
|
||||
* renewals. This will return a null value for non-renewable tickets.
|
||||
*
|
||||
* @return the latest expiration time for this ticket.
|
||||
*/
|
||||
public final java.util.Date getRenewTill() {
|
||||
return (renewTill == null) ? null: (Date)renewTill.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of addresses from where the ticket can be used.
|
||||
*
|
||||
* @return ths list of addresses or null, if the field was not
|
||||
* provided.
|
||||
*/
|
||||
public final java.net.InetAddress[] getClientAddresses() {
|
||||
return (clientAddresses == null) ? null: clientAddresses.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ASN.1 encoding of the entire ticket.
|
||||
*
|
||||
* @return an ASN.1 encoding of the entire ticket.
|
||||
*/
|
||||
public final byte[] getEncoded() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This ticket is no longer valid");
|
||||
return asn1Encoding.clone();
|
||||
}
|
||||
|
||||
/** Determines if this ticket is still current. */
|
||||
public boolean isCurrent() {
|
||||
return endTime == null? false: (System.currentTimeMillis() <= endTime.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends the validity period of this ticket. The ticket will contain
|
||||
* a new session key if the refresh operation succeeds. The refresh
|
||||
* operation will fail if the ticket is not renewable or the latest
|
||||
* allowable renew time has passed. Any other error returned by the
|
||||
* KDC will also cause this method to fail.
|
||||
*
|
||||
* Note: This method is not synchronized with the the accessor
|
||||
* methods of this object. Hence callers need to be aware of multiple
|
||||
* threads that might access this and try to renew it at the same
|
||||
* time.
|
||||
*
|
||||
* @throws RefreshFailedException if the ticket is not renewable, or
|
||||
* the latest allowable renew time has passed, or the KDC returns some
|
||||
* error.
|
||||
*
|
||||
* @see #isRenewable()
|
||||
* @see #getRenewTill()
|
||||
*/
|
||||
public void refresh() throws RefreshFailedException {
|
||||
|
||||
if (destroyed)
|
||||
throw new RefreshFailedException("A destroyed ticket "
|
||||
+ "cannot be renewd.");
|
||||
|
||||
if (!isRenewable())
|
||||
throw new RefreshFailedException("This ticket is not renewable");
|
||||
|
||||
if (getRenewTill() == null) {
|
||||
// Renewable ticket without renew-till. Illegal and ignored.
|
||||
return;
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() > getRenewTill().getTime())
|
||||
throw new RefreshFailedException("This ticket is past "
|
||||
+ "its last renewal time.");
|
||||
Throwable e = null;
|
||||
sun.security.krb5.Credentials krb5Creds = null;
|
||||
|
||||
try {
|
||||
krb5Creds = new sun.security.krb5.Credentials(asn1Encoding,
|
||||
client.toString(),
|
||||
(clientAlias != null ?
|
||||
clientAlias.getName() : null),
|
||||
server.toString(),
|
||||
(serverAlias != null ?
|
||||
serverAlias.getName() : null),
|
||||
sessionKey.getEncoded(),
|
||||
sessionKey.getKeyType(),
|
||||
flags,
|
||||
authTime,
|
||||
startTime,
|
||||
endTime,
|
||||
renewTill,
|
||||
clientAddresses);
|
||||
krb5Creds = krb5Creds.renew();
|
||||
} catch (sun.security.krb5.KrbException krbException) {
|
||||
e = krbException;
|
||||
} catch (java.io.IOException ioException) {
|
||||
e = ioException;
|
||||
}
|
||||
|
||||
if (e != null) {
|
||||
RefreshFailedException rfException
|
||||
= new RefreshFailedException("Failed to renew Kerberos Ticket "
|
||||
+ "for client " + client
|
||||
+ " and server " + server
|
||||
+ " - " + e.getMessage());
|
||||
rfException.initCause(e);
|
||||
throw rfException;
|
||||
}
|
||||
|
||||
/*
|
||||
* In case multiple threads try to refresh it at the same time.
|
||||
*/
|
||||
synchronized (this) {
|
||||
try {
|
||||
this.destroy();
|
||||
} catch (DestroyFailedException dfException) {
|
||||
// Squelch it since we don't care about the old ticket.
|
||||
}
|
||||
init(krb5Creds.getEncoded(),
|
||||
new KerberosPrincipal(krb5Creds.getClient().getName()),
|
||||
new KerberosPrincipal(krb5Creds.getServer().getName(),
|
||||
KerberosPrincipal.KRB_NT_SRV_INST),
|
||||
krb5Creds.getSessionKey().getBytes(),
|
||||
krb5Creds.getSessionKey().getEType(),
|
||||
krb5Creds.getFlags(),
|
||||
krb5Creds.getAuthTime(),
|
||||
krb5Creds.getStartTime(),
|
||||
krb5Creds.getEndTime(),
|
||||
krb5Creds.getRenewTill(),
|
||||
krb5Creds.getClientAddresses());
|
||||
destroyed = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the ticket and destroys any sensitive information stored in
|
||||
* it.
|
||||
*/
|
||||
public void destroy() throws DestroyFailedException {
|
||||
if (!destroyed) {
|
||||
Arrays.fill(asn1Encoding, (byte) 0);
|
||||
client = null;
|
||||
server = null;
|
||||
sessionKey.destroy();
|
||||
flags = null;
|
||||
authTime = null;
|
||||
startTime = null;
|
||||
endTime = null;
|
||||
renewTill = null;
|
||||
clientAddresses = null;
|
||||
destroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this ticket has been destroyed.
|
||||
*/
|
||||
public boolean isDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (destroyed) {
|
||||
return "Destroyed KerberosTicket";
|
||||
}
|
||||
StringBuffer caddrBuf = new StringBuffer();
|
||||
if (clientAddresses != null) {
|
||||
for (int i = 0; i < clientAddresses.length; i++) {
|
||||
caddrBuf.append("clientAddresses[" + i + "] = " +
|
||||
clientAddresses[i].toString());
|
||||
}
|
||||
}
|
||||
return ("Ticket (hex) = " + "\n" +
|
||||
(new HexDumpEncoder()).encodeBuffer(asn1Encoding) + "\n" +
|
||||
"Client Principal = " + client.toString() + "\n" +
|
||||
"Server Principal = " + server.toString() + "\n" +
|
||||
"Session Key = " + sessionKey.toString() + "\n" +
|
||||
"Forwardable Ticket " + flags[FORWARDABLE_TICKET_FLAG] + "\n" +
|
||||
"Forwarded Ticket " + flags[FORWARDED_TICKET_FLAG] + "\n" +
|
||||
"Proxiable Ticket " + flags[PROXIABLE_TICKET_FLAG] + "\n" +
|
||||
"Proxy Ticket " + flags[PROXY_TICKET_FLAG] + "\n" +
|
||||
"Postdated Ticket " + flags[POSTDATED_TICKET_FLAG] + "\n" +
|
||||
"Renewable Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
|
||||
"Initial Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
|
||||
"Auth Time = " + String.valueOf(authTime) + "\n" +
|
||||
"Start Time = " + String.valueOf(startTime) + "\n" +
|
||||
"End Time = " + endTime.toString() + "\n" +
|
||||
"Renew Till = " + String.valueOf(renewTill) + "\n" +
|
||||
"Client Addresses " +
|
||||
(clientAddresses == null ? " Null " : caddrBuf.toString() +
|
||||
(proxy == null ? "" : "\nwith a proxy ticket") +
|
||||
"\n"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this KerberosTicket.
|
||||
*
|
||||
* @return a hashCode() for the {@code KerberosTicket}
|
||||
* @since 1.6
|
||||
*/
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if (isDestroyed()) {
|
||||
return result;
|
||||
}
|
||||
result = result * 37 + Arrays.hashCode(getEncoded());
|
||||
result = result * 37 + endTime.hashCode();
|
||||
result = result * 37 + client.hashCode();
|
||||
result = result * 37 + server.hashCode();
|
||||
result = result * 37 + sessionKey.hashCode();
|
||||
|
||||
// authTime may be null
|
||||
if (authTime != null) {
|
||||
result = result * 37 + authTime.hashCode();
|
||||
}
|
||||
|
||||
// startTime may be null
|
||||
if (startTime != null) {
|
||||
result = result * 37 + startTime.hashCode();
|
||||
}
|
||||
|
||||
// renewTill may be null
|
||||
if (renewTill != null) {
|
||||
result = result * 37 + renewTill.hashCode();
|
||||
}
|
||||
|
||||
// clientAddress may be null, the array's hashCode is 0
|
||||
result = result * 37 + Arrays.hashCode(clientAddresses);
|
||||
|
||||
if (proxy != null) {
|
||||
result = result * 37 + proxy.hashCode();
|
||||
}
|
||||
return result * 37 + Arrays.hashCode(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified Object with this KerberosTicket for equality.
|
||||
* Returns true if the given object is also a
|
||||
* {@code KerberosTicket} and the two
|
||||
* {@code KerberosTicket} instances are equivalent.
|
||||
*
|
||||
* @param other the Object to compare to
|
||||
* @return true if the specified object is equal to this KerberosTicket,
|
||||
* false otherwise. NOTE: Returns false if either of the KerberosTicket
|
||||
* objects has been destroyed.
|
||||
* @since 1.6
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
|
||||
if (other == this)
|
||||
return true;
|
||||
|
||||
if (! (other instanceof KerberosTicket)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KerberosTicket otherTicket = ((KerberosTicket) other);
|
||||
if (isDestroyed() || otherTicket.isDestroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Arrays.equals(getEncoded(), otherTicket.getEncoded()) ||
|
||||
!endTime.equals(otherTicket.getEndTime()) ||
|
||||
!server.equals(otherTicket.getServer()) ||
|
||||
!client.equals(otherTicket.getClient()) ||
|
||||
!sessionKey.equals(otherTicket.getSessionKey()) ||
|
||||
!Arrays.equals(clientAddresses, otherTicket.getClientAddresses()) ||
|
||||
!Arrays.equals(flags, otherTicket.getFlags())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// authTime may be null
|
||||
if (authTime == null) {
|
||||
if (otherTicket.getAuthTime() != null)
|
||||
return false;
|
||||
} else {
|
||||
if (!authTime.equals(otherTicket.getAuthTime()))
|
||||
return false;
|
||||
}
|
||||
|
||||
// startTime may be null
|
||||
if (startTime == null) {
|
||||
if (otherTicket.getStartTime() != null)
|
||||
return false;
|
||||
} else {
|
||||
if (!startTime.equals(otherTicket.getStartTime()))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (renewTill == null) {
|
||||
if (otherTicket.getRenewTill() != null)
|
||||
return false;
|
||||
} else {
|
||||
if (!renewTill.equals(otherTicket.getRenewTill()))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Objects.equals(proxy, otherTicket.proxy)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
s.defaultReadObject();
|
||||
if (sessionKey == null) {
|
||||
throw new InvalidObjectException("Session key cannot be null");
|
||||
}
|
||||
try {
|
||||
init(asn1Encoding, client, server, sessionKey,
|
||||
flags, authTime, startTime, endTime,
|
||||
renewTill, clientAddresses);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw (InvalidObjectException)
|
||||
new InvalidObjectException(iae.getMessage()).initCause(iae);
|
||||
}
|
||||
}
|
||||
}
|
||||
238
jdkSrc/jdk8/javax/security/auth/kerberos/KeyImpl.java
Normal file
238
jdkSrc/jdk8/javax/security/auth/kerberos/KeyImpl.java
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.kerberos;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.security.auth.Destroyable;
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
|
||||
import sun.security.jgss.krb5.Krb5Util;
|
||||
import sun.security.krb5.Asn1Exception;
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.EncryptionKey;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.KrbException;
|
||||
import sun.security.krb5.KrbCryptoException;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
* This class encapsulates a Kerberos encryption key. It is not associated
|
||||
* with a principal and may represent an ephemeral session key.
|
||||
*
|
||||
* @author Mayank Upadhyay
|
||||
* @since 1.4
|
||||
*
|
||||
* @serial include
|
||||
*/
|
||||
class KeyImpl implements SecretKey, Destroyable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7889313790214321193L;
|
||||
|
||||
private transient byte[] keyBytes;
|
||||
private transient int keyType;
|
||||
private transient volatile boolean destroyed = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a KeyImpl from the given bytes.
|
||||
*
|
||||
* @param keyBytes the raw bytes for the secret key
|
||||
* @param keyType the key type for the secret key as defined by the
|
||||
* Kerberos protocol specification.
|
||||
*/
|
||||
public KeyImpl(byte[] keyBytes,
|
||||
int keyType) {
|
||||
this.keyBytes = keyBytes.clone();
|
||||
this.keyType = keyType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a KeyImpl from a password.
|
||||
*
|
||||
* @param principal the principal from which to derive the salt
|
||||
* @param password the password that should be used to compute the
|
||||
* key.
|
||||
* @param algorithm the name for the algorithm that this key wil be
|
||||
* used for. This parameter may be null in which case "DES" will be
|
||||
* assumed.
|
||||
*/
|
||||
public KeyImpl(KerberosPrincipal principal,
|
||||
char[] password,
|
||||
String algorithm) {
|
||||
|
||||
try {
|
||||
PrincipalName princ = new PrincipalName(principal.getName());
|
||||
EncryptionKey key =
|
||||
new EncryptionKey(password, princ.getSalt(), algorithm);
|
||||
this.keyBytes = key.getBytes();
|
||||
this.keyType = key.getEType();
|
||||
} catch (KrbException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the keyType for this key as defined in the Kerberos Spec.
|
||||
*/
|
||||
public final int getKeyType() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This key is no longer valid");
|
||||
return keyType;
|
||||
}
|
||||
|
||||
/*
|
||||
* Methods from java.security.Key
|
||||
*/
|
||||
|
||||
public final String getAlgorithm() {
|
||||
return getAlgorithmName(keyType);
|
||||
}
|
||||
|
||||
private String getAlgorithmName(int eType) {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This key is no longer valid");
|
||||
|
||||
switch (eType) {
|
||||
case EncryptedData.ETYPE_DES_CBC_CRC:
|
||||
case EncryptedData.ETYPE_DES_CBC_MD5:
|
||||
return "DES";
|
||||
|
||||
case EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD:
|
||||
return "DESede";
|
||||
|
||||
case EncryptedData.ETYPE_ARCFOUR_HMAC:
|
||||
return "ArcFourHmac";
|
||||
|
||||
case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:
|
||||
return "AES128";
|
||||
|
||||
case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
|
||||
return "AES256";
|
||||
|
||||
case EncryptedData.ETYPE_NULL:
|
||||
return "NULL";
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported encryption type: " + eType);
|
||||
}
|
||||
}
|
||||
|
||||
public final String getFormat() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This key is no longer valid");
|
||||
return "RAW";
|
||||
}
|
||||
|
||||
public final byte[] getEncoded() {
|
||||
if (destroyed)
|
||||
throw new IllegalStateException("This key is no longer valid");
|
||||
return keyBytes.clone();
|
||||
}
|
||||
|
||||
public void destroy() throws DestroyFailedException {
|
||||
if (!destroyed) {
|
||||
destroyed = true;
|
||||
Arrays.fill(keyBytes, (byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @serialData this {@code KeyImpl} is serialized by
|
||||
* writing out the ASN1 Encoded bytes of the encryption key.
|
||||
* The ASN1 encoding is defined in RFC4120 and as follows:
|
||||
* EncryptionKey ::= SEQUENCE {
|
||||
* keytype [0] Int32 -- actually encryption type --,
|
||||
* keyvalue [1] OCTET STRING
|
||||
* }
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream ois)
|
||||
throws IOException {
|
||||
if (destroyed) {
|
||||
throw new IOException("This key is no longer valid");
|
||||
}
|
||||
|
||||
try {
|
||||
ois.writeObject((new EncryptionKey(keyType, keyBytes)).asn1Encode());
|
||||
} catch (Asn1Exception ae) {
|
||||
throw new IOException(ae.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois)
|
||||
throws IOException, ClassNotFoundException {
|
||||
try {
|
||||
EncryptionKey encKey = new EncryptionKey(new
|
||||
DerValue((byte[])ois.readObject()));
|
||||
keyType = encKey.getEType();
|
||||
keyBytes = encKey.getBytes();
|
||||
} catch (Asn1Exception ae) {
|
||||
throw new IOException(ae.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "keyType=" + keyType
|
||||
+ ", " + Krb5Util.keyInfo(keyBytes);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
if(isDestroyed()) {
|
||||
return result;
|
||||
}
|
||||
result = 37 * result + Arrays.hashCode(keyBytes);
|
||||
return 37 * result + keyType;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
|
||||
if (other == this)
|
||||
return true;
|
||||
|
||||
if (! (other instanceof KeyImpl)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KeyImpl otherKey = ((KeyImpl) other);
|
||||
if (isDestroyed() || otherKey.isDestroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(keyType != otherKey.getKeyType() ||
|
||||
!Arrays.equals(keyBytes, otherKey.getEncoded())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
380
jdkSrc/jdk8/javax/security/auth/kerberos/KeyTab.java
Normal file
380
jdkSrc/jdk8/javax/security/auth/kerberos/KeyTab.java
Normal file
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.kerberos;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.Objects;
|
||||
import sun.security.krb5.EncryptionKey;
|
||||
import sun.security.krb5.KerberosSecrets;
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.RealmException;
|
||||
|
||||
/**
|
||||
* This class encapsulates a keytab file.
|
||||
* <p>
|
||||
* A Kerberos JAAS login module that obtains long term secret keys from a
|
||||
* keytab file should use this class. The login module will store
|
||||
* an instance of this class in the private credential set of a
|
||||
* {@link javax.security.auth.Subject Subject} during the commit phase of the
|
||||
* authentication process.
|
||||
* <p>
|
||||
* If a {@code KeyTab} object is obtained from {@link #getUnboundInstance()}
|
||||
* or {@link #getUnboundInstance(java.io.File)}, it is unbound and thus can be
|
||||
* used by any service principal. Otherwise, if it's obtained from
|
||||
* {@link #getInstance(KerberosPrincipal)} or
|
||||
* {@link #getInstance(KerberosPrincipal, java.io.File)}, it is bound to the
|
||||
* specific service principal and can only be used by it.
|
||||
* <p>
|
||||
* Please note the constructors {@link #getInstance()} and
|
||||
* {@link #getInstance(java.io.File)} were created when there was no support
|
||||
* for unbound keytabs. These methods should not be used anymore. An object
|
||||
* created with either of these methods are considered to be bound to an
|
||||
* unknown principal, which means, its {@link #isBound()} returns true and
|
||||
* {@link #getPrincipal()} returns null.
|
||||
* <p>
|
||||
* It might be necessary for the application to be granted a
|
||||
* {@link javax.security.auth.PrivateCredentialPermission
|
||||
* PrivateCredentialPermission} if it needs to access the KeyTab
|
||||
* instance from a Subject. This permission is not needed when the
|
||||
* application depends on the default JGSS Kerberos mechanism to access the
|
||||
* KeyTab. In that case, however, the application will need an appropriate
|
||||
* {@link javax.security.auth.kerberos.ServicePermission ServicePermission}.
|
||||
* <p>
|
||||
* The keytab file format is described at
|
||||
* <a href="http://www.ioplex.com/utilities/keytab.txt">
|
||||
* http://www.ioplex.com/utilities/keytab.txt</a>.
|
||||
* <p>
|
||||
* @since 1.7
|
||||
*/
|
||||
public final class KeyTab {
|
||||
|
||||
/*
|
||||
* Impl notes:
|
||||
*
|
||||
* This class is only a name, a permanent link to the keytab source
|
||||
* (can be missing). Itself has no content. In order to read content,
|
||||
* take a snapshot and read from it.
|
||||
*
|
||||
* The snapshot is of type sun.security.krb5.internal.ktab.KeyTab, which
|
||||
* contains the content of the keytab file when the snapshot is taken.
|
||||
* Itself has no refresh function and mostly an immutable class (except
|
||||
* for the create/add/save methods only used by the ktab command).
|
||||
*/
|
||||
|
||||
// Source, null if using the default one. Note that the default name
|
||||
// is maintained in snapshot, this field is never "resolved".
|
||||
private final File file;
|
||||
|
||||
// Bound user: normally from the "principal" value in a JAAS krb5
|
||||
// login conf. Will be null if it's "*".
|
||||
private final KerberosPrincipal princ;
|
||||
|
||||
private final boolean bound;
|
||||
|
||||
// Set up JavaxSecurityAuthKerberosAccess in KerberosSecrets
|
||||
static {
|
||||
KerberosSecrets.setJavaxSecurityAuthKerberosAccess(
|
||||
new JavaxSecurityAuthKerberosAccessImpl());
|
||||
}
|
||||
|
||||
private KeyTab(KerberosPrincipal princ, File file, boolean bound) {
|
||||
this.princ = princ;
|
||||
this.file = file;
|
||||
this.bound = bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code KeyTab} instance from a {@code File} object
|
||||
* that is bound to an unknown service principal.
|
||||
* <p>
|
||||
* The result of this method is never null. This method only associates
|
||||
* the returned {@code KeyTab} object with the file and does not read it.
|
||||
* <p>
|
||||
* Developers should call {@link #getInstance(KerberosPrincipal,File)}
|
||||
* when the bound service principal is known.
|
||||
* @param file the keytab {@code File} object, must not be null
|
||||
* @return the keytab instance
|
||||
* @throws NullPointerException if the {@code file} argument is null
|
||||
*/
|
||||
public static KeyTab getInstance(File file) {
|
||||
if (file == null) {
|
||||
throw new NullPointerException("file must be non null");
|
||||
}
|
||||
return new KeyTab(null, file, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unbound {@code KeyTab} instance from a {@code File}
|
||||
* object.
|
||||
* <p>
|
||||
* The result of this method is never null. This method only associates
|
||||
* the returned {@code KeyTab} object with the file and does not read it.
|
||||
* @param file the keytab {@code File} object, must not be null
|
||||
* @return the keytab instance
|
||||
* @throws NullPointerException if the file argument is null
|
||||
* @since 1.8
|
||||
*/
|
||||
public static KeyTab getUnboundInstance(File file) {
|
||||
if (file == null) {
|
||||
throw new NullPointerException("file must be non null");
|
||||
}
|
||||
return new KeyTab(null, file, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code KeyTab} instance from a {@code File} object
|
||||
* that is bound to the specified service principal.
|
||||
* <p>
|
||||
* The result of this method is never null. This method only associates
|
||||
* the returned {@code KeyTab} object with the file and does not read it.
|
||||
* @param princ the bound service principal, must not be null
|
||||
* @param file the keytab {@code File} object, must not be null
|
||||
* @return the keytab instance
|
||||
* @throws NullPointerException if either of the arguments is null
|
||||
* @since 1.8
|
||||
*/
|
||||
public static KeyTab getInstance(KerberosPrincipal princ, File file) {
|
||||
if (princ == null) {
|
||||
throw new NullPointerException("princ must be non null");
|
||||
}
|
||||
if (file == null) {
|
||||
throw new NullPointerException("file must be non null");
|
||||
}
|
||||
return new KeyTab(princ, file, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default {@code KeyTab} instance that is bound
|
||||
* to an unknown service principal.
|
||||
* <p>
|
||||
* The result of this method is never null. This method only associates
|
||||
* the returned {@code KeyTab} object with the default keytab file and
|
||||
* does not read it.
|
||||
* <p>
|
||||
* Developers should call {@link #getInstance(KerberosPrincipal)}
|
||||
* when the bound service principal is known.
|
||||
* @return the default keytab instance.
|
||||
*/
|
||||
public static KeyTab getInstance() {
|
||||
return new KeyTab(null, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default unbound {@code KeyTab} instance.
|
||||
* <p>
|
||||
* The result of this method is never null. This method only associates
|
||||
* the returned {@code KeyTab} object with the default keytab file and
|
||||
* does not read it.
|
||||
* @return the default keytab instance
|
||||
* @since 1.8
|
||||
*/
|
||||
public static KeyTab getUnboundInstance() {
|
||||
return new KeyTab(null, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default {@code KeyTab} instance that is bound
|
||||
* to the specified service principal.
|
||||
* <p>
|
||||
* The result of this method is never null. This method only associates
|
||||
* the returned {@code KeyTab} object with the default keytab file and
|
||||
* does not read it.
|
||||
* @param princ the bound service principal, must not be null
|
||||
* @return the default keytab instance
|
||||
* @throws NullPointerException if {@code princ} is null
|
||||
* @since 1.8
|
||||
*/
|
||||
public static KeyTab getInstance(KerberosPrincipal princ) {
|
||||
if (princ == null) {
|
||||
throw new NullPointerException("princ must be non null");
|
||||
}
|
||||
return new KeyTab(princ, null, true);
|
||||
}
|
||||
|
||||
// Takes a snapshot of the keytab content. This method is called by
|
||||
// JavaxSecurityAuthKerberosAccessImpl so no more private
|
||||
sun.security.krb5.internal.ktab.KeyTab takeSnapshot() {
|
||||
try {
|
||||
return sun.security.krb5.internal.ktab.KeyTab.getInstance(file);
|
||||
} catch (AccessControlException ace) {
|
||||
if (file != null) {
|
||||
// It's OK to show the name if caller specified it
|
||||
throw ace;
|
||||
} else {
|
||||
AccessControlException ace2 = new AccessControlException(
|
||||
"Access to default keytab denied (modified exception)");
|
||||
ace2.setStackTrace(ace.getStackTrace());
|
||||
throw ace2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns fresh keys for the given Kerberos principal.
|
||||
* <p>
|
||||
* Implementation of this method should make sure the returned keys match
|
||||
* the latest content of the keytab file. The result is a newly created
|
||||
* copy that can be modified by the caller without modifying the keytab
|
||||
* object. The caller should {@link KerberosKey#destroy() destroy} the
|
||||
* result keys after they are used.
|
||||
* <p>
|
||||
* Please note that the keytab file can be created after the
|
||||
* {@code KeyTab} object is instantiated and its content may change over
|
||||
* time. Therefore, an application should call this method only when it
|
||||
* needs to use the keys. Any previous result from an earlier invocation
|
||||
* could potentially be expired.
|
||||
* <p>
|
||||
* If there is any error (say, I/O error or format error)
|
||||
* during the reading process of the KeyTab file, a saved result should be
|
||||
* returned. If there is no saved result (say, this is the first time this
|
||||
* method is called, or, all previous read attempts failed), an empty array
|
||||
* should be returned. This can make sure the result is not drastically
|
||||
* changed during the (probably slow) update of the keytab file.
|
||||
* <p>
|
||||
* Each time this method is called and the reading of the file succeeds
|
||||
* with no exception (say, I/O error or file format error),
|
||||
* the result should be saved for {@code principal}. The implementation can
|
||||
* also save keys for other principals having keys in the same keytab object
|
||||
* if convenient.
|
||||
* <p>
|
||||
* Any unsupported key read from the keytab is ignored and not included
|
||||
* in the result.
|
||||
* <p>
|
||||
* If this keytab is bound to a specific principal, calling this method on
|
||||
* another principal will return an empty array.
|
||||
*
|
||||
* @param principal the Kerberos principal, must not be null.
|
||||
* @return the keys (never null, may be empty)
|
||||
* @throws NullPointerException if the {@code principal}
|
||||
* argument is null
|
||||
* @throws SecurityException if a security manager exists and the read
|
||||
* access to the keytab file is not permitted
|
||||
*/
|
||||
public KerberosKey[] getKeys(KerberosPrincipal principal) {
|
||||
try {
|
||||
if (princ != null && !principal.equals(princ)) {
|
||||
return new KerberosKey[0];
|
||||
}
|
||||
PrincipalName pn = new PrincipalName(principal.getName());
|
||||
EncryptionKey[] keys = takeSnapshot().readServiceKeys(pn);
|
||||
KerberosKey[] kks = new KerberosKey[keys.length];
|
||||
for (int i=0; i<kks.length; i++) {
|
||||
Integer tmp = keys[i].getKeyVersionNumber();
|
||||
kks[i] = new KerberosKey(
|
||||
principal,
|
||||
keys[i].getBytes(),
|
||||
keys[i].getEType(),
|
||||
tmp == null ? 0 : tmp.intValue());
|
||||
keys[i].destroy();
|
||||
}
|
||||
return kks;
|
||||
} catch (RealmException re) {
|
||||
return new KerberosKey[0];
|
||||
}
|
||||
}
|
||||
|
||||
EncryptionKey[] getEncryptionKeys(PrincipalName principal) {
|
||||
return takeSnapshot().readServiceKeys(principal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the keytab file exists. Implementation of this method
|
||||
* should make sure that the result matches the latest status of the
|
||||
* keytab file.
|
||||
* <p>
|
||||
* The caller can use the result to determine if it should fallback to
|
||||
* another mechanism to read the keys.
|
||||
* @return true if the keytab file exists; false otherwise.
|
||||
* @throws SecurityException if a security manager exists and the read
|
||||
* access to the keytab file is not permitted
|
||||
*/
|
||||
public boolean exists() {
|
||||
return !takeSnapshot().isMissing();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String s = (file == null) ? "Default keytab" : file.toString();
|
||||
if (!bound) return s;
|
||||
else if (princ == null) return s + " for someone";
|
||||
else return s + " for " + princ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this KeyTab.
|
||||
*
|
||||
* @return a hashCode() for the {@code KeyTab}
|
||||
*/
|
||||
public int hashCode() {
|
||||
return Objects.hash(file, princ, bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified Object with this KeyTab for equality.
|
||||
* Returns true if the given object is also a
|
||||
* {@code KeyTab} and the two
|
||||
* {@code KeyTab} instances are equivalent.
|
||||
*
|
||||
* @param other the Object to compare to
|
||||
* @return true if the specified object is equal to this KeyTab
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (other == this)
|
||||
return true;
|
||||
|
||||
if (! (other instanceof KeyTab)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KeyTab otherKtab = (KeyTab) other;
|
||||
return Objects.equals(otherKtab.princ, princ) &&
|
||||
Objects.equals(otherKtab.file, file) &&
|
||||
bound == otherKtab.bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the service principal this {@code KeyTab} object
|
||||
* is bound to. Returns {@code null} if it's not bound.
|
||||
* <p>
|
||||
* Please note the deprecated constructors create a KeyTab object bound for
|
||||
* some unknown principal. In this case, this method also returns null.
|
||||
* User can call {@link #isBound()} to verify this case.
|
||||
* @return the service principal
|
||||
* @since 1.8
|
||||
*/
|
||||
public KerberosPrincipal getPrincipal() {
|
||||
return princ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the keytab is bound to a principal
|
||||
* @return if the keytab is bound to a principal
|
||||
* @since 1.8
|
||||
*/
|
||||
public boolean isBound() {
|
||||
return bound;
|
||||
}
|
||||
}
|
||||
616
jdkSrc/jdk8/javax/security/auth/kerberos/ServicePermission.java
Normal file
616
jdkSrc/jdk8/javax/security/auth/kerberos/ServicePermission.java
Normal file
@@ -0,0 +1,616 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.kerberos;
|
||||
|
||||
import java.util.*;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.io.ObjectStreamField;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class is used to protect Kerberos services and the
|
||||
* credentials necessary to access those services. There is a one to
|
||||
* one mapping of a service principal and the credentials necessary
|
||||
* to access the service. Therefore granting access to a service
|
||||
* principal implicitly grants access to the credential necessary to
|
||||
* establish a security context with the service principal. This
|
||||
* applies regardless of whether the credentials are in a cache
|
||||
* or acquired via an exchange with the KDC. The credential can
|
||||
* be either a ticket granting ticket, a service ticket or a secret
|
||||
* key from a key table.
|
||||
* <p>
|
||||
* A ServicePermission contains a service principal name and
|
||||
* a list of actions which specify the context the credential can be
|
||||
* used within.
|
||||
* <p>
|
||||
* The service principal name is the canonical name of the
|
||||
* {@code KerberosPrincipal} supplying the service, that is
|
||||
* the KerberosPrincipal represents a Kerberos service
|
||||
* principal. This name is treated in a case sensitive manner.
|
||||
* An asterisk may appear by itself, to signify any service principal.
|
||||
* <p>
|
||||
* Granting this permission implies that the caller can use a cached
|
||||
* credential (TGT, service ticket or secret key) within the context
|
||||
* designated by the action. In the case of the TGT, granting this
|
||||
* permission also implies that the TGT can be obtained by an
|
||||
* Authentication Service exchange.
|
||||
* <p>
|
||||
* The possible actions are:
|
||||
*
|
||||
* <pre>
|
||||
* initiate - allow the caller to use the credential to
|
||||
* initiate a security context with a service
|
||||
* principal.
|
||||
*
|
||||
* accept - allow the caller to use the credential to
|
||||
* accept security context as a particular
|
||||
* principal.
|
||||
* </pre>
|
||||
*
|
||||
* For example, to specify the permission to access to the TGT to
|
||||
* initiate a security context the permission is constructed as follows:
|
||||
*
|
||||
* <pre>
|
||||
* ServicePermission("krbtgt/EXAMPLE.COM@EXAMPLE.COM", "initiate");
|
||||
* </pre>
|
||||
* <p>
|
||||
* To obtain a service ticket to initiate a context with the "host"
|
||||
* service the permission is constructed as follows:
|
||||
* <pre>
|
||||
* ServicePermission("host/foo.example.com@EXAMPLE.COM", "initiate");
|
||||
* </pre>
|
||||
* <p>
|
||||
* For a Kerberized server the action is "accept". For example, the permission
|
||||
* necessary to access and use the secret key of the Kerberized "host"
|
||||
* service (telnet and the likes) would be constructed as follows:
|
||||
*
|
||||
* <pre>
|
||||
* ServicePermission("host/foo.example.com@EXAMPLE.COM", "accept");
|
||||
* </pre>
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public final class ServicePermission extends Permission
|
||||
implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1227585031618624935L;
|
||||
|
||||
/**
|
||||
* Initiate a security context to the specified service
|
||||
*/
|
||||
private final static int INITIATE = 0x1;
|
||||
|
||||
/**
|
||||
* Accept a security context
|
||||
*/
|
||||
private final static int ACCEPT = 0x2;
|
||||
|
||||
/**
|
||||
* All actions
|
||||
*/
|
||||
private final static int ALL = INITIATE|ACCEPT;
|
||||
|
||||
/**
|
||||
* No actions.
|
||||
*/
|
||||
private final static int NONE = 0x0;
|
||||
|
||||
// the actions mask
|
||||
private transient int mask;
|
||||
|
||||
/**
|
||||
* the actions string.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
|
||||
private String actions; // Left null as long as possible, then
|
||||
// created and re-used in the getAction function.
|
||||
|
||||
/**
|
||||
* Create a new {@code ServicePermission}
|
||||
* with the specified {@code servicePrincipal}
|
||||
* and {@code action}.
|
||||
*
|
||||
* @param servicePrincipal the name of the service principal.
|
||||
* An asterisk may appear by itself, to signify any service principal.
|
||||
* <p>
|
||||
* @param action the action string
|
||||
*/
|
||||
public ServicePermission(String servicePrincipal, String action) {
|
||||
// Note: servicePrincipal can be "@REALM" which means any principal in
|
||||
// this realm implies it. action can be "-" which means any
|
||||
// action implies it.
|
||||
super(servicePrincipal);
|
||||
init(servicePrincipal, getMask(action));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the ServicePermission object.
|
||||
*/
|
||||
private void init(String servicePrincipal, int mask) {
|
||||
|
||||
if (servicePrincipal == null)
|
||||
throw new NullPointerException("service principal can't be null");
|
||||
|
||||
if ((mask & ALL) != mask)
|
||||
throw new IllegalArgumentException("invalid actions mask");
|
||||
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if this Kerberos service permission object "implies" the
|
||||
* specified permission.
|
||||
* <P>
|
||||
* If none of the above are true, {@code implies} returns false.
|
||||
* @param p the permission to check against.
|
||||
*
|
||||
* @return true if the specified permission is implied by this object,
|
||||
* false if not.
|
||||
*/
|
||||
public boolean implies(Permission p) {
|
||||
if (!(p instanceof ServicePermission))
|
||||
return false;
|
||||
|
||||
ServicePermission that = (ServicePermission) p;
|
||||
|
||||
return ((this.mask & that.mask) == that.mask) &&
|
||||
impliesIgnoreMask(that);
|
||||
}
|
||||
|
||||
|
||||
boolean impliesIgnoreMask(ServicePermission p) {
|
||||
return ((this.getName().equals("*")) ||
|
||||
this.getName().equals(p.getName()) ||
|
||||
(p.getName().startsWith("@") &&
|
||||
this.getName().endsWith(p.getName())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks two ServicePermission objects for equality.
|
||||
* <P>
|
||||
* @param obj the object to test for equality with this object.
|
||||
*
|
||||
* @return true if <i>obj</i> is a ServicePermission, and has the
|
||||
* same service principal, and actions as this
|
||||
* ServicePermission object.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
if (! (obj instanceof ServicePermission))
|
||||
return false;
|
||||
|
||||
ServicePermission that = (ServicePermission) obj;
|
||||
return ((this.mask & that.mask) == that.mask) &&
|
||||
this.getName().equals(that.getName());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this object.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
|
||||
public int hashCode() {
|
||||
return (getName().hashCode() ^ mask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the "canonical string representation" of the actions in the
|
||||
* specified mask.
|
||||
* Always returns present actions in the following order:
|
||||
* initiate, accept.
|
||||
*
|
||||
* @param mask a specific integer action mask to translate into a string
|
||||
* @return the canonical string representation of the actions
|
||||
*/
|
||||
private static String getActions(int mask)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean comma = false;
|
||||
|
||||
if ((mask & INITIATE) == INITIATE) {
|
||||
if (comma) sb.append(',');
|
||||
else comma = true;
|
||||
sb.append("initiate");
|
||||
}
|
||||
|
||||
if ((mask & ACCEPT) == ACCEPT) {
|
||||
if (comma) sb.append(',');
|
||||
else comma = true;
|
||||
sb.append("accept");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the canonical string representation of the actions.
|
||||
* Always returns present actions in the following order:
|
||||
* initiate, accept.
|
||||
*/
|
||||
public String getActions() {
|
||||
if (actions == null)
|
||||
actions = getActions(this.mask);
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a PermissionCollection object for storing
|
||||
* ServicePermission objects.
|
||||
* <br>
|
||||
* ServicePermission objects must be stored in a manner that
|
||||
* allows them to be inserted into the collection in any order, but
|
||||
* that also enables the PermissionCollection implies method to
|
||||
* be implemented in an efficient (and consistent) manner.
|
||||
*
|
||||
* @return a new PermissionCollection object suitable for storing
|
||||
* ServicePermissions.
|
||||
*/
|
||||
public PermissionCollection newPermissionCollection() {
|
||||
return new KrbServicePermissionCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current action mask.
|
||||
*
|
||||
* @return the actions mask.
|
||||
*/
|
||||
int getMask() {
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an action string to an integer actions mask.
|
||||
*
|
||||
* Note: if action is "-", action will be NONE, which means any
|
||||
* action implies it.
|
||||
*
|
||||
* @param action the action string.
|
||||
* @return the action mask
|
||||
*/
|
||||
private static int getMask(String action) {
|
||||
|
||||
if (action == null) {
|
||||
throw new NullPointerException("action can't be null");
|
||||
}
|
||||
|
||||
if (action.equals("")) {
|
||||
throw new IllegalArgumentException("action can't be empty");
|
||||
}
|
||||
|
||||
int mask = NONE;
|
||||
|
||||
char[] a = action.toCharArray();
|
||||
|
||||
if (a.length == 1 && a[0] == '-') {
|
||||
return mask;
|
||||
}
|
||||
|
||||
int i = a.length - 1;
|
||||
|
||||
while (i != -1) {
|
||||
char c;
|
||||
|
||||
// skip whitespace
|
||||
while ((i!=-1) && ((c = a[i]) == ' ' ||
|
||||
c == '\r' ||
|
||||
c == '\n' ||
|
||||
c == '\f' ||
|
||||
c == '\t'))
|
||||
i--;
|
||||
|
||||
// check for the known strings
|
||||
int matchlen;
|
||||
|
||||
if (i >= 7 && (a[i-7] == 'i' || a[i-7] == 'I') &&
|
||||
(a[i-6] == 'n' || a[i-6] == 'N') &&
|
||||
(a[i-5] == 'i' || a[i-5] == 'I') &&
|
||||
(a[i-4] == 't' || a[i-4] == 'T') &&
|
||||
(a[i-3] == 'i' || a[i-3] == 'I') &&
|
||||
(a[i-2] == 'a' || a[i-2] == 'A') &&
|
||||
(a[i-1] == 't' || a[i-1] == 'T') &&
|
||||
(a[i] == 'e' || a[i] == 'E'))
|
||||
{
|
||||
matchlen = 8;
|
||||
mask |= INITIATE;
|
||||
|
||||
} else if (i >= 5 && (a[i-5] == 'a' || a[i-5] == 'A') &&
|
||||
(a[i-4] == 'c' || a[i-4] == 'C') &&
|
||||
(a[i-3] == 'c' || a[i-3] == 'C') &&
|
||||
(a[i-2] == 'e' || a[i-2] == 'E') &&
|
||||
(a[i-1] == 'p' || a[i-1] == 'P') &&
|
||||
(a[i] == 't' || a[i] == 'T'))
|
||||
{
|
||||
matchlen = 6;
|
||||
mask |= ACCEPT;
|
||||
|
||||
} else {
|
||||
// parse error
|
||||
throw new IllegalArgumentException(
|
||||
"invalid permission: " + action);
|
||||
}
|
||||
|
||||
// make sure we didn't just match the tail of a word
|
||||
// like "ackbarfaccept". Also, skip to the comma.
|
||||
boolean seencomma = false;
|
||||
while (i >= matchlen && !seencomma) {
|
||||
switch(a[i-matchlen]) {
|
||||
case ',':
|
||||
seencomma = true;
|
||||
break;
|
||||
case ' ': case '\r': case '\n':
|
||||
case '\f': case '\t':
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"invalid permission: " + action);
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
// point i at the location of the comma minus one (or -1).
|
||||
i -= matchlen;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* WriteObject is called to save the state of the ServicePermission
|
||||
* to a stream. The actions are serialized, and the superclass
|
||||
* takes care of the name.
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws IOException
|
||||
{
|
||||
// Write out the actions. The superclass takes care of the name
|
||||
// call getActions to make sure actions field is initialized
|
||||
if (actions == null)
|
||||
getActions();
|
||||
s.defaultWriteObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the
|
||||
* ServicePermission from a stream.
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
// Read in the action, then initialize the rest
|
||||
s.defaultReadObject();
|
||||
init(getName(),getMask(actions));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public static void main(String args[]) throws Exception {
|
||||
ServicePermission this_ =
|
||||
new ServicePermission(args[0], "accept");
|
||||
ServicePermission that_ =
|
||||
new ServicePermission(args[1], "accept,initiate");
|
||||
System.out.println("-----\n");
|
||||
System.out.println("this.implies(that) = " + this_.implies(that_));
|
||||
System.out.println("-----\n");
|
||||
System.out.println("this = "+this_);
|
||||
System.out.println("-----\n");
|
||||
System.out.println("that = "+that_);
|
||||
System.out.println("-----\n");
|
||||
|
||||
KrbServicePermissionCollection nps =
|
||||
new KrbServicePermissionCollection();
|
||||
nps.add(this_);
|
||||
nps.add(new ServicePermission("nfs/example.com@EXAMPLE.COM",
|
||||
"accept"));
|
||||
nps.add(new ServicePermission("host/example.com@EXAMPLE.COM",
|
||||
"initiate"));
|
||||
System.out.println("nps.implies(that) = " + nps.implies(that_));
|
||||
System.out.println("-----\n");
|
||||
|
||||
Enumeration e = nps.elements();
|
||||
|
||||
while (e.hasMoreElements()) {
|
||||
ServicePermission x =
|
||||
(ServicePermission) e.nextElement();
|
||||
System.out.println("nps.e = " + x);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
final class KrbServicePermissionCollection extends PermissionCollection
|
||||
implements java.io.Serializable {
|
||||
|
||||
// Not serialized; see serialization section at end of class
|
||||
private transient List<Permission> perms;
|
||||
|
||||
public KrbServicePermissionCollection() {
|
||||
perms = new ArrayList<Permission>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and see if this collection of permissions implies the permissions
|
||||
* expressed in "permission".
|
||||
*
|
||||
* @param permission the Permission object to compare
|
||||
*
|
||||
* @return true if "permission" is a proper subset of a permission in
|
||||
* the collection, false if not.
|
||||
*/
|
||||
public boolean implies(Permission permission) {
|
||||
if (! (permission instanceof ServicePermission))
|
||||
return false;
|
||||
|
||||
ServicePermission np = (ServicePermission) permission;
|
||||
int desired = np.getMask();
|
||||
|
||||
if (desired == 0) {
|
||||
for (Permission p: perms) {
|
||||
ServicePermission sp = (ServicePermission)p;
|
||||
if (sp.impliesIgnoreMask(np)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int effective = 0;
|
||||
int needed = desired;
|
||||
|
||||
synchronized (this) {
|
||||
int len = perms.size();
|
||||
|
||||
// need to deal with the case where the needed permission has
|
||||
// more than one action and the collection has individual permissions
|
||||
// that sum up to the needed.
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
ServicePermission x = (ServicePermission) perms.get(i);
|
||||
|
||||
//System.out.println(" trying "+x);
|
||||
if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(np)) {
|
||||
effective |= x.getMask();
|
||||
if ((effective & desired) == desired)
|
||||
return true;
|
||||
needed = (desired ^ effective);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a permission to the ServicePermissions. The key for
|
||||
* the hash is the name.
|
||||
*
|
||||
* @param permission the Permission object to add.
|
||||
*
|
||||
* @exception IllegalArgumentException - if the permission is not a
|
||||
* ServicePermission
|
||||
*
|
||||
* @exception SecurityException - if this PermissionCollection object
|
||||
* has been marked readonly
|
||||
*/
|
||||
public void add(Permission permission) {
|
||||
if (! (permission instanceof ServicePermission))
|
||||
throw new IllegalArgumentException("invalid permission: "+
|
||||
permission);
|
||||
if (isReadOnly())
|
||||
throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
|
||||
|
||||
synchronized (this) {
|
||||
perms.add(0, permission);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an enumeration of all the ServicePermission objects
|
||||
* in the container.
|
||||
*
|
||||
* @return an enumeration of all the ServicePermission objects.
|
||||
*/
|
||||
|
||||
public Enumeration<Permission> elements() {
|
||||
// Convert Iterator into Enumeration
|
||||
synchronized (this) {
|
||||
return Collections.enumeration(perms);
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -4118834211490102011L;
|
||||
|
||||
// Need to maintain serialization interoperability with earlier releases,
|
||||
// which had the serializable field:
|
||||
// private Vector permissions;
|
||||
|
||||
/**
|
||||
* @serialField permissions java.util.Vector
|
||||
* A list of ServicePermission objects.
|
||||
*/
|
||||
private static final ObjectStreamField[] serialPersistentFields = {
|
||||
new ObjectStreamField("permissions", Vector.class),
|
||||
};
|
||||
|
||||
/**
|
||||
* @serialData "permissions" field (a Vector containing the ServicePermissions).
|
||||
*/
|
||||
/*
|
||||
* Writes the contents of the perms field out as a Vector for
|
||||
* serialization compatibility with earlier releases.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
// Don't call out.defaultWriteObject()
|
||||
|
||||
// Write out Vector
|
||||
Vector<Permission> permissions = new Vector<>(perms.size());
|
||||
|
||||
synchronized (this) {
|
||||
permissions.addAll(perms);
|
||||
}
|
||||
|
||||
ObjectOutputStream.PutField pfields = out.putFields();
|
||||
pfields.put("permissions", permissions);
|
||||
out.writeFields();
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads in a Vector of ServicePermissions and saves them in the perms field.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void readObject(ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
// Don't call defaultReadObject()
|
||||
|
||||
// Read in serialized fields
|
||||
ObjectInputStream.GetField gfields = in.readFields();
|
||||
|
||||
// Get the one we want
|
||||
Vector<Permission> permissions =
|
||||
(Vector<Permission>)gfields.get("permissions", null);
|
||||
perms = new ArrayList<Permission>(permissions.size());
|
||||
perms.addAll(permissions);
|
||||
}
|
||||
}
|
||||
59
jdkSrc/jdk8/javax/security/auth/kerberos/package-info.java
Normal file
59
jdkSrc/jdk8/javax/security/auth/kerberos/package-info.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This package contains utility classes related to the Kerberos network
|
||||
* authentication protocol. They do not provide much Kerberos support
|
||||
* themselves.<p>
|
||||
*
|
||||
* The Kerberos network authentication protocol is defined in
|
||||
* <a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>. The Java
|
||||
* platform contains support for the client side of Kerberos via the
|
||||
* {@link org.ietf.jgss} package. There might also be
|
||||
* a login module that implements
|
||||
* {@link javax.security.auth.spi.LoginModule LoginModule} to authenticate
|
||||
* Kerberos principals.<p>
|
||||
*
|
||||
* You can provide the name of your default realm and Key Distribution
|
||||
* Center (KDC) host for that realm using the system properties
|
||||
* {@code java.security.krb5.realm} and {@code java.security.krb5.kdc}.
|
||||
* Both properties must be set.
|
||||
* Alternatively, the {@code java.security.krb5.conf} system property can
|
||||
* be set to the location of an MIT style {@code krb5.conf} configuration
|
||||
* file. If none of these system properties are set, the {@code krb5.conf}
|
||||
* file is searched for in an implementation-specific manner. Typically,
|
||||
* an implementation will first look for a {@code krb5.conf} file in
|
||||
* {@code <java-home>/lib/security} and failing that, in an OS-specific
|
||||
* location.<p>
|
||||
*
|
||||
* The {@code krb5.conf} file is formatted in the Windows INI file style,
|
||||
* which contains a series of relations grouped into different sections.
|
||||
* Each relation contains a key and a value, the value can be an arbitrary
|
||||
* string or a boolean value. A boolean value can be one of "true", "false",
|
||||
* "yes", or "no", case-insensitive.<p>
|
||||
*
|
||||
* @since JDK1.4
|
||||
*/
|
||||
package javax.security.auth.kerberos;
|
||||
57
jdkSrc/jdk8/javax/security/auth/login/AccountException.java
Normal file
57
jdkSrc/jdk8/javax/security/auth/login/AccountException.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
/**
|
||||
* A generic account exception.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class AccountException extends LoginException {
|
||||
|
||||
private static final long serialVersionUID = -2112878680072211787L;
|
||||
|
||||
/**
|
||||
* Constructs a AccountException with no detail message. A detail
|
||||
* message is a String that describes this particular exception.
|
||||
*/
|
||||
public AccountException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a AccountException with the specified detail message.
|
||||
* A detail message is a String that describes this particular
|
||||
* exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public AccountException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
/**
|
||||
* Signals that a user account has expired.
|
||||
*
|
||||
* <p> This exception is thrown by LoginModules when they determine
|
||||
* that an account has expired. For example, a {@code LoginModule},
|
||||
* after successfully authenticating a user, may determine that the
|
||||
* user's account has expired. In this case the {@code LoginModule}
|
||||
* throws this exception to notify the application. The application can
|
||||
* then take the appropriate steps to notify the user.
|
||||
*
|
||||
*/
|
||||
public class AccountExpiredException extends AccountException {
|
||||
|
||||
private static final long serialVersionUID = -6064064890162661560L;
|
||||
|
||||
/**
|
||||
* Constructs a AccountExpiredException with no detail message. A detail
|
||||
* message is a String that describes this particular exception.
|
||||
*/
|
||||
public AccountExpiredException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a AccountExpiredException with the specified detail
|
||||
* message. A detail message is a String that describes this particular
|
||||
* exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public AccountExpiredException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
/**
|
||||
* Signals that an account was locked.
|
||||
*
|
||||
* <p> This exception may be thrown by a LoginModule if it
|
||||
* determines that authentication is being attempted on a
|
||||
* locked account.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class AccountLockedException extends AccountException {
|
||||
|
||||
private static final long serialVersionUID = 8280345554014066334L;
|
||||
|
||||
/**
|
||||
* Constructs a AccountLockedException with no detail message.
|
||||
* A detail message is a String that describes this particular exception.
|
||||
*/
|
||||
public AccountLockedException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a AccountLockedException with the specified
|
||||
* detail message. A detail message is a String that describes
|
||||
* this particular exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public AccountLockedException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
/**
|
||||
* Signals that an account was not found.
|
||||
*
|
||||
* <p> This exception may be thrown by a LoginModule if it is unable
|
||||
* to locate an account necessary to perform authentication.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class AccountNotFoundException extends AccountException {
|
||||
|
||||
private static final long serialVersionUID = 1498349563916294614L;
|
||||
|
||||
/**
|
||||
* Constructs a AccountNotFoundException with no detail message.
|
||||
* A detail message is a String that describes this particular exception.
|
||||
*/
|
||||
public AccountNotFoundException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a AccountNotFoundException with the specified
|
||||
* detail message. A detail message is a String that describes
|
||||
* this particular exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public AccountNotFoundException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
173
jdkSrc/jdk8/javax/security/auth/login/AppConfigurationEntry.java
Normal file
173
jdkSrc/jdk8/javax/security/auth/login/AppConfigurationEntry.java
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* This class represents a single {@code LoginModule} entry
|
||||
* configured for the application specified in the
|
||||
* {@code getAppConfigurationEntry(String appName)}
|
||||
* method in the {@code Configuration} class. Each respective
|
||||
* {@code AppConfigurationEntry} contains a {@code LoginModule} name,
|
||||
* a control flag (specifying whether this {@code LoginModule} is
|
||||
* REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL), and LoginModule-specific
|
||||
* options. Please refer to the {@code Configuration} class for
|
||||
* more information on the different control flags and their semantics.
|
||||
*
|
||||
* @see javax.security.auth.login.Configuration
|
||||
*/
|
||||
public class AppConfigurationEntry {
|
||||
|
||||
private String loginModuleName;
|
||||
private LoginModuleControlFlag controlFlag;
|
||||
private Map<String,?> options;
|
||||
|
||||
/**
|
||||
* Default constructor for this class.
|
||||
*
|
||||
* <p> This entry represents a single {@code LoginModule}
|
||||
* entry configured for the application specified in the
|
||||
* {@code getAppConfigurationEntry(String appName)}
|
||||
* method from the {@code Configuration} class.
|
||||
*
|
||||
* @param loginModuleName String representing the class name of the
|
||||
* {@code LoginModule} configured for the
|
||||
* specified application. <p>
|
||||
*
|
||||
* @param controlFlag either REQUIRED, REQUISITE, SUFFICIENT,
|
||||
* or OPTIONAL. <p>
|
||||
*
|
||||
* @param options the options configured for this {@code LoginModule}.
|
||||
*
|
||||
* @exception IllegalArgumentException if {@code loginModuleName}
|
||||
* is null, if {@code LoginModuleName}
|
||||
* has a length of 0, if {@code controlFlag}
|
||||
* is not either REQUIRED, REQUISITE, SUFFICIENT
|
||||
* or OPTIONAL, or if {@code options} is null.
|
||||
*/
|
||||
public AppConfigurationEntry(String loginModuleName,
|
||||
LoginModuleControlFlag controlFlag,
|
||||
Map<String,?> options)
|
||||
{
|
||||
if (loginModuleName == null || loginModuleName.length() == 0 ||
|
||||
(controlFlag != LoginModuleControlFlag.REQUIRED &&
|
||||
controlFlag != LoginModuleControlFlag.REQUISITE &&
|
||||
controlFlag != LoginModuleControlFlag.SUFFICIENT &&
|
||||
controlFlag != LoginModuleControlFlag.OPTIONAL) ||
|
||||
options == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.loginModuleName = loginModuleName;
|
||||
this.controlFlag = controlFlag;
|
||||
this.options = Collections.unmodifiableMap(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class name of the configured {@code LoginModule}.
|
||||
*
|
||||
* @return the class name of the configured {@code LoginModule} as
|
||||
* a String.
|
||||
*/
|
||||
public String getLoginModuleName() {
|
||||
return loginModuleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the controlFlag
|
||||
* (either REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL)
|
||||
* for this {@code LoginModule}.
|
||||
*
|
||||
* @return the controlFlag
|
||||
* (either REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL)
|
||||
* for this {@code LoginModule}.
|
||||
*/
|
||||
public LoginModuleControlFlag getControlFlag() {
|
||||
return controlFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options configured for this {@code LoginModule}.
|
||||
*
|
||||
* @return the options configured for this {@code LoginModule}
|
||||
* as an unmodifiable {@code Map}.
|
||||
*/
|
||||
public Map<String,?> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class represents whether or not a {@code LoginModule}
|
||||
* is REQUIRED, REQUISITE, SUFFICIENT or OPTIONAL.
|
||||
*/
|
||||
public static class LoginModuleControlFlag {
|
||||
|
||||
private String controlFlag;
|
||||
|
||||
/**
|
||||
* Required {@code LoginModule}.
|
||||
*/
|
||||
public static final LoginModuleControlFlag REQUIRED =
|
||||
new LoginModuleControlFlag("required");
|
||||
|
||||
/**
|
||||
* Requisite {@code LoginModule}.
|
||||
*/
|
||||
public static final LoginModuleControlFlag REQUISITE =
|
||||
new LoginModuleControlFlag("requisite");
|
||||
|
||||
/**
|
||||
* Sufficient {@code LoginModule}.
|
||||
*/
|
||||
public static final LoginModuleControlFlag SUFFICIENT =
|
||||
new LoginModuleControlFlag("sufficient");
|
||||
|
||||
/**
|
||||
* Optional {@code LoginModule}.
|
||||
*/
|
||||
public static final LoginModuleControlFlag OPTIONAL =
|
||||
new LoginModuleControlFlag("optional");
|
||||
|
||||
private LoginModuleControlFlag(String controlFlag) {
|
||||
this.controlFlag = controlFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a String representation of this controlFlag.
|
||||
*
|
||||
* <p> The String has the format, "LoginModuleControlFlag: <i>flag</i>",
|
||||
* where <i>flag</i> is either <i>required</i>, <i>requisite</i>,
|
||||
* <i>sufficient</i>, or <i>optional</i>.
|
||||
*
|
||||
* @return a String representation of this controlFlag.
|
||||
*/
|
||||
public String toString() {
|
||||
return (sun.security.util.ResourcesMgr.getString
|
||||
("LoginModuleControlFlag.") + controlFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
620
jdkSrc/jdk8/javax/security/auth/login/Configuration.java
Normal file
620
jdkSrc/jdk8/javax/security/auth/login/Configuration.java
Normal file
@@ -0,0 +1,620 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
import javax.security.auth.AuthPermission;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.util.Objects;
|
||||
|
||||
import sun.security.jca.GetInstance;
|
||||
|
||||
/**
|
||||
* A Configuration object is responsible for specifying which LoginModules
|
||||
* should be used for a particular application, and in what order the
|
||||
* LoginModules should be invoked.
|
||||
*
|
||||
* <p> A login configuration contains the following information.
|
||||
* Note that this example only represents the default syntax for the
|
||||
* {@code Configuration}. Subclass implementations of this class
|
||||
* may implement alternative syntaxes and may retrieve the
|
||||
* {@code Configuration} from any source such as files, databases,
|
||||
* or servers.
|
||||
*
|
||||
* <pre>
|
||||
* Name {
|
||||
* ModuleClass Flag ModuleOptions;
|
||||
* ModuleClass Flag ModuleOptions;
|
||||
* ModuleClass Flag ModuleOptions;
|
||||
* };
|
||||
* Name {
|
||||
* ModuleClass Flag ModuleOptions;
|
||||
* ModuleClass Flag ModuleOptions;
|
||||
* };
|
||||
* other {
|
||||
* ModuleClass Flag ModuleOptions;
|
||||
* ModuleClass Flag ModuleOptions;
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* <p> Each entry in the {@code Configuration} is indexed via an
|
||||
* application name, <i>Name</i>, and contains a list of
|
||||
* LoginModules configured for that application. Each {@code LoginModule}
|
||||
* is specified via its fully qualified class name.
|
||||
* Authentication proceeds down the module list in the exact order specified.
|
||||
* If an application does not have a specific entry,
|
||||
* it defaults to the specific entry for "<i>other</i>".
|
||||
*
|
||||
* <p> The <i>Flag</i> value controls the overall behavior as authentication
|
||||
* proceeds down the stack. The following represents a description of the
|
||||
* valid values for <i>Flag</i> and their respective semantics:
|
||||
*
|
||||
* <pre>
|
||||
* 1) Required - The {@code LoginModule} is required to succeed.
|
||||
* If it succeeds or fails, authentication still continues
|
||||
* to proceed down the {@code LoginModule} list.
|
||||
*
|
||||
* 2) Requisite - The {@code LoginModule} is required to succeed.
|
||||
* If it succeeds, authentication continues down the
|
||||
* {@code LoginModule} list. If it fails,
|
||||
* control immediately returns to the application
|
||||
* (authentication does not proceed down the
|
||||
* {@code LoginModule} list).
|
||||
*
|
||||
* 3) Sufficient - The {@code LoginModule} is not required to
|
||||
* succeed. If it does succeed, control immediately
|
||||
* returns to the application (authentication does not
|
||||
* proceed down the {@code LoginModule} list).
|
||||
* If it fails, authentication continues down the
|
||||
* {@code LoginModule} list.
|
||||
*
|
||||
* 4) Optional - The {@code LoginModule} is not required to
|
||||
* succeed. If it succeeds or fails,
|
||||
* authentication still continues to proceed down the
|
||||
* {@code LoginModule} list.
|
||||
* </pre>
|
||||
*
|
||||
* <p> The overall authentication succeeds only if all <i>Required</i> and
|
||||
* <i>Requisite</i> LoginModules succeed. If a <i>Sufficient</i>
|
||||
* {@code LoginModule} is configured and succeeds,
|
||||
* then only the <i>Required</i> and <i>Requisite</i> LoginModules prior to
|
||||
* that <i>Sufficient</i> {@code LoginModule} need to have succeeded for
|
||||
* the overall authentication to succeed. If no <i>Required</i> or
|
||||
* <i>Requisite</i> LoginModules are configured for an application,
|
||||
* then at least one <i>Sufficient</i> or <i>Optional</i>
|
||||
* {@code LoginModule} must succeed.
|
||||
*
|
||||
* <p> <i>ModuleOptions</i> is a space separated list of
|
||||
* {@code LoginModule}-specific values which are passed directly to
|
||||
* the underlying LoginModules. Options are defined by the
|
||||
* {@code LoginModule} itself, and control the behavior within it.
|
||||
* For example, a {@code LoginModule} may define options to support
|
||||
* debugging/testing capabilities. The correct way to specify options in the
|
||||
* {@code Configuration} is by using the following key-value pairing:
|
||||
* <i>debug="true"</i>. The key and value should be separated by an
|
||||
* 'equals' symbol, and the value should be surrounded by double quotes.
|
||||
* If a String in the form, ${system.property}, occurs in the value,
|
||||
* it will be expanded to the value of the system property.
|
||||
* Note that there is no limit to the number of
|
||||
* options a {@code LoginModule} may define.
|
||||
*
|
||||
* <p> The following represents an example {@code Configuration} entry
|
||||
* based on the syntax above:
|
||||
*
|
||||
* <pre>
|
||||
* Login {
|
||||
* com.sun.security.auth.module.UnixLoginModule required;
|
||||
* com.sun.security.auth.module.Krb5LoginModule optional
|
||||
* useTicketCache="true"
|
||||
* ticketCache="${user.home}${/}tickets";
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* <p> This {@code Configuration} specifies that an application named,
|
||||
* "Login", requires users to first authenticate to the
|
||||
* <i>com.sun.security.auth.module.UnixLoginModule</i>, which is
|
||||
* required to succeed. Even if the <i>UnixLoginModule</i>
|
||||
* authentication fails, the
|
||||
* <i>com.sun.security.auth.module.Krb5LoginModule</i>
|
||||
* still gets invoked. This helps hide the source of failure.
|
||||
* Since the <i>Krb5LoginModule</i> is <i>Optional</i>, the overall
|
||||
* authentication succeeds only if the <i>UnixLoginModule</i>
|
||||
* (<i>Required</i>) succeeds.
|
||||
*
|
||||
* <p> Also note that the LoginModule-specific options,
|
||||
* <i>useTicketCache="true"</i> and
|
||||
* <i>ticketCache=${user.home}${/}tickets"</i>,
|
||||
* are passed to the <i>Krb5LoginModule</i>.
|
||||
* These options instruct the <i>Krb5LoginModule</i> to
|
||||
* use the ticket cache at the specified location.
|
||||
* The system properties, <i>user.home</i> and <i>/</i>
|
||||
* (file.separator), are expanded to their respective values.
|
||||
*
|
||||
* <p> There is only one Configuration object installed in the runtime at any
|
||||
* given time. A Configuration object can be installed by calling the
|
||||
* {@code setConfiguration} method. The installed Configuration object
|
||||
* can be obtained by calling the {@code getConfiguration} method.
|
||||
*
|
||||
* <p> If no Configuration object has been installed in the runtime, a call to
|
||||
* {@code getConfiguration} installs an instance of the default
|
||||
* Configuration implementation (a default subclass implementation of this
|
||||
* abstract class).
|
||||
* The default Configuration implementation can be changed by setting the value
|
||||
* of the {@code login.configuration.provider} security property to the fully
|
||||
* qualified name of the desired Configuration subclass implementation.
|
||||
*
|
||||
* <p> Application code can directly subclass Configuration to provide a custom
|
||||
* implementation. In addition, an instance of a Configuration object can be
|
||||
* constructed by invoking one of the {@code getInstance} factory methods
|
||||
* with a standard type. The default policy type is "JavaLoginConfig".
|
||||
* See the Configuration section in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for a list of standard Configuration types.
|
||||
*
|
||||
* @see javax.security.auth.login.LoginContext
|
||||
* @see java.security.Security security properties
|
||||
*/
|
||||
public abstract class Configuration {
|
||||
|
||||
private static Configuration configuration;
|
||||
|
||||
private final java.security.AccessControlContext acc =
|
||||
java.security.AccessController.getContext();
|
||||
|
||||
private static void checkPermission(String type) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new AuthPermission
|
||||
("createLoginConfiguration." + type));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
*/
|
||||
protected Configuration() { }
|
||||
|
||||
/**
|
||||
* Get the installed login Configuration.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the login Configuration. If a Configuration object was set
|
||||
* via the {@code Configuration.setConfiguration} method,
|
||||
* then that object is returned. Otherwise, a default
|
||||
* Configuration object is returned.
|
||||
*
|
||||
* @exception SecurityException if the caller does not have permission
|
||||
* to retrieve the Configuration.
|
||||
*
|
||||
* @see #setConfiguration
|
||||
*/
|
||||
public static Configuration getConfiguration() {
|
||||
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null)
|
||||
sm.checkPermission(new AuthPermission("getLoginConfiguration"));
|
||||
|
||||
synchronized (Configuration.class) {
|
||||
if (configuration == null) {
|
||||
String config_class = null;
|
||||
config_class = AccessController.doPrivileged
|
||||
(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return java.security.Security.getProperty
|
||||
("login.configuration.provider");
|
||||
}
|
||||
});
|
||||
if (config_class == null) {
|
||||
config_class = "sun.security.provider.ConfigFile";
|
||||
}
|
||||
|
||||
try {
|
||||
final String finalClass = config_class;
|
||||
Configuration untrustedImpl = AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Configuration>() {
|
||||
public Configuration run() throws ClassNotFoundException,
|
||||
InstantiationException,
|
||||
IllegalAccessException {
|
||||
Class<? extends Configuration> implClass = Class.forName(
|
||||
finalClass, false,
|
||||
Thread.currentThread().getContextClassLoader()
|
||||
).asSubclass(Configuration.class);
|
||||
return implClass.newInstance();
|
||||
}
|
||||
});
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() {
|
||||
setConfiguration(untrustedImpl);
|
||||
return null;
|
||||
}
|
||||
}, Objects.requireNonNull(untrustedImpl.acc)
|
||||
);
|
||||
} catch (PrivilegedActionException e) {
|
||||
Exception ee = e.getException();
|
||||
if (ee instanceof InstantiationException) {
|
||||
throw (SecurityException) new
|
||||
SecurityException
|
||||
("Configuration error:" +
|
||||
ee.getCause().getMessage() +
|
||||
"\n").initCause(ee.getCause());
|
||||
} else {
|
||||
throw (SecurityException) new
|
||||
SecurityException
|
||||
("Configuration error: " +
|
||||
ee.toString() +
|
||||
"\n").initCause(ee);
|
||||
}
|
||||
}
|
||||
}
|
||||
return configuration;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the login {@code Configuration}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param configuration the new {@code Configuration}
|
||||
*
|
||||
* @exception SecurityException if the current thread does not have
|
||||
* Permission to set the {@code Configuration}.
|
||||
*
|
||||
* @see #getConfiguration
|
||||
*/
|
||||
public static void setConfiguration(Configuration configuration) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null)
|
||||
sm.checkPermission(new AuthPermission("setLoginConfiguration"));
|
||||
Configuration.configuration = configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Configuration object of the specified type.
|
||||
*
|
||||
* <p> This method traverses the list of registered security providers,
|
||||
* starting with the most preferred Provider.
|
||||
* A new Configuration object encapsulating the
|
||||
* ConfigurationSpi implementation from the first
|
||||
* Provider that supports the specified type is returned.
|
||||
*
|
||||
* <p> Note that the list of registered providers may be retrieved via
|
||||
* the {@link Security#getProviders() Security.getProviders()} method.
|
||||
*
|
||||
* @param type the specified Configuration type. See the Configuration
|
||||
* section in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
|
||||
* Java Cryptography Architecture Standard Algorithm Name
|
||||
* Documentation</a> for a list of standard Configuration types.
|
||||
*
|
||||
* @param params parameters for the Configuration, which may be null.
|
||||
*
|
||||
* @return the new Configuration object.
|
||||
*
|
||||
* @exception SecurityException if the caller does not have permission
|
||||
* to get a Configuration instance for the specified type.
|
||||
*
|
||||
* @exception NullPointerException if the specified type is null.
|
||||
*
|
||||
* @exception IllegalArgumentException if the specified parameters
|
||||
* are not understood by the ConfigurationSpi implementation
|
||||
* from the selected Provider.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if no Provider supports a
|
||||
* ConfigurationSpi implementation for the specified type.
|
||||
*
|
||||
* @see Provider
|
||||
* @since 1.6
|
||||
*/
|
||||
public static Configuration getInstance(String type,
|
||||
Configuration.Parameters params)
|
||||
throws NoSuchAlgorithmException {
|
||||
|
||||
checkPermission(type);
|
||||
try {
|
||||
GetInstance.Instance instance = GetInstance.getInstance
|
||||
("Configuration",
|
||||
ConfigurationSpi.class,
|
||||
type,
|
||||
params);
|
||||
return new ConfigDelegate((ConfigurationSpi)instance.impl,
|
||||
instance.provider,
|
||||
type,
|
||||
params);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
return handleException (nsae);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Configuration object of the specified type.
|
||||
*
|
||||
* <p> A new Configuration object encapsulating the
|
||||
* ConfigurationSpi implementation from the specified provider
|
||||
* is returned. The specified provider must be registered
|
||||
* in the provider list.
|
||||
*
|
||||
* <p> Note that the list of registered providers may be retrieved via
|
||||
* the {@link Security#getProviders() Security.getProviders()} method.
|
||||
*
|
||||
* @param type the specified Configuration type. See the Configuration
|
||||
* section in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
|
||||
* Java Cryptography Architecture Standard Algorithm Name
|
||||
* Documentation</a> for a list of standard Configuration types.
|
||||
*
|
||||
* @param params parameters for the Configuration, which may be null.
|
||||
*
|
||||
* @param provider the provider.
|
||||
*
|
||||
* @return the new Configuration object.
|
||||
*
|
||||
* @exception SecurityException if the caller does not have permission
|
||||
* to get a Configuration instance for the specified type.
|
||||
*
|
||||
* @exception NullPointerException if the specified type is null.
|
||||
*
|
||||
* @exception IllegalArgumentException if the specified provider
|
||||
* is null or empty,
|
||||
* or if the specified parameters are not understood by
|
||||
* the ConfigurationSpi implementation from the specified provider.
|
||||
*
|
||||
* @exception NoSuchProviderException if the specified provider is not
|
||||
* registered in the security provider list.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if the specified provider does not
|
||||
* support a ConfigurationSpi implementation for the specified
|
||||
* type.
|
||||
*
|
||||
* @see Provider
|
||||
* @since 1.6
|
||||
*/
|
||||
public static Configuration getInstance(String type,
|
||||
Configuration.Parameters params,
|
||||
String provider)
|
||||
throws NoSuchProviderException, NoSuchAlgorithmException {
|
||||
|
||||
if (provider == null || provider.length() == 0) {
|
||||
throw new IllegalArgumentException("missing provider");
|
||||
}
|
||||
|
||||
checkPermission(type);
|
||||
try {
|
||||
GetInstance.Instance instance = GetInstance.getInstance
|
||||
("Configuration",
|
||||
ConfigurationSpi.class,
|
||||
type,
|
||||
params,
|
||||
provider);
|
||||
return new ConfigDelegate((ConfigurationSpi)instance.impl,
|
||||
instance.provider,
|
||||
type,
|
||||
params);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
return handleException (nsae);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Configuration object of the specified type.
|
||||
*
|
||||
* <p> A new Configuration object encapsulating the
|
||||
* ConfigurationSpi implementation from the specified Provider
|
||||
* object is returned. Note that the specified Provider object
|
||||
* does not have to be registered in the provider list.
|
||||
*
|
||||
* @param type the specified Configuration type. See the Configuration
|
||||
* section in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
|
||||
* Java Cryptography Architecture Standard Algorithm Name
|
||||
* Documentation</a> for a list of standard Configuration types.
|
||||
*
|
||||
* @param params parameters for the Configuration, which may be null.
|
||||
*
|
||||
* @param provider the Provider.
|
||||
*
|
||||
* @return the new Configuration object.
|
||||
*
|
||||
* @exception SecurityException if the caller does not have permission
|
||||
* to get a Configuration instance for the specified type.
|
||||
*
|
||||
* @exception NullPointerException if the specified type is null.
|
||||
*
|
||||
* @exception IllegalArgumentException if the specified Provider is null,
|
||||
* or if the specified parameters are not understood by
|
||||
* the ConfigurationSpi implementation from the specified Provider.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if the specified Provider does not
|
||||
* support a ConfigurationSpi implementation for the specified
|
||||
* type.
|
||||
*
|
||||
* @see Provider
|
||||
* @since 1.6
|
||||
*/
|
||||
public static Configuration getInstance(String type,
|
||||
Configuration.Parameters params,
|
||||
Provider provider)
|
||||
throws NoSuchAlgorithmException {
|
||||
|
||||
if (provider == null) {
|
||||
throw new IllegalArgumentException("missing provider");
|
||||
}
|
||||
|
||||
checkPermission(type);
|
||||
try {
|
||||
GetInstance.Instance instance = GetInstance.getInstance
|
||||
("Configuration",
|
||||
ConfigurationSpi.class,
|
||||
type,
|
||||
params,
|
||||
provider);
|
||||
return new ConfigDelegate((ConfigurationSpi)instance.impl,
|
||||
instance.provider,
|
||||
type,
|
||||
params);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
return handleException (nsae);
|
||||
}
|
||||
}
|
||||
|
||||
private static Configuration handleException(NoSuchAlgorithmException nsae)
|
||||
throws NoSuchAlgorithmException {
|
||||
Throwable cause = nsae.getCause();
|
||||
if (cause instanceof IllegalArgumentException) {
|
||||
throw (IllegalArgumentException)cause;
|
||||
}
|
||||
throw nsae;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Provider of this Configuration.
|
||||
*
|
||||
* <p> This Configuration instance will only have a Provider if it
|
||||
* was obtained via a call to {@code Configuration.getInstance}.
|
||||
* Otherwise this method returns null.
|
||||
*
|
||||
* @return the Provider of this Configuration, or null.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public Provider getProvider() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of this Configuration.
|
||||
*
|
||||
* <p> This Configuration instance will only have a type if it
|
||||
* was obtained via a call to {@code Configuration.getInstance}.
|
||||
* Otherwise this method returns null.
|
||||
*
|
||||
* @return the type of this Configuration, or null.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public String getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Configuration parameters.
|
||||
*
|
||||
* <p> This Configuration instance will only have parameters if it
|
||||
* was obtained via a call to {@code Configuration.getInstance}.
|
||||
* Otherwise this method returns null.
|
||||
*
|
||||
* @return Configuration parameters, or null.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public Configuration.Parameters getParameters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the AppConfigurationEntries for the specified <i>name</i>
|
||||
* from this Configuration.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param name the name used to index the Configuration.
|
||||
*
|
||||
* @return an array of AppConfigurationEntries for the specified <i>name</i>
|
||||
* from this Configuration, or null if there are no entries
|
||||
* for the specified <i>name</i>
|
||||
*/
|
||||
public abstract AppConfigurationEntry[] getAppConfigurationEntry
|
||||
(String name);
|
||||
|
||||
/**
|
||||
* Refresh and reload the Configuration.
|
||||
*
|
||||
* <p> This method causes this Configuration object to refresh/reload its
|
||||
* contents in an implementation-dependent manner.
|
||||
* For example, if this Configuration object stores its entries in a file,
|
||||
* calling {@code refresh} may cause the file to be re-read.
|
||||
*
|
||||
* <p> The default implementation of this method does nothing.
|
||||
* This method should be overridden if a refresh operation is supported
|
||||
* by the implementation.
|
||||
*
|
||||
* @exception SecurityException if the caller does not have permission
|
||||
* to refresh its Configuration.
|
||||
*/
|
||||
public void refresh() { }
|
||||
|
||||
/**
|
||||
* This subclass is returned by the getInstance calls. All Configuration
|
||||
* calls are delegated to the underlying ConfigurationSpi.
|
||||
*/
|
||||
private static class ConfigDelegate extends Configuration {
|
||||
|
||||
private ConfigurationSpi spi;
|
||||
private Provider p;
|
||||
private String type;
|
||||
private Configuration.Parameters params;
|
||||
|
||||
private ConfigDelegate(ConfigurationSpi spi, Provider p,
|
||||
String type, Configuration.Parameters params) {
|
||||
this.spi = spi;
|
||||
this.p = p;
|
||||
this.type = type;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public String getType() { return type; }
|
||||
|
||||
public Configuration.Parameters getParameters() { return params; }
|
||||
|
||||
public Provider getProvider() { return p; }
|
||||
|
||||
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
|
||||
return spi.engineGetAppConfigurationEntry(name);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
spi.engineRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a marker interface for Configuration parameters.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static interface Parameters { }
|
||||
}
|
||||
75
jdkSrc/jdk8/javax/security/auth/login/ConfigurationSpi.java
Normal file
75
jdkSrc/jdk8/javax/security/auth/login/ConfigurationSpi.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
/**
|
||||
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
|
||||
* for the {@code Configuration} class.
|
||||
* All the abstract methods in this class must be implemented by each
|
||||
* service provider who wishes to supply a Configuration implementation.
|
||||
*
|
||||
* <p> Subclass implementations of this abstract class must provide
|
||||
* a public constructor that takes a {@code Configuration.Parameters}
|
||||
* object as an input parameter. This constructor also must throw
|
||||
* an IllegalArgumentException if it does not understand the
|
||||
* {@code Configuration.Parameters} input.
|
||||
*
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public abstract class ConfigurationSpi {
|
||||
/**
|
||||
* Retrieve the AppConfigurationEntries for the specified <i>name</i>.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param name the name used to index the Configuration.
|
||||
*
|
||||
* @return an array of AppConfigurationEntries for the specified
|
||||
* <i>name</i>, or null if there are no entries.
|
||||
*/
|
||||
protected abstract AppConfigurationEntry[] engineGetAppConfigurationEntry
|
||||
(String name);
|
||||
|
||||
/**
|
||||
* Refresh and reload the Configuration.
|
||||
*
|
||||
* <p> This method causes this Configuration object to refresh/reload its
|
||||
* contents in an implementation-dependent manner.
|
||||
* For example, if this Configuration object stores its entries in a file,
|
||||
* calling {@code refresh} may cause the file to be re-read.
|
||||
*
|
||||
* <p> The default implementation of this method does nothing.
|
||||
* This method should be overridden if a refresh operation is supported
|
||||
* by the implementation.
|
||||
*
|
||||
* @exception SecurityException if the caller does not have permission
|
||||
* to refresh its Configuration.
|
||||
*/
|
||||
protected void engineRefresh() { }
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
/**
|
||||
* A generic credential exception.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class CredentialException extends LoginException {
|
||||
|
||||
private static final long serialVersionUID = -4772893876810601859L;
|
||||
|
||||
/**
|
||||
* Constructs a CredentialException with no detail message. A detail
|
||||
* message is a String that describes this particular exception.
|
||||
*/
|
||||
public CredentialException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a CredentialException with the specified detail message.
|
||||
* A detail message is a String that describes this particular
|
||||
* exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public CredentialException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
/**
|
||||
* Signals that a {@code Credential} has expired.
|
||||
*
|
||||
* <p> This exception is thrown by LoginModules when they determine
|
||||
* that a {@code Credential} has expired.
|
||||
* For example, a {@code LoginModule} authenticating a user
|
||||
* in its {@code login} method may determine that the user's
|
||||
* password, although entered correctly, has expired. In this case
|
||||
* the {@code LoginModule} throws this exception to notify
|
||||
* the application. The application can then take the appropriate
|
||||
* steps to assist the user in updating the password.
|
||||
*
|
||||
*/
|
||||
public class CredentialExpiredException extends CredentialException {
|
||||
|
||||
private static final long serialVersionUID = -5344739593859737937L;
|
||||
|
||||
/**
|
||||
* Constructs a CredentialExpiredException with no detail message. A detail
|
||||
* message is a String that describes this particular exception.
|
||||
*/
|
||||
public CredentialExpiredException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a CredentialExpiredException with the specified detail
|
||||
* message. A detail message is a String that describes this particular
|
||||
* exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public CredentialExpiredException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
/**
|
||||
* Signals that a credential was not found.
|
||||
*
|
||||
* <p> This exception may be thrown by a LoginModule if it is unable
|
||||
* to locate a credential necessary to perform authentication.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class CredentialNotFoundException extends CredentialException {
|
||||
|
||||
private static final long serialVersionUID = -7779934467214319475L;
|
||||
|
||||
/**
|
||||
* Constructs a CredentialNotFoundException with no detail message.
|
||||
* A detail message is a String that describes this particular exception.
|
||||
*/
|
||||
public CredentialNotFoundException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a CredentialNotFoundException with the specified
|
||||
* detail message. A detail message is a String that describes
|
||||
* this particular exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public CredentialNotFoundException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
/**
|
||||
* Signals that user authentication failed.
|
||||
*
|
||||
* <p> This exception is thrown by LoginModules if authentication failed.
|
||||
* For example, a {@code LoginModule} throws this exception if
|
||||
* the user entered an incorrect password.
|
||||
*
|
||||
*/
|
||||
public class FailedLoginException extends LoginException {
|
||||
|
||||
private static final long serialVersionUID = 802556922354616286L;
|
||||
|
||||
/**
|
||||
* Constructs a FailedLoginException with no detail message. A detail
|
||||
* message is a String that describes this particular exception.
|
||||
*/
|
||||
public FailedLoginException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a FailedLoginException with the specified detail
|
||||
* message. A detail message is a String that describes this particular
|
||||
* exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public FailedLoginException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
966
jdkSrc/jdk8/javax/security/auth/login/LoginContext.java
Normal file
966
jdkSrc/jdk8/javax/security/auth/login/LoginContext.java
Normal file
@@ -0,0 +1,966 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.text.MessageFormat;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.AuthPermission;
|
||||
import javax.security.auth.callback.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessControlContext;
|
||||
import sun.security.util.PendingException;
|
||||
import sun.security.util.ResourcesMgr;
|
||||
|
||||
/**
|
||||
* <p> The {@code LoginContext} class describes the basic methods used
|
||||
* to authenticate Subjects and provides a way to develop an
|
||||
* application independent of the underlying authentication technology.
|
||||
* A {@code Configuration} specifies the authentication technology, or
|
||||
* {@code LoginModule}, to be used with a particular application.
|
||||
* Different LoginModules can be plugged in under an application
|
||||
* without requiring any modifications to the application itself.
|
||||
*
|
||||
* <p> In addition to supporting <i>pluggable</i> authentication, this class
|
||||
* also supports the notion of <i>stacked</i> authentication.
|
||||
* Applications may be configured to use more than one
|
||||
* LoginModule. For example, one could
|
||||
* configure both a Kerberos LoginModule and a smart card
|
||||
* LoginModule under an application.
|
||||
*
|
||||
* <p> A typical caller instantiates a LoginContext with
|
||||
* a <i>name</i> and a {@code CallbackHandler}.
|
||||
* LoginContext uses the <i>name</i> as the index into a
|
||||
* Configuration to determine which LoginModules should be used,
|
||||
* and which ones must succeed in order for the overall authentication to
|
||||
* succeed. The {@code CallbackHandler} is passed to the underlying
|
||||
* LoginModules so they may communicate and interact with users
|
||||
* (prompting for a username and password via a graphical user interface,
|
||||
* for example).
|
||||
*
|
||||
* <p> Once the caller has instantiated a LoginContext,
|
||||
* it invokes the {@code login} method to authenticate
|
||||
* a {@code Subject}. The {@code login} method invokes
|
||||
* the configured modules to perform their respective types of authentication
|
||||
* (username/password, smart card pin verification, etc.).
|
||||
* Note that the LoginModules will not attempt authentication retries nor
|
||||
* introduce delays if the authentication fails.
|
||||
* Such tasks belong to the LoginContext caller.
|
||||
*
|
||||
* <p> If the {@code login} method returns without
|
||||
* throwing an exception, then the overall authentication succeeded.
|
||||
* The caller can then retrieve
|
||||
* the newly authenticated Subject by invoking the
|
||||
* {@code getSubject} method. Principals and Credentials associated
|
||||
* with the Subject may be retrieved by invoking the Subject's
|
||||
* respective {@code getPrincipals}, {@code getPublicCredentials},
|
||||
* and {@code getPrivateCredentials} methods.
|
||||
*
|
||||
* <p> To logout the Subject, the caller calls
|
||||
* the {@code logout} method. As with the {@code login}
|
||||
* method, this {@code logout} method invokes the {@code logout}
|
||||
* method for the configured modules.
|
||||
*
|
||||
* <p> A LoginContext should not be used to authenticate
|
||||
* more than one Subject. A separate LoginContext
|
||||
* should be used to authenticate each different Subject.
|
||||
*
|
||||
* <p> The following documentation applies to all LoginContext constructors:
|
||||
* <ol>
|
||||
*
|
||||
* <li> {@code Subject}
|
||||
* <ul>
|
||||
* <li> If the constructor has a Subject
|
||||
* input parameter, the LoginContext uses the caller-specified
|
||||
* Subject object.
|
||||
*
|
||||
* <li> If the caller specifies a {@code null} Subject
|
||||
* and a {@code null} value is permitted,
|
||||
* the LoginContext instantiates a new Subject.
|
||||
*
|
||||
* <li> If the constructor does <b>not</b> have a Subject
|
||||
* input parameter, the LoginContext instantiates a new Subject.
|
||||
* <p>
|
||||
* </ul>
|
||||
*
|
||||
* <li> {@code Configuration}
|
||||
* <ul>
|
||||
* <li> If the constructor has a Configuration
|
||||
* input parameter and the caller specifies a non-null Configuration,
|
||||
* the LoginContext uses the caller-specified Configuration.
|
||||
* <p>
|
||||
* If the constructor does <b>not</b> have a Configuration
|
||||
* input parameter, or if the caller specifies a {@code null}
|
||||
* Configuration object, the constructor uses the following call to
|
||||
* get the installed Configuration:
|
||||
* <pre>
|
||||
* config = Configuration.getConfiguration();
|
||||
* </pre>
|
||||
* For both cases,
|
||||
* the <i>name</i> argument given to the constructor is passed to the
|
||||
* {@code Configuration.getAppConfigurationEntry} method.
|
||||
* If the Configuration has no entries for the specified <i>name</i>,
|
||||
* then the {@code LoginContext} calls
|
||||
* {@code getAppConfigurationEntry} with the name, "<i>other</i>"
|
||||
* (the default entry name). If there is no entry for "<i>other</i>",
|
||||
* then a {@code LoginException} is thrown.
|
||||
*
|
||||
* <li> When LoginContext uses the installed Configuration, the caller
|
||||
* requires the createLoginContext.<em>name</em> and possibly
|
||||
* createLoginContext.other AuthPermissions. Furthermore, the
|
||||
* LoginContext will invoke configured modules from within an
|
||||
* {@code AccessController.doPrivileged} call so that modules that
|
||||
* perform security-sensitive tasks (such as connecting to remote hosts,
|
||||
* and updating the Subject) will require the respective permissions, but
|
||||
* the callers of the LoginContext will not require those permissions.
|
||||
*
|
||||
* <li> When LoginContext uses a caller-specified Configuration, the caller
|
||||
* does not require any createLoginContext AuthPermission. The LoginContext
|
||||
* saves the {@code AccessControlContext} for the caller,
|
||||
* and invokes the configured modules from within an
|
||||
* {@code AccessController.doPrivileged} call constrained by that context.
|
||||
* This means the caller context (stored when the LoginContext was created)
|
||||
* must have sufficient permissions to perform any security-sensitive tasks
|
||||
* that the modules may perform.
|
||||
* <p>
|
||||
* </ul>
|
||||
*
|
||||
* <li> {@code CallbackHandler}
|
||||
* <ul>
|
||||
* <li> If the constructor has a CallbackHandler
|
||||
* input parameter, the LoginContext uses the caller-specified
|
||||
* CallbackHandler object.
|
||||
*
|
||||
* <li> If the constructor does <b>not</b> have a CallbackHandler
|
||||
* input parameter, or if the caller specifies a {@code null}
|
||||
* CallbackHandler object (and a {@code null} value is permitted),
|
||||
* the LoginContext queries the
|
||||
* {@code auth.login.defaultCallbackHandler} security property for the
|
||||
* fully qualified class name of a default handler
|
||||
* implementation. If the security property is not set,
|
||||
* then the underlying modules will not have a
|
||||
* CallbackHandler for use in communicating
|
||||
* with users. The caller thus assumes that the configured
|
||||
* modules have alternative means for authenticating the user.
|
||||
*
|
||||
*
|
||||
* <li> When the LoginContext uses the installed Configuration (instead of
|
||||
* a caller-specified Configuration, see above),
|
||||
* then this LoginContext must wrap any
|
||||
* caller-specified or default CallbackHandler implementation
|
||||
* in a new CallbackHandler implementation
|
||||
* whose {@code handle} method implementation invokes the
|
||||
* specified CallbackHandler's {@code handle} method in a
|
||||
* {@code java.security.AccessController.doPrivileged} call
|
||||
* constrained by the caller's current {@code AccessControlContext}.
|
||||
* </ul>
|
||||
* </ol>
|
||||
*
|
||||
* @see java.security.Security
|
||||
* @see javax.security.auth.AuthPermission
|
||||
* @see javax.security.auth.Subject
|
||||
* @see javax.security.auth.callback.CallbackHandler
|
||||
* @see javax.security.auth.login.Configuration
|
||||
* @see javax.security.auth.spi.LoginModule
|
||||
* @see java.security.Security security properties
|
||||
*/
|
||||
public class LoginContext {
|
||||
|
||||
private static final String INIT_METHOD = "initialize";
|
||||
private static final String LOGIN_METHOD = "login";
|
||||
private static final String COMMIT_METHOD = "commit";
|
||||
private static final String ABORT_METHOD = "abort";
|
||||
private static final String LOGOUT_METHOD = "logout";
|
||||
private static final String OTHER = "other";
|
||||
private static final String DEFAULT_HANDLER =
|
||||
"auth.login.defaultCallbackHandler";
|
||||
private Subject subject = null;
|
||||
private boolean subjectProvided = false;
|
||||
private boolean loginSucceeded = false;
|
||||
private CallbackHandler callbackHandler;
|
||||
private Map<String,?> state = new HashMap<String,Object>();
|
||||
|
||||
private Configuration config;
|
||||
private AccessControlContext creatorAcc = null; // customized config only
|
||||
private ModuleInfo[] moduleStack;
|
||||
private ClassLoader contextClassLoader = null;
|
||||
private static final Class<?>[] PARAMS = { };
|
||||
|
||||
// state saved in the event a user-specified asynchronous exception
|
||||
// was specified and thrown
|
||||
|
||||
private int moduleIndex = 0;
|
||||
private LoginException firstError = null;
|
||||
private LoginException firstRequiredError = null;
|
||||
private boolean success = false;
|
||||
|
||||
private static final sun.security.util.Debug debug =
|
||||
sun.security.util.Debug.getInstance("logincontext", "\t[LoginContext]");
|
||||
|
||||
private void init(String name) throws LoginException {
|
||||
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null && creatorAcc == null) {
|
||||
sm.checkPermission(new AuthPermission
|
||||
("createLoginContext." + name));
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
throw new LoginException
|
||||
(ResourcesMgr.getString("Invalid.null.input.name"));
|
||||
|
||||
// get the Configuration
|
||||
if (config == null) {
|
||||
config = java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedAction<Configuration>() {
|
||||
public Configuration run() {
|
||||
return Configuration.getConfiguration();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// get the LoginModules configured for this application
|
||||
AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name);
|
||||
if (entries == null) {
|
||||
|
||||
if (sm != null && creatorAcc == null) {
|
||||
sm.checkPermission(new AuthPermission
|
||||
("createLoginContext." + OTHER));
|
||||
}
|
||||
|
||||
entries = config.getAppConfigurationEntry(OTHER);
|
||||
if (entries == null) {
|
||||
MessageFormat form = new MessageFormat(ResourcesMgr.getString
|
||||
("No.LoginModules.configured.for.name"));
|
||||
Object[] source = {name};
|
||||
throw new LoginException(form.format(source));
|
||||
}
|
||||
}
|
||||
moduleStack = new ModuleInfo[entries.length];
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
// clone returned array
|
||||
moduleStack[i] = new ModuleInfo
|
||||
(new AppConfigurationEntry
|
||||
(entries[i].getLoginModuleName(),
|
||||
entries[i].getControlFlag(),
|
||||
entries[i].getOptions()),
|
||||
null);
|
||||
}
|
||||
|
||||
contextClassLoader = java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedAction<ClassLoader>() {
|
||||
public ClassLoader run() {
|
||||
ClassLoader loader =
|
||||
Thread.currentThread().getContextClassLoader();
|
||||
if (loader == null) {
|
||||
// Don't use bootstrap class loader directly to ensure
|
||||
// proper package access control!
|
||||
loader = ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
|
||||
return loader;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadDefaultCallbackHandler() throws LoginException {
|
||||
|
||||
// get the default handler class
|
||||
try {
|
||||
|
||||
final ClassLoader finalLoader = contextClassLoader;
|
||||
|
||||
this.callbackHandler = java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedExceptionAction<CallbackHandler>() {
|
||||
public CallbackHandler run() throws Exception {
|
||||
String defaultHandler = java.security.Security.getProperty
|
||||
(DEFAULT_HANDLER);
|
||||
if (defaultHandler == null || defaultHandler.length() == 0)
|
||||
return null;
|
||||
Class<? extends CallbackHandler> c = Class.forName(
|
||||
defaultHandler, true,
|
||||
finalLoader).asSubclass(CallbackHandler.class);
|
||||
return c.newInstance();
|
||||
}
|
||||
});
|
||||
} catch (java.security.PrivilegedActionException pae) {
|
||||
throw new LoginException(pae.getException().toString());
|
||||
}
|
||||
|
||||
// secure it with the caller's ACC
|
||||
if (this.callbackHandler != null && creatorAcc == null) {
|
||||
this.callbackHandler = new SecureCallbackHandler
|
||||
(java.security.AccessController.getContext(),
|
||||
this.callbackHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new {@code LoginContext} object with a name.
|
||||
*
|
||||
* @param name the name used as the index into the
|
||||
* {@code Configuration}.
|
||||
*
|
||||
* @exception LoginException if the caller-specified {@code name}
|
||||
* does not appear in the {@code Configuration}
|
||||
* and there is no {@code Configuration} entry
|
||||
* for "<i>other</i>", or if the
|
||||
* <i>auth.login.defaultCallbackHandler</i>
|
||||
* security property was set, but the implementation
|
||||
* class could not be loaded.
|
||||
* <p>
|
||||
* @exception SecurityException if a SecurityManager is set and
|
||||
* the caller does not have
|
||||
* AuthPermission("createLoginContext.<i>name</i>"),
|
||||
* or if a configuration entry for <i>name</i> does not exist and
|
||||
* the caller does not additionally have
|
||||
* AuthPermission("createLoginContext.other")
|
||||
*/
|
||||
public LoginContext(String name) throws LoginException {
|
||||
init(name);
|
||||
loadDefaultCallbackHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new {@code LoginContext} object with a name
|
||||
* and a {@code Subject} object.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param name the name used as the index into the
|
||||
* {@code Configuration}. <p>
|
||||
*
|
||||
* @param subject the {@code Subject} to authenticate.
|
||||
*
|
||||
* @exception LoginException if the caller-specified {@code name}
|
||||
* does not appear in the {@code Configuration}
|
||||
* and there is no {@code Configuration} entry
|
||||
* for "<i>other</i>", if the caller-specified {@code subject}
|
||||
* is {@code null}, or if the
|
||||
* <i>auth.login.defaultCallbackHandler</i>
|
||||
* security property was set, but the implementation
|
||||
* class could not be loaded.
|
||||
* <p>
|
||||
* @exception SecurityException if a SecurityManager is set and
|
||||
* the caller does not have
|
||||
* AuthPermission("createLoginContext.<i>name</i>"),
|
||||
* or if a configuration entry for <i>name</i> does not exist and
|
||||
* the caller does not additionally have
|
||||
* AuthPermission("createLoginContext.other")
|
||||
*/
|
||||
public LoginContext(String name, Subject subject)
|
||||
throws LoginException {
|
||||
init(name);
|
||||
if (subject == null)
|
||||
throw new LoginException
|
||||
(ResourcesMgr.getString("invalid.null.Subject.provided"));
|
||||
this.subject = subject;
|
||||
subjectProvided = true;
|
||||
loadDefaultCallbackHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new {@code LoginContext} object with a name
|
||||
* and a {@code CallbackHandler} object.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param name the name used as the index into the
|
||||
* {@code Configuration}. <p>
|
||||
*
|
||||
* @param callbackHandler the {@code CallbackHandler} object used by
|
||||
* LoginModules to communicate with the user.
|
||||
*
|
||||
* @exception LoginException if the caller-specified {@code name}
|
||||
* does not appear in the {@code Configuration}
|
||||
* and there is no {@code Configuration} entry
|
||||
* for "<i>other</i>", or if the caller-specified
|
||||
* {@code callbackHandler} is {@code null}.
|
||||
* <p>
|
||||
* @exception SecurityException if a SecurityManager is set and
|
||||
* the caller does not have
|
||||
* AuthPermission("createLoginContext.<i>name</i>"),
|
||||
* or if a configuration entry for <i>name</i> does not exist and
|
||||
* the caller does not additionally have
|
||||
* AuthPermission("createLoginContext.other")
|
||||
*/
|
||||
public LoginContext(String name, CallbackHandler callbackHandler)
|
||||
throws LoginException {
|
||||
init(name);
|
||||
if (callbackHandler == null)
|
||||
throw new LoginException(ResourcesMgr.getString
|
||||
("invalid.null.CallbackHandler.provided"));
|
||||
this.callbackHandler = new SecureCallbackHandler
|
||||
(java.security.AccessController.getContext(),
|
||||
callbackHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new {@code LoginContext} object with a name,
|
||||
* a {@code Subject} to be authenticated, and a
|
||||
* {@code CallbackHandler} object.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param name the name used as the index into the
|
||||
* {@code Configuration}. <p>
|
||||
*
|
||||
* @param subject the {@code Subject} to authenticate. <p>
|
||||
*
|
||||
* @param callbackHandler the {@code CallbackHandler} object used by
|
||||
* LoginModules to communicate with the user.
|
||||
*
|
||||
* @exception LoginException if the caller-specified {@code name}
|
||||
* does not appear in the {@code Configuration}
|
||||
* and there is no {@code Configuration} entry
|
||||
* for "<i>other</i>", or if the caller-specified
|
||||
* {@code subject} is {@code null},
|
||||
* or if the caller-specified
|
||||
* {@code callbackHandler} is {@code null}.
|
||||
* <p>
|
||||
* @exception SecurityException if a SecurityManager is set and
|
||||
* the caller does not have
|
||||
* AuthPermission("createLoginContext.<i>name</i>"),
|
||||
* or if a configuration entry for <i>name</i> does not exist and
|
||||
* the caller does not additionally have
|
||||
* AuthPermission("createLoginContext.other")
|
||||
*/
|
||||
public LoginContext(String name, Subject subject,
|
||||
CallbackHandler callbackHandler) throws LoginException {
|
||||
this(name, subject);
|
||||
if (callbackHandler == null)
|
||||
throw new LoginException(ResourcesMgr.getString
|
||||
("invalid.null.CallbackHandler.provided"));
|
||||
this.callbackHandler = new SecureCallbackHandler
|
||||
(java.security.AccessController.getContext(),
|
||||
callbackHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new {@code LoginContext} object with a name,
|
||||
* a {@code Subject} to be authenticated,
|
||||
* a {@code CallbackHandler} object, and a login
|
||||
* {@code Configuration}.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param name the name used as the index into the caller-specified
|
||||
* {@code Configuration}. <p>
|
||||
*
|
||||
* @param subject the {@code Subject} to authenticate,
|
||||
* or {@code null}. <p>
|
||||
*
|
||||
* @param callbackHandler the {@code CallbackHandler} object used by
|
||||
* LoginModules to communicate with the user, or {@code null}.
|
||||
* <p>
|
||||
*
|
||||
* @param config the {@code Configuration} that lists the
|
||||
* login modules to be called to perform the authentication,
|
||||
* or {@code null}.
|
||||
*
|
||||
* @exception LoginException if the caller-specified {@code name}
|
||||
* does not appear in the {@code Configuration}
|
||||
* and there is no {@code Configuration} entry
|
||||
* for "<i>other</i>".
|
||||
* <p>
|
||||
* @exception SecurityException if a SecurityManager is set,
|
||||
* <i>config</i> is {@code null},
|
||||
* and either the caller does not have
|
||||
* AuthPermission("createLoginContext.<i>name</i>"),
|
||||
* or if a configuration entry for <i>name</i> does not exist and
|
||||
* the caller does not additionally have
|
||||
* AuthPermission("createLoginContext.other")
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public LoginContext(String name, Subject subject,
|
||||
CallbackHandler callbackHandler,
|
||||
Configuration config) throws LoginException {
|
||||
this.config = config;
|
||||
if (config != null) {
|
||||
creatorAcc = java.security.AccessController.getContext();
|
||||
}
|
||||
|
||||
init(name);
|
||||
if (subject != null) {
|
||||
this.subject = subject;
|
||||
subjectProvided = true;
|
||||
}
|
||||
if (callbackHandler == null) {
|
||||
loadDefaultCallbackHandler();
|
||||
} else if (creatorAcc == null) {
|
||||
this.callbackHandler = new SecureCallbackHandler
|
||||
(java.security.AccessController.getContext(),
|
||||
callbackHandler);
|
||||
} else {
|
||||
this.callbackHandler = callbackHandler;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the authentication.
|
||||
*
|
||||
* <p> This method invokes the {@code login} method for each
|
||||
* LoginModule configured for the <i>name</i> specified to the
|
||||
* {@code LoginContext} constructor, as determined by the login
|
||||
* {@code Configuration}. Each {@code LoginModule}
|
||||
* then performs its respective type of authentication
|
||||
* (username/password, smart card pin verification, etc.).
|
||||
*
|
||||
* <p> This method completes a 2-phase authentication process by
|
||||
* calling each configured LoginModule's {@code commit} method
|
||||
* if the overall authentication succeeded (the relevant REQUIRED,
|
||||
* REQUISITE, SUFFICIENT, and OPTIONAL LoginModules succeeded),
|
||||
* or by calling each configured LoginModule's {@code abort} method
|
||||
* if the overall authentication failed. If authentication succeeded,
|
||||
* each successful LoginModule's {@code commit} method associates
|
||||
* the relevant Principals and Credentials with the {@code Subject}.
|
||||
* If authentication failed, each LoginModule's {@code abort} method
|
||||
* removes/destroys any previously stored state.
|
||||
*
|
||||
* <p> If the {@code commit} phase of the authentication process
|
||||
* fails, then the overall authentication fails and this method
|
||||
* invokes the {@code abort} method for each configured
|
||||
* {@code LoginModule}.
|
||||
*
|
||||
* <p> If the {@code abort} phase
|
||||
* fails for any reason, then this method propagates the
|
||||
* original exception thrown either during the {@code login} phase
|
||||
* or the {@code commit} phase. In either case, the overall
|
||||
* authentication fails.
|
||||
*
|
||||
* <p> In the case where multiple LoginModules fail,
|
||||
* this method propagates the exception raised by the first
|
||||
* {@code LoginModule} which failed.
|
||||
*
|
||||
* <p> Note that if this method enters the {@code abort} phase
|
||||
* (either the {@code login} or {@code commit} phase failed),
|
||||
* this method invokes all LoginModules configured for the
|
||||
* application regardless of their respective {@code Configuration}
|
||||
* flag parameters. Essentially this means that {@code Requisite}
|
||||
* and {@code Sufficient} semantics are ignored during the
|
||||
* {@code abort} phase. This guarantees that proper cleanup
|
||||
* and state restoration can take place.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @exception LoginException if the authentication fails.
|
||||
*/
|
||||
public void login() throws LoginException {
|
||||
|
||||
loginSucceeded = false;
|
||||
|
||||
if (subject == null) {
|
||||
subject = new Subject();
|
||||
}
|
||||
|
||||
try {
|
||||
// module invoked in doPrivileged
|
||||
invokePriv(LOGIN_METHOD);
|
||||
invokePriv(COMMIT_METHOD);
|
||||
loginSucceeded = true;
|
||||
} catch (LoginException le) {
|
||||
try {
|
||||
invokePriv(ABORT_METHOD);
|
||||
} catch (LoginException le2) {
|
||||
throw le;
|
||||
}
|
||||
throw le;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout the {@code Subject}.
|
||||
*
|
||||
* <p> This method invokes the {@code logout} method for each
|
||||
* {@code LoginModule} configured for this {@code LoginContext}.
|
||||
* Each {@code LoginModule} performs its respective logout procedure
|
||||
* which may include removing/destroying
|
||||
* {@code Principal} and {@code Credential} information
|
||||
* from the {@code Subject} and state cleanup.
|
||||
*
|
||||
* <p> Note that this method invokes all LoginModules configured for the
|
||||
* application regardless of their respective
|
||||
* {@code Configuration} flag parameters. Essentially this means
|
||||
* that {@code Requisite} and {@code Sufficient} semantics are
|
||||
* ignored for this method. This guarantees that proper cleanup
|
||||
* and state restoration can take place.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @exception LoginException if the logout fails.
|
||||
*/
|
||||
public void logout() throws LoginException {
|
||||
if (subject == null) {
|
||||
throw new LoginException(ResourcesMgr.getString
|
||||
("null.subject.logout.called.before.login"));
|
||||
}
|
||||
|
||||
// module invoked in doPrivileged
|
||||
invokePriv(LOGOUT_METHOD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the authenticated Subject.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the authenticated Subject. If the caller specified a
|
||||
* Subject to this LoginContext's constructor,
|
||||
* this method returns the caller-specified Subject.
|
||||
* If a Subject was not specified and authentication succeeds,
|
||||
* this method returns the Subject instantiated and used for
|
||||
* authentication by this LoginContext.
|
||||
* If a Subject was not specified, and authentication fails or
|
||||
* has not been attempted, this method returns null.
|
||||
*/
|
||||
public Subject getSubject() {
|
||||
if (!loginSucceeded && !subjectProvided)
|
||||
return null;
|
||||
return subject;
|
||||
}
|
||||
|
||||
private void clearState() {
|
||||
moduleIndex = 0;
|
||||
firstError = null;
|
||||
firstRequiredError = null;
|
||||
success = false;
|
||||
}
|
||||
|
||||
private void throwException(LoginException originalError, LoginException le)
|
||||
throws LoginException {
|
||||
|
||||
// first clear state
|
||||
clearState();
|
||||
|
||||
// throw the exception
|
||||
LoginException error = (originalError != null) ? originalError : le;
|
||||
throw error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the login, commit, and logout methods
|
||||
* from a LoginModule inside a doPrivileged block restricted
|
||||
* by creatorAcc (may be null).
|
||||
*
|
||||
* This version is called if the caller did not instantiate
|
||||
* the LoginContext with a Configuration object.
|
||||
*/
|
||||
private void invokePriv(final String methodName) throws LoginException {
|
||||
try {
|
||||
java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws LoginException {
|
||||
invoke(methodName);
|
||||
return null;
|
||||
}
|
||||
}, creatorAcc);
|
||||
} catch (java.security.PrivilegedActionException pae) {
|
||||
throw (LoginException)pae.getException();
|
||||
}
|
||||
}
|
||||
|
||||
private void invoke(String methodName) throws LoginException {
|
||||
|
||||
// start at moduleIndex
|
||||
// - this can only be non-zero if methodName is LOGIN_METHOD
|
||||
|
||||
for (int i = moduleIndex; i < moduleStack.length; i++, moduleIndex++) {
|
||||
try {
|
||||
|
||||
int mIndex = 0;
|
||||
Method[] methods = null;
|
||||
|
||||
if (moduleStack[i].module != null) {
|
||||
methods = moduleStack[i].module.getClass().getMethods();
|
||||
} else {
|
||||
|
||||
// instantiate the LoginModule
|
||||
//
|
||||
// Allow any object to be a LoginModule as long as it
|
||||
// conforms to the interface.
|
||||
Class<?> c = Class.forName(
|
||||
moduleStack[i].entry.getLoginModuleName(),
|
||||
true,
|
||||
contextClassLoader);
|
||||
|
||||
Constructor<?> constructor = c.getConstructor(PARAMS);
|
||||
Object[] args = { };
|
||||
moduleStack[i].module = constructor.newInstance(args);
|
||||
|
||||
// call the LoginModule's initialize method
|
||||
methods = moduleStack[i].module.getClass().getMethods();
|
||||
for (mIndex = 0; mIndex < methods.length; mIndex++) {
|
||||
if (methods[mIndex].getName().equals(INIT_METHOD)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Object[] initArgs = {subject,
|
||||
callbackHandler,
|
||||
state,
|
||||
moduleStack[i].entry.getOptions() };
|
||||
// invoke the LoginModule initialize method
|
||||
//
|
||||
// Throws ArrayIndexOutOfBoundsException if no such
|
||||
// method defined. May improve to use LoginException in
|
||||
// the future.
|
||||
methods[mIndex].invoke(moduleStack[i].module, initArgs);
|
||||
}
|
||||
|
||||
// find the requested method in the LoginModule
|
||||
for (mIndex = 0; mIndex < methods.length; mIndex++) {
|
||||
if (methods[mIndex].getName().equals(methodName)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// set up the arguments to be passed to the LoginModule method
|
||||
Object[] args = { };
|
||||
|
||||
// invoke the LoginModule method
|
||||
//
|
||||
// Throws ArrayIndexOutOfBoundsException if no such
|
||||
// method defined. May improve to use LoginException in
|
||||
// the future.
|
||||
boolean status = ((Boolean)methods[mIndex].invoke
|
||||
(moduleStack[i].module, args)).booleanValue();
|
||||
|
||||
if (status == true) {
|
||||
|
||||
// if SUFFICIENT, return if no prior REQUIRED errors
|
||||
if (!methodName.equals(ABORT_METHOD) &&
|
||||
!methodName.equals(LOGOUT_METHOD) &&
|
||||
moduleStack[i].entry.getControlFlag() ==
|
||||
AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT &&
|
||||
firstRequiredError == null) {
|
||||
|
||||
// clear state
|
||||
clearState();
|
||||
|
||||
if (debug != null)
|
||||
debug.println(methodName + " SUFFICIENT success");
|
||||
return;
|
||||
}
|
||||
|
||||
if (debug != null)
|
||||
debug.println(methodName + " success");
|
||||
success = true;
|
||||
} else {
|
||||
if (debug != null)
|
||||
debug.println(methodName + " ignored");
|
||||
}
|
||||
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
MessageFormat form = new MessageFormat(ResourcesMgr.getString
|
||||
("unable.to.instantiate.LoginModule.module.because.it.does.not.provide.a.no.argument.constructor"));
|
||||
Object[] source = {moduleStack[i].entry.getLoginModuleName()};
|
||||
throwException(null, new LoginException(form.format(source)));
|
||||
} catch (InstantiationException ie) {
|
||||
throwException(null, new LoginException(ResourcesMgr.getString
|
||||
("unable.to.instantiate.LoginModule.") +
|
||||
ie.getMessage()));
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
throwException(null, new LoginException(ResourcesMgr.getString
|
||||
("unable.to.find.LoginModule.class.") +
|
||||
cnfe.getMessage()));
|
||||
} catch (IllegalAccessException iae) {
|
||||
throwException(null, new LoginException(ResourcesMgr.getString
|
||||
("unable.to.access.LoginModule.") +
|
||||
iae.getMessage()));
|
||||
} catch (InvocationTargetException ite) {
|
||||
|
||||
// failure cases
|
||||
|
||||
LoginException le;
|
||||
|
||||
if (ite.getCause() instanceof PendingException &&
|
||||
methodName.equals(LOGIN_METHOD)) {
|
||||
|
||||
// XXX
|
||||
//
|
||||
// if a module's LOGIN_METHOD threw a PendingException
|
||||
// then immediately throw it.
|
||||
//
|
||||
// when LoginContext is called again,
|
||||
// the module that threw the exception is invoked first
|
||||
// (the module list is not invoked from the start).
|
||||
// previously thrown exception state is still present.
|
||||
//
|
||||
// it is assumed that the module which threw
|
||||
// the exception can have its
|
||||
// LOGIN_METHOD invoked twice in a row
|
||||
// without any commit/abort in between.
|
||||
//
|
||||
// in all cases when LoginContext returns
|
||||
// (either via natural return or by throwing an exception)
|
||||
// we need to call clearState before returning.
|
||||
// the only time that is not true is in this case -
|
||||
// do not call throwException here.
|
||||
|
||||
throw (PendingException)ite.getCause();
|
||||
|
||||
} else if (ite.getCause() instanceof LoginException) {
|
||||
|
||||
le = (LoginException)ite.getCause();
|
||||
|
||||
} else if (ite.getCause() instanceof SecurityException) {
|
||||
|
||||
// do not want privacy leak
|
||||
// (e.g., sensitive file path in exception msg)
|
||||
|
||||
le = new LoginException("Security Exception");
|
||||
le.initCause(new SecurityException());
|
||||
if (debug != null) {
|
||||
debug.println
|
||||
("original security exception with detail msg " +
|
||||
"replaced by new exception with empty detail msg");
|
||||
debug.println("original security exception: " +
|
||||
ite.getCause().toString());
|
||||
}
|
||||
} else {
|
||||
|
||||
// capture an unexpected LoginModule exception
|
||||
java.io.StringWriter sw = new java.io.StringWriter();
|
||||
ite.getCause().printStackTrace
|
||||
(new java.io.PrintWriter(sw));
|
||||
sw.flush();
|
||||
le = new LoginException(sw.toString());
|
||||
}
|
||||
|
||||
if (moduleStack[i].entry.getControlFlag() ==
|
||||
AppConfigurationEntry.LoginModuleControlFlag.REQUISITE) {
|
||||
|
||||
if (debug != null)
|
||||
debug.println(methodName + " REQUISITE failure");
|
||||
|
||||
// if REQUISITE, then immediately throw an exception
|
||||
if (methodName.equals(ABORT_METHOD) ||
|
||||
methodName.equals(LOGOUT_METHOD)) {
|
||||
if (firstRequiredError == null)
|
||||
firstRequiredError = le;
|
||||
} else {
|
||||
throwException(firstRequiredError, le);
|
||||
}
|
||||
|
||||
} else if (moduleStack[i].entry.getControlFlag() ==
|
||||
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED) {
|
||||
|
||||
if (debug != null)
|
||||
debug.println(methodName + " REQUIRED failure");
|
||||
|
||||
// mark down that a REQUIRED module failed
|
||||
if (firstRequiredError == null)
|
||||
firstRequiredError = le;
|
||||
|
||||
} else {
|
||||
|
||||
if (debug != null)
|
||||
debug.println(methodName + " OPTIONAL failure");
|
||||
|
||||
// mark down that an OPTIONAL module failed
|
||||
if (firstError == null)
|
||||
firstError = le;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we went thru all the LoginModules.
|
||||
if (firstRequiredError != null) {
|
||||
// a REQUIRED module failed -- return the error
|
||||
throwException(firstRequiredError, null);
|
||||
} else if (success == false && firstError != null) {
|
||||
// no module succeeded -- return the first error
|
||||
throwException(firstError, null);
|
||||
} else if (success == false) {
|
||||
// no module succeeded -- all modules were IGNORED
|
||||
throwException(new LoginException
|
||||
(ResourcesMgr.getString("Login.Failure.all.modules.ignored")),
|
||||
null);
|
||||
} else {
|
||||
// success
|
||||
|
||||
clearState();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the caller-specified CallbackHandler in our own
|
||||
* and invoke it within a privileged block, constrained by
|
||||
* the caller's AccessControlContext.
|
||||
*/
|
||||
private static class SecureCallbackHandler implements CallbackHandler {
|
||||
|
||||
private final java.security.AccessControlContext acc;
|
||||
private final CallbackHandler ch;
|
||||
|
||||
SecureCallbackHandler(java.security.AccessControlContext acc,
|
||||
CallbackHandler ch) {
|
||||
this.acc = acc;
|
||||
this.ch = ch;
|
||||
}
|
||||
|
||||
public void handle(final Callback[] callbacks)
|
||||
throws java.io.IOException, UnsupportedCallbackException {
|
||||
try {
|
||||
java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws java.io.IOException,
|
||||
UnsupportedCallbackException {
|
||||
ch.handle(callbacks);
|
||||
return null;
|
||||
}
|
||||
}, acc);
|
||||
} catch (java.security.PrivilegedActionException pae) {
|
||||
if (pae.getException() instanceof java.io.IOException) {
|
||||
throw (java.io.IOException)pae.getException();
|
||||
} else {
|
||||
throw (UnsupportedCallbackException)pae.getException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LoginModule information -
|
||||
* incapsulates Configuration info and actual module instances
|
||||
*/
|
||||
private static class ModuleInfo {
|
||||
AppConfigurationEntry entry;
|
||||
Object module;
|
||||
|
||||
ModuleInfo(AppConfigurationEntry newEntry, Object newModule) {
|
||||
this.entry = newEntry;
|
||||
this.module = newModule;
|
||||
}
|
||||
}
|
||||
}
|
||||
58
jdkSrc/jdk8/javax/security/auth/login/LoginException.java
Normal file
58
jdkSrc/jdk8/javax/security/auth/login/LoginException.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.login;
|
||||
|
||||
/**
|
||||
* This is the basic login exception.
|
||||
*
|
||||
* @see javax.security.auth.login.LoginContext
|
||||
*/
|
||||
|
||||
public class LoginException extends java.security.GeneralSecurityException {
|
||||
|
||||
private static final long serialVersionUID = -4679091624035232488L;
|
||||
|
||||
/**
|
||||
* Constructs a LoginException with no detail message. A detail
|
||||
* message is a String that describes this particular exception.
|
||||
*/
|
||||
public LoginException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a LoginException with the specified detail message.
|
||||
* A detail message is a String that describes this particular
|
||||
* exception.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public LoginException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
39
jdkSrc/jdk8/javax/security/auth/login/package-info.java
Normal file
39
jdkSrc/jdk8/javax/security/auth/login/package-info.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This package provides a pluggable authentication framework.
|
||||
* <h2>Package Specification</h2>
|
||||
*
|
||||
* <ul>
|
||||
* <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
|
||||
* <b>Java™
|
||||
* Cryptography Architecture Standard Algorithm Name
|
||||
* Documentation</b></a></li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
package javax.security.auth.login;
|
||||
38
jdkSrc/jdk8/javax/security/auth/package-info.java
Normal file
38
jdkSrc/jdk8/javax/security/auth/package-info.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This package provides a framework for authentication and
|
||||
* authorization. The framework allows
|
||||
* authentication to be performed in pluggable fashion. Different
|
||||
* authentication modules can be plugged under an application without
|
||||
* requiring modifications to the application itself. The
|
||||
* authorization component allows specification of access controls
|
||||
* based on code location, code signers and code executors
|
||||
* (Subjects).
|
||||
*
|
||||
* @since JDK1.4
|
||||
*/
|
||||
package javax.security.auth;
|
||||
240
jdkSrc/jdk8/javax/security/auth/spi/LoginModule.java
Normal file
240
jdkSrc/jdk8/javax/security/auth/spi/LoginModule.java
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.spi;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.AuthPermission;
|
||||
import javax.security.auth.callback.*;
|
||||
import javax.security.auth.login.*;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p> {@code LoginModule} describes the interface
|
||||
* implemented by authentication technology providers. LoginModules
|
||||
* are plugged in under applications to provide a particular type of
|
||||
* authentication.
|
||||
*
|
||||
* <p> While applications write to the {@code LoginContext} API,
|
||||
* authentication technology providers implement the
|
||||
* {@code LoginModule} interface.
|
||||
* A {@code Configuration} specifies the LoginModule(s)
|
||||
* to be used with a particular login application. Therefore different
|
||||
* LoginModules can be plugged in under the application without
|
||||
* requiring any modifications to the application itself.
|
||||
*
|
||||
* <p> The {@code LoginContext} is responsible for reading the
|
||||
* {@code Configuration} and instantiating the appropriate
|
||||
* LoginModules. Each {@code LoginModule} is initialized with
|
||||
* a {@code Subject}, a {@code CallbackHandler}, shared
|
||||
* {@code LoginModule} state, and LoginModule-specific options.
|
||||
*
|
||||
* The {@code Subject} represents the
|
||||
* {@code Subject} currently being authenticated and is updated
|
||||
* with relevant Credentials if authentication succeeds.
|
||||
* LoginModules use the {@code CallbackHandler} to
|
||||
* communicate with users. The {@code CallbackHandler} may be
|
||||
* used to prompt for usernames and passwords, for example.
|
||||
* Note that the {@code CallbackHandler} may be null. LoginModules
|
||||
* which absolutely require a {@code CallbackHandler} to authenticate
|
||||
* the {@code Subject} may throw a {@code LoginException}.
|
||||
* LoginModules optionally use the shared state to share information
|
||||
* or data among themselves.
|
||||
*
|
||||
* <p> The LoginModule-specific options represent the options
|
||||
* configured for this {@code LoginModule} by an administrator or user
|
||||
* in the login {@code Configuration}.
|
||||
* The options are defined by the {@code LoginModule} itself
|
||||
* and control the behavior within it. For example, a
|
||||
* {@code LoginModule} may define options to support debugging/testing
|
||||
* capabilities. Options are defined using a key-value syntax,
|
||||
* such as <i>debug=true</i>. The {@code LoginModule}
|
||||
* stores the options as a {@code Map} so that the values may
|
||||
* be retrieved using the key. Note that there is no limit to the number
|
||||
* of options a {@code LoginModule} chooses to define.
|
||||
*
|
||||
* <p> The calling application sees the authentication process as a single
|
||||
* operation. However, the authentication process within the
|
||||
* {@code LoginModule} proceeds in two distinct phases.
|
||||
* In the first phase, the LoginModule's
|
||||
* {@code login} method gets invoked by the LoginContext's
|
||||
* {@code login} method. The {@code login}
|
||||
* method for the {@code LoginModule} then performs
|
||||
* the actual authentication (prompt for and verify a password for example)
|
||||
* and saves its authentication status as private state
|
||||
* information. Once finished, the LoginModule's {@code login}
|
||||
* method either returns {@code true} (if it succeeded) or
|
||||
* {@code false} (if it should be ignored), or throws a
|
||||
* {@code LoginException} to specify a failure.
|
||||
* In the failure case, the {@code LoginModule} must not retry the
|
||||
* authentication or introduce delays. The responsibility of such tasks
|
||||
* belongs to the application. If the application attempts to retry
|
||||
* the authentication, the LoginModule's {@code login} method will be
|
||||
* called again.
|
||||
*
|
||||
* <p> In the second phase, if the LoginContext's overall authentication
|
||||
* succeeded (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL
|
||||
* LoginModules succeeded), then the {@code commit}
|
||||
* method for the {@code LoginModule} gets invoked.
|
||||
* The {@code commit} method for a {@code LoginModule} checks its
|
||||
* privately saved state to see if its own authentication succeeded.
|
||||
* If the overall {@code LoginContext} authentication succeeded
|
||||
* and the LoginModule's own authentication succeeded, then the
|
||||
* {@code commit} method associates the relevant
|
||||
* Principals (authenticated identities) and Credentials (authentication data
|
||||
* such as cryptographic keys) with the {@code Subject}
|
||||
* located within the {@code LoginModule}.
|
||||
*
|
||||
* <p> If the LoginContext's overall authentication failed (the relevant
|
||||
* REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules did not succeed),
|
||||
* then the {@code abort} method for each {@code LoginModule}
|
||||
* gets invoked. In this case, the {@code LoginModule} removes/destroys
|
||||
* any authentication state originally saved.
|
||||
*
|
||||
* <p> Logging out a {@code Subject} involves only one phase.
|
||||
* The {@code LoginContext} invokes the LoginModule's {@code logout}
|
||||
* method. The {@code logout} method for the {@code LoginModule}
|
||||
* then performs the logout procedures, such as removing Principals or
|
||||
* Credentials from the {@code Subject} or logging session information.
|
||||
*
|
||||
* <p> A {@code LoginModule} implementation must have a constructor with
|
||||
* no arguments. This allows classes which load the {@code LoginModule}
|
||||
* to instantiate it.
|
||||
*
|
||||
* @see javax.security.auth.login.LoginContext
|
||||
* @see javax.security.auth.login.Configuration
|
||||
*/
|
||||
public interface LoginModule {
|
||||
|
||||
/**
|
||||
* Initialize this LoginModule.
|
||||
*
|
||||
* <p> This method is called by the {@code LoginContext}
|
||||
* after this {@code LoginModule} has been instantiated.
|
||||
* The purpose of this method is to initialize this
|
||||
* {@code LoginModule} with the relevant information.
|
||||
* If this {@code LoginModule} does not understand
|
||||
* any of the data stored in {@code sharedState} or
|
||||
* {@code options} parameters, they can be ignored.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param subject the {@code Subject} to be authenticated. <p>
|
||||
*
|
||||
* @param callbackHandler a {@code CallbackHandler} for communicating
|
||||
* with the end user (prompting for usernames and
|
||||
* passwords, for example). <p>
|
||||
*
|
||||
* @param sharedState state shared with other configured LoginModules. <p>
|
||||
*
|
||||
* @param options options specified in the login
|
||||
* {@code Configuration} for this particular
|
||||
* {@code LoginModule}.
|
||||
*/
|
||||
void initialize(Subject subject, CallbackHandler callbackHandler,
|
||||
Map<String,?> sharedState,
|
||||
Map<String,?> options);
|
||||
|
||||
/**
|
||||
* Method to authenticate a {@code Subject} (phase 1).
|
||||
*
|
||||
* <p> The implementation of this method authenticates
|
||||
* a {@code Subject}. For example, it may prompt for
|
||||
* {@code Subject} information such
|
||||
* as a username and password and then attempt to verify the password.
|
||||
* This method saves the result of the authentication attempt
|
||||
* as private state within the LoginModule.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @exception LoginException if the authentication fails
|
||||
*
|
||||
* @return true if the authentication succeeded, or false if this
|
||||
* {@code LoginModule} should be ignored.
|
||||
*/
|
||||
boolean login() throws LoginException;
|
||||
|
||||
/**
|
||||
* Method to commit the authentication process (phase 2).
|
||||
*
|
||||
* <p> This method is called if the LoginContext's
|
||||
* overall authentication succeeded
|
||||
* (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
|
||||
* succeeded).
|
||||
*
|
||||
* <p> If this LoginModule's own authentication attempt
|
||||
* succeeded (checked by retrieving the private state saved by the
|
||||
* {@code login} method), then this method associates relevant
|
||||
* Principals and Credentials with the {@code Subject} located in the
|
||||
* {@code LoginModule}. If this LoginModule's own
|
||||
* authentication attempted failed, then this method removes/destroys
|
||||
* any state that was originally saved.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @exception LoginException if the commit fails
|
||||
*
|
||||
* @return true if this method succeeded, or false if this
|
||||
* {@code LoginModule} should be ignored.
|
||||
*/
|
||||
boolean commit() throws LoginException;
|
||||
|
||||
/**
|
||||
* Method to abort the authentication process (phase 2).
|
||||
*
|
||||
* <p> This method is called if the LoginContext's
|
||||
* overall authentication failed.
|
||||
* (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
|
||||
* did not succeed).
|
||||
*
|
||||
* <p> If this LoginModule's own authentication attempt
|
||||
* succeeded (checked by retrieving the private state saved by the
|
||||
* {@code login} method), then this method cleans up any state
|
||||
* that was originally saved.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @exception LoginException if the abort fails
|
||||
*
|
||||
* @return true if this method succeeded, or false if this
|
||||
* {@code LoginModule} should be ignored.
|
||||
*/
|
||||
boolean abort() throws LoginException;
|
||||
|
||||
/**
|
||||
* Method which logs out a {@code Subject}.
|
||||
*
|
||||
* <p>An implementation of this method might remove/destroy a Subject's
|
||||
* Principals and Credentials.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @exception LoginException if the logout fails
|
||||
*
|
||||
* @return true if this method succeeded, or false if this
|
||||
* {@code LoginModule} should be ignored.
|
||||
*/
|
||||
boolean logout() throws LoginException;
|
||||
}
|
||||
32
jdkSrc/jdk8/javax/security/auth/spi/package-info.java
Normal file
32
jdkSrc/jdk8/javax/security/auth/spi/package-info.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This package provides the interface to be used for
|
||||
* implementing pluggable authentication modules.
|
||||
*
|
||||
* @since JDK1.4
|
||||
*/
|
||||
package javax.security.auth.spi;
|
||||
513
jdkSrc/jdk8/javax/security/auth/x500/X500Principal.java
Normal file
513
jdkSrc/jdk8/javax/security/auth/x500/X500Principal.java
Normal file
@@ -0,0 +1,513 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.x500;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.Principal;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import sun.security.x509.X500Name;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* <p> This class represents an X.500 {@code Principal}.
|
||||
* {@code X500Principal}s are represented by distinguished names such as
|
||||
* "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US".
|
||||
*
|
||||
* <p> This class can be instantiated by using a string representation
|
||||
* of the distinguished name, or by using the ASN.1 DER encoded byte
|
||||
* representation of the distinguished name. The current specification
|
||||
* for the string representation of a distinguished name is defined in
|
||||
* <a href="http://tools.ietf.org/html/rfc2253">RFC 2253: Lightweight
|
||||
* Directory Access Protocol (v3): UTF-8 String Representation of
|
||||
* Distinguished Names</a>. This class, however, accepts string formats from
|
||||
* both RFC 2253 and <a href="http://tools.ietf.org/html/rfc1779">RFC 1779:
|
||||
* A String Representation of Distinguished Names</a>, and also recognizes
|
||||
* attribute type keywords whose OIDs (Object Identifiers) are defined in
|
||||
* <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
|
||||
* Public Key Infrastructure Certificate and CRL Profile</a>.
|
||||
*
|
||||
* <p> The string representation for this {@code X500Principal}
|
||||
* can be obtained by calling the {@code getName} methods.
|
||||
*
|
||||
* <p> Note that the {@code getSubjectX500Principal} and
|
||||
* {@code getIssuerX500Principal} methods of
|
||||
* {@code X509Certificate} return X500Principals representing the
|
||||
* issuer and subject fields of the certificate.
|
||||
*
|
||||
* @see java.security.cert.X509Certificate
|
||||
* @since 1.4
|
||||
*/
|
||||
public final class X500Principal implements Principal, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -500463348111345721L;
|
||||
|
||||
/**
|
||||
* RFC 1779 String format of Distinguished Names.
|
||||
*/
|
||||
public static final String RFC1779 = "RFC1779";
|
||||
/**
|
||||
* RFC 2253 String format of Distinguished Names.
|
||||
*/
|
||||
public static final String RFC2253 = "RFC2253";
|
||||
/**
|
||||
* Canonical String format of Distinguished Names.
|
||||
*/
|
||||
public static final String CANONICAL = "CANONICAL";
|
||||
|
||||
/**
|
||||
* The X500Name representing this principal.
|
||||
*
|
||||
* NOTE: this field is reflectively accessed from within X500Name.
|
||||
*/
|
||||
private transient X500Name thisX500Name;
|
||||
|
||||
/**
|
||||
* Creates an X500Principal by wrapping an X500Name.
|
||||
*
|
||||
* NOTE: The constructor is package private. It is intended to be accessed
|
||||
* using privileged reflection from classes in sun.security.*.
|
||||
* Currently referenced from sun.security.x509.X500Name.asX500Principal().
|
||||
*/
|
||||
X500Principal(X500Name x500Name) {
|
||||
thisX500Name = x500Name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code X500Principal} from a string representation of
|
||||
* an X.500 distinguished name (ex:
|
||||
* "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US").
|
||||
* The distinguished name must be specified using the grammar defined in
|
||||
* RFC 1779 or RFC 2253 (either format is acceptable).
|
||||
*
|
||||
* <p>This constructor recognizes the attribute type keywords
|
||||
* defined in RFC 1779 and RFC 2253
|
||||
* (and listed in {@link #getName(String format) getName(String format)}),
|
||||
* as well as the T, DNQ or DNQUALIFIER, SURNAME, GIVENNAME, INITIALS,
|
||||
* GENERATION, EMAILADDRESS, and SERIALNUMBER keywords whose Object
|
||||
* Identifiers (OIDs) are defined in RFC 5280.
|
||||
* Any other attribute type must be specified as an OID.
|
||||
*
|
||||
* <p>This implementation enforces a more restrictive OID syntax than
|
||||
* defined in RFC 1779 and 2253. It uses the more correct syntax defined in
|
||||
* <a href="http://www.ietf.org/rfc/rfc4512.txt">RFC 4512</a>, which
|
||||
* specifies that OIDs contain at least 2 digits:
|
||||
*
|
||||
* <p>{@code numericoid = number 1*( DOT number ) }
|
||||
*
|
||||
* @param name an X.500 distinguished name in RFC 1779 or RFC 2253 format
|
||||
* @exception NullPointerException if the {@code name}
|
||||
* is {@code null}
|
||||
* @exception IllegalArgumentException if the {@code name}
|
||||
* is improperly specified
|
||||
*/
|
||||
public X500Principal(String name) {
|
||||
this(name, Collections.<String, String>emptyMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code X500Principal} from a string representation of
|
||||
* an X.500 distinguished name (ex:
|
||||
* "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US").
|
||||
* The distinguished name must be specified using the grammar defined in
|
||||
* RFC 1779 or RFC 2253 (either format is acceptable).
|
||||
*
|
||||
* <p> This constructor recognizes the attribute type keywords specified
|
||||
* in {@link #X500Principal(String)} and also recognizes additional
|
||||
* keywords that have entries in the {@code keywordMap} parameter.
|
||||
* Keyword entries in the keywordMap take precedence over the default
|
||||
* keywords recognized by {@code X500Principal(String)}. Keywords
|
||||
* MUST be specified in all upper-case, otherwise they will be ignored.
|
||||
* Improperly specified keywords are ignored; however if a keyword in the
|
||||
* name maps to an improperly specified Object Identifier (OID), an
|
||||
* {@code IllegalArgumentException} is thrown. It is permissible to
|
||||
* have 2 different keywords that map to the same OID.
|
||||
*
|
||||
* <p>This implementation enforces a more restrictive OID syntax than
|
||||
* defined in RFC 1779 and 2253. It uses the more correct syntax defined in
|
||||
* <a href="http://www.ietf.org/rfc/rfc4512.txt">RFC 4512</a>, which
|
||||
* specifies that OIDs contain at least 2 digits:
|
||||
*
|
||||
* <p>{@code numericoid = number 1*( DOT number ) }
|
||||
*
|
||||
* @param name an X.500 distinguished name in RFC 1779 or RFC 2253 format
|
||||
* @param keywordMap an attribute type keyword map, where each key is a
|
||||
* keyword String that maps to a corresponding object identifier in String
|
||||
* form (a sequence of nonnegative integers separated by periods). The map
|
||||
* may be empty but never {@code null}.
|
||||
* @exception NullPointerException if {@code name} or
|
||||
* {@code keywordMap} is {@code null}
|
||||
* @exception IllegalArgumentException if the {@code name} is
|
||||
* improperly specified or a keyword in the {@code name} maps to an
|
||||
* OID that is not in the correct form
|
||||
* @since 1.6
|
||||
*/
|
||||
public X500Principal(String name, Map<String, String> keywordMap) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException
|
||||
(sun.security.util.ResourcesMgr.getString
|
||||
("provided.null.name"));
|
||||
}
|
||||
if (keywordMap == null) {
|
||||
throw new NullPointerException
|
||||
(sun.security.util.ResourcesMgr.getString
|
||||
("provided.null.keyword.map"));
|
||||
}
|
||||
|
||||
try {
|
||||
thisX500Name = new X500Name(name, keywordMap);
|
||||
} catch (Exception e) {
|
||||
IllegalArgumentException iae = new IllegalArgumentException
|
||||
("improperly specified input name: " + name);
|
||||
iae.initCause(e);
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code X500Principal} from a distinguished name in
|
||||
* ASN.1 DER encoded form. The ASN.1 notation for this structure is as
|
||||
* follows.
|
||||
* <pre>{@code
|
||||
* Name ::= CHOICE {
|
||||
* RDNSequence }
|
||||
*
|
||||
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
||||
*
|
||||
* RelativeDistinguishedName ::=
|
||||
* SET SIZE (1 .. MAX) OF AttributeTypeAndValue
|
||||
*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* value AttributeValue }
|
||||
*
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* AttributeValue ::= ANY DEFINED BY AttributeType
|
||||
* ....
|
||||
* DirectoryString ::= CHOICE {
|
||||
* teletexString TeletexString (SIZE (1..MAX)),
|
||||
* printableString PrintableString (SIZE (1..MAX)),
|
||||
* universalString UniversalString (SIZE (1..MAX)),
|
||||
* utf8String UTF8String (SIZE (1.. MAX)),
|
||||
* bmpString BMPString (SIZE (1..MAX)) }
|
||||
* }</pre>
|
||||
*
|
||||
* @param name a byte array containing the distinguished name in ASN.1
|
||||
* DER encoded form
|
||||
* @throws IllegalArgumentException if an encoding error occurs
|
||||
* (incorrect form for DN)
|
||||
*/
|
||||
public X500Principal(byte[] name) {
|
||||
try {
|
||||
thisX500Name = new X500Name(name);
|
||||
} catch (Exception e) {
|
||||
IllegalArgumentException iae = new IllegalArgumentException
|
||||
("improperly specified input name");
|
||||
iae.initCause(e);
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code X500Principal} from an {@code InputStream}
|
||||
* containing the distinguished name in ASN.1 DER encoded form.
|
||||
* The ASN.1 notation for this structure is supplied in the
|
||||
* documentation for
|
||||
* {@link #X500Principal(byte[] name) X500Principal(byte[] name)}.
|
||||
*
|
||||
* <p> The read position of the input stream is positioned
|
||||
* to the next available byte after the encoded distinguished name.
|
||||
*
|
||||
* @param is an {@code InputStream} containing the distinguished
|
||||
* name in ASN.1 DER encoded form
|
||||
*
|
||||
* @exception NullPointerException if the {@code InputStream}
|
||||
* is {@code null}
|
||||
* @exception IllegalArgumentException if an encoding error occurs
|
||||
* (incorrect form for DN)
|
||||
*/
|
||||
public X500Principal(InputStream is) {
|
||||
if (is == null) {
|
||||
throw new NullPointerException("provided null input stream");
|
||||
}
|
||||
|
||||
try {
|
||||
if (is.markSupported())
|
||||
is.mark(is.available() + 1);
|
||||
DerValue der = new DerValue(is);
|
||||
thisX500Name = new X500Name(der.data);
|
||||
} catch (Exception e) {
|
||||
if (is.markSupported()) {
|
||||
try {
|
||||
is.reset();
|
||||
} catch (IOException ioe) {
|
||||
IllegalArgumentException iae = new IllegalArgumentException
|
||||
("improperly specified input stream " +
|
||||
("and unable to reset input stream"));
|
||||
iae.initCause(e);
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
IllegalArgumentException iae = new IllegalArgumentException
|
||||
("improperly specified input stream");
|
||||
iae.initCause(e);
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the X.500 distinguished name using
|
||||
* the format defined in RFC 2253.
|
||||
*
|
||||
* <p>This method is equivalent to calling
|
||||
* {@code getName(X500Principal.RFC2253)}.
|
||||
*
|
||||
* @return the distinguished name of this {@code X500Principal}
|
||||
*/
|
||||
public String getName() {
|
||||
return getName(X500Principal.RFC2253);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the X.500 distinguished name
|
||||
* using the specified format. Valid values for the format are
|
||||
* "RFC1779", "RFC2253", and "CANONICAL" (case insensitive).
|
||||
*
|
||||
* <p> If "RFC1779" is specified as the format,
|
||||
* this method emits the attribute type keywords defined in
|
||||
* RFC 1779 (CN, L, ST, O, OU, C, STREET).
|
||||
* Any other attribute type is emitted as an OID.
|
||||
*
|
||||
* <p> If "RFC2253" is specified as the format,
|
||||
* this method emits the attribute type keywords defined in
|
||||
* RFC 2253 (CN, L, ST, O, OU, C, STREET, DC, UID).
|
||||
* Any other attribute type is emitted as an OID.
|
||||
* Under a strict reading, RFC 2253 only specifies a UTF-8 string
|
||||
* representation. The String returned by this method is the
|
||||
* Unicode string achieved by decoding this UTF-8 representation.
|
||||
*
|
||||
* <p> If "CANONICAL" is specified as the format,
|
||||
* this method returns an RFC 2253 conformant string representation
|
||||
* with the following additional canonicalizations:
|
||||
*
|
||||
* <ol>
|
||||
* <li> Leading zeros are removed from attribute types
|
||||
* that are encoded as dotted decimal OIDs
|
||||
* <li> DirectoryString attribute values of type
|
||||
* PrintableString and UTF8String are not
|
||||
* output in hexadecimal format
|
||||
* <li> DirectoryString attribute values of types
|
||||
* other than PrintableString and UTF8String
|
||||
* are output in hexadecimal format
|
||||
* <li> Leading and trailing white space characters
|
||||
* are removed from non-hexadecimal attribute values
|
||||
* (unless the value consists entirely of white space characters)
|
||||
* <li> Internal substrings of one or more white space characters are
|
||||
* converted to a single space in non-hexadecimal
|
||||
* attribute values
|
||||
* <li> Relative Distinguished Names containing more than one
|
||||
* Attribute Value Assertion (AVA) are output in the
|
||||
* following order: an alphabetical ordering of AVAs
|
||||
* containing standard keywords, followed by a numeric
|
||||
* ordering of AVAs containing OID keywords.
|
||||
* <li> The only characters in attribute values that are escaped are
|
||||
* those which section 2.4 of RFC 2253 states must be escaped
|
||||
* (they are escaped using a preceding backslash character)
|
||||
* <li> The entire name is converted to upper case
|
||||
* using {@code String.toUpperCase(Locale.US)}
|
||||
* <li> The entire name is converted to lower case
|
||||
* using {@code String.toLowerCase(Locale.US)}
|
||||
* <li> The name is finally normalized using normalization form KD,
|
||||
* as described in the Unicode Standard and UAX #15
|
||||
* </ol>
|
||||
*
|
||||
* <p> Additional standard formats may be introduced in the future.
|
||||
*
|
||||
* @param format the format to use
|
||||
*
|
||||
* @return a string representation of this {@code X500Principal}
|
||||
* using the specified format
|
||||
* @throws IllegalArgumentException if the specified format is invalid
|
||||
* or null
|
||||
*/
|
||||
public String getName(String format) {
|
||||
if (format != null) {
|
||||
if (format.equalsIgnoreCase(RFC1779)) {
|
||||
return thisX500Name.getRFC1779Name();
|
||||
} else if (format.equalsIgnoreCase(RFC2253)) {
|
||||
return thisX500Name.getRFC2253Name();
|
||||
} else if (format.equalsIgnoreCase(CANONICAL)) {
|
||||
return thisX500Name.getRFC2253CanonicalName();
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("invalid format specified");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the X.500 distinguished name
|
||||
* using the specified format. Valid values for the format are
|
||||
* "RFC1779" and "RFC2253" (case insensitive). "CANONICAL" is not
|
||||
* permitted and an {@code IllegalArgumentException} will be thrown.
|
||||
*
|
||||
* <p>This method returns Strings in the format as specified in
|
||||
* {@link #getName(String)} and also emits additional attribute type
|
||||
* keywords for OIDs that have entries in the {@code oidMap}
|
||||
* parameter. OID entries in the oidMap take precedence over the default
|
||||
* OIDs recognized by {@code getName(String)}.
|
||||
* Improperly specified OIDs are ignored; however if an OID
|
||||
* in the name maps to an improperly specified keyword, an
|
||||
* {@code IllegalArgumentException} is thrown.
|
||||
*
|
||||
* <p> Additional standard formats may be introduced in the future.
|
||||
*
|
||||
* <p> Warning: additional attribute type keywords may not be recognized
|
||||
* by other implementations; therefore do not use this method if
|
||||
* you are unsure if these keywords will be recognized by other
|
||||
* implementations.
|
||||
*
|
||||
* @param format the format to use
|
||||
* @param oidMap an OID map, where each key is an object identifier in
|
||||
* String form (a sequence of nonnegative integers separated by periods)
|
||||
* that maps to a corresponding attribute type keyword String.
|
||||
* The map may be empty but never {@code null}.
|
||||
* @return a string representation of this {@code X500Principal}
|
||||
* using the specified format
|
||||
* @throws IllegalArgumentException if the specified format is invalid,
|
||||
* null, or an OID in the name maps to an improperly specified keyword
|
||||
* @throws NullPointerException if {@code oidMap} is {@code null}
|
||||
* @since 1.6
|
||||
*/
|
||||
public String getName(String format, Map<String, String> oidMap) {
|
||||
if (oidMap == null) {
|
||||
throw new NullPointerException
|
||||
(sun.security.util.ResourcesMgr.getString
|
||||
("provided.null.OID.map"));
|
||||
}
|
||||
if (format != null) {
|
||||
if (format.equalsIgnoreCase(RFC1779)) {
|
||||
return thisX500Name.getRFC1779Name(oidMap);
|
||||
} else if (format.equalsIgnoreCase(RFC2253)) {
|
||||
return thisX500Name.getRFC2253Name(oidMap);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("invalid format specified");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distinguished name in ASN.1 DER encoded form. The ASN.1
|
||||
* notation for this structure is supplied in the documentation for
|
||||
* {@link #X500Principal(byte[] name) X500Principal(byte[] name)}.
|
||||
*
|
||||
* <p>Note that the byte array returned is cloned to protect against
|
||||
* subsequent modifications.
|
||||
*
|
||||
* @return a byte array containing the distinguished name in ASN.1 DER
|
||||
* encoded form
|
||||
*/
|
||||
public byte[] getEncoded() {
|
||||
try {
|
||||
return thisX500Name.getEncoded();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("unable to get encoding", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a user-friendly string representation of this
|
||||
* {@code X500Principal}.
|
||||
*
|
||||
* @return a string representation of this {@code X500Principal}
|
||||
*/
|
||||
public String toString() {
|
||||
return thisX500Name.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified {@code Object} with this
|
||||
* {@code X500Principal} for equality.
|
||||
*
|
||||
* <p> Specifically, this method returns {@code true} if
|
||||
* the {@code Object} <i>o</i> is an {@code X500Principal}
|
||||
* and if the respective canonical string representations
|
||||
* (obtained via the {@code getName(X500Principal.CANONICAL)} method)
|
||||
* of this object and <i>o</i> are equal.
|
||||
*
|
||||
* <p> This implementation is compliant with the requirements of RFC 5280.
|
||||
*
|
||||
* @param o Object to be compared for equality with this
|
||||
* {@code X500Principal}
|
||||
*
|
||||
* @return {@code true} if the specified {@code Object} is equal
|
||||
* to this {@code X500Principal}, {@code false} otherwise
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o instanceof X500Principal == false) {
|
||||
return false;
|
||||
}
|
||||
X500Principal other = (X500Principal)o;
|
||||
return this.thisX500Name.equals(other.thisX500Name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hash code for this {@code X500Principal}.
|
||||
*
|
||||
* <p> The hash code is calculated via:
|
||||
* {@code getName(X500Principal.CANONICAL).hashCode()}
|
||||
*
|
||||
* @return a hash code for this {@code X500Principal}
|
||||
*/
|
||||
public int hashCode() {
|
||||
return thisX500Name.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the X500Principal object to a stream.
|
||||
*
|
||||
* @serialData this {@code X500Principal} is serialized
|
||||
* by writing out its DER-encoded form
|
||||
* (the value of {@code getEncoded} is serialized).
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws IOException {
|
||||
s.writeObject(thisX500Name.getEncodedInternal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this object from a stream (i.e., deserializes it).
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException,
|
||||
java.io.NotActiveException,
|
||||
ClassNotFoundException {
|
||||
|
||||
// re-create thisX500Name
|
||||
thisX500Name = new X500Name((byte[])s.readObject());
|
||||
}
|
||||
}
|
||||
134
jdkSrc/jdk8/javax/security/auth/x500/X500PrivateCredential.java
Normal file
134
jdkSrc/jdk8/javax/security/auth/x500/X500PrivateCredential.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.security.auth.x500;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import javax.security.auth.Destroyable;
|
||||
|
||||
/**
|
||||
* <p> This class represents an {@code X500PrivateCredential}.
|
||||
* It associates an X.509 certificate, corresponding private key and the
|
||||
* KeyStore alias used to reference that exact key pair in the KeyStore.
|
||||
* This enables looking up the private credentials for an X.500 principal
|
||||
* in a subject.
|
||||
*
|
||||
*/
|
||||
public final class X500PrivateCredential implements Destroyable {
|
||||
private X509Certificate cert;
|
||||
private PrivateKey key;
|
||||
private String alias;
|
||||
|
||||
/**
|
||||
* Creates an X500PrivateCredential that associates an X.509 certificate,
|
||||
* a private key and the KeyStore alias.
|
||||
* <p>
|
||||
* @param cert X509Certificate
|
||||
* @param key PrivateKey for the certificate
|
||||
* @exception IllegalArgumentException if either {@code cert} or
|
||||
* {@code key} is null
|
||||
*
|
||||
*/
|
||||
|
||||
public X500PrivateCredential(X509Certificate cert, PrivateKey key) {
|
||||
if (cert == null || key == null )
|
||||
throw new IllegalArgumentException();
|
||||
this.cert = cert;
|
||||
this.key = key;
|
||||
this.alias=null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an X500PrivateCredential that associates an X.509 certificate,
|
||||
* a private key and the KeyStore alias.
|
||||
* <p>
|
||||
* @param cert X509Certificate
|
||||
* @param key PrivateKey for the certificate
|
||||
* @param alias KeyStore alias
|
||||
* @exception IllegalArgumentException if either {@code cert},
|
||||
* {@code key} or {@code alias} is null
|
||||
*
|
||||
*/
|
||||
public X500PrivateCredential(X509Certificate cert, PrivateKey key,
|
||||
String alias) {
|
||||
if (cert == null || key == null|| alias == null )
|
||||
throw new IllegalArgumentException();
|
||||
this.cert = cert;
|
||||
this.key = key;
|
||||
this.alias=alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the X.509 certificate.
|
||||
* <p>
|
||||
* @return the X509Certificate
|
||||
*/
|
||||
|
||||
public X509Certificate getCertificate() {
|
||||
return cert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PrivateKey.
|
||||
* <p>
|
||||
* @return the PrivateKey
|
||||
*/
|
||||
public PrivateKey getPrivateKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the KeyStore alias.
|
||||
* <p>
|
||||
* @return the KeyStore alias
|
||||
*/
|
||||
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the references to the X.509 certificate, private key and the
|
||||
* KeyStore alias in this object.
|
||||
*/
|
||||
|
||||
public void destroy() {
|
||||
cert = null;
|
||||
key = null;
|
||||
alias =null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the references to the X.509 certificate and private key
|
||||
* in this object have been cleared.
|
||||
* <p>
|
||||
* @return true if X509Certificate and the PrivateKey are null
|
||||
|
||||
*/
|
||||
public boolean isDestroyed() {
|
||||
return cert == null && key == null && alias==null;
|
||||
}
|
||||
}
|
||||
49
jdkSrc/jdk8/javax/security/auth/x500/package-info.java
Normal file
49
jdkSrc/jdk8/javax/security/auth/x500/package-info.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This package contains the classes that should be used to store
|
||||
* X500 Principal and X500 Private Credentials in a
|
||||
* <i>Subject</i>.
|
||||
*
|
||||
* <h2>Package Specification</h2>
|
||||
*
|
||||
* <ul>
|
||||
* <li><a href="http://tools.ietf.org/html/rfc1779">
|
||||
* RFC 1779: A String Representation of Distinguished Names</a></li>
|
||||
* <li><a href="http://tools.ietf.org/html/rfc2253">
|
||||
* RFC 2253: Lightweight Directory Access Protocol (v3):
|
||||
* UTF-8 String Representation of Distinguished Names</a></li>
|
||||
* <li><a href="http://tools.ietf.org/html/rfc5280">
|
||||
* RFC 5280: Internet X.509 Public Key Infrastructure
|
||||
* Certificate and Certificate Revocation List (CRL) Profile</a></li>
|
||||
* <li><a href="http://tools.ietf.org/html/rfc4512">
|
||||
* RFC 4512: Lightweight Directory Access Protocol (LDAP):
|
||||
* Directory Information Models</a></li>
|
||||
* </ul>
|
||||
*
|
||||
* @since JDK1.4
|
||||
*/
|
||||
package javax.security.auth.x500;
|
||||
Reference in New Issue
Block a user