feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -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;
|
||||
Reference in New Issue
Block a user