--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2000, 2017, 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;
+
+ private transient String fullName;
+
+ private transient String realm;
+
+ private transient int nameType;
+
+
+ /**
+ * Constructs a {@code 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, see the
+ * {@extLink security_guide_jgss_tutorial Kerberos Requirements}.
+ * Additionally, if a security manager is
+ * installed, a {@link ServicePermission} must be granted and the service
+ * principal of the permission must minimally be inside the
+ * {@code KerberosPrincipal}'s realm. For example, if the result of
+ * {@code new KerberosPrincipal("user")} is {@code user@EXAMPLE.COM},
+ * then a {@code ServicePermission} with service principal
+ * {@code host/www.example.com@EXAMPLE.COM} (and any action)
+ * must be granted.
+ *
+ * @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.
+ * @throws SecurityException if a security manager is installed and
+ * {@code name} does not contain the realm to use, and a proper
+ * {@link ServicePermission} as described above is not granted.
+ */
+ public KerberosPrincipal(String name) {
+ this(name, KRB_NT_PRINCIPAL);
+ }
+
+ /**
+ * Constructs a {@code 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 the
+ * {@extLink security_guide_jgss_tutorial Kerberos Requirements}.
+ * Additionally, if a security manager is
+ * installed, a {@link ServicePermission} must be granted and the service
+ * principal of the permission must minimally be inside the
+ * {@code KerberosPrincipal}'s realm. For example, if the result of
+ * {@code new KerberosPrincipal("user")} is {@code user@EXAMPLE.COM},
+ * then a {@code ServicePermission} with service principal
+ * {@code host/www.example.com@EXAMPLE.COM} (and any action)
+ * must be granted.
+ *
+ * @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.
+ * @throws SecurityException if a security manager is installed and
+ * {@code name} does not contain the realm to use, and a proper
+ * {@link ServicePermission} as described above is not granted.
+ */
+
+ 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());
+ }
+
+ 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 hash code for this {@code KerberosPrincipal}. The hash code
+ * is defined to be the result of the following calculation:
+ * <pre>{@code
+ * hashCode = getName().hashCode();
+ * }</pre>
+ *
+ * @return a hash code for this {@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 {@code 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 {@code 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;
+ }
+
+ /**
+ * Returns an informative textual representation of this {@code KerberosPrincipal}.
+ *
+ * @return an informative textual representation of this {@code KerberosPrincipal}.
+ */
+ public String toString() {
+ return getName();
+ }
+}