Path: blob/master/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
41161 views
/*1* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.security.auth.kerberos;2627import java.io.*;28import sun.security.krb5.KrbException;29import sun.security.krb5.PrincipalName;30import sun.security.krb5.Realm;31import sun.security.util.*;3233/**34* This class encapsulates a Kerberos principal.35*36* @author Mayank Upadhyay37* @since 1.438*/3940public final class KerberosPrincipal41implements java.security.Principal, java.io.Serializable {4243private static final long serialVersionUID = -7374788026156829911L;4445//name types4647/**48* unknown name type.49*/5051public static final int KRB_NT_UNKNOWN = 0;5253/**54* user principal name type.55*/5657public static final int KRB_NT_PRINCIPAL = 1;5859/**60* service and other unique instance (krbtgt) name type.61*/62public static final int KRB_NT_SRV_INST = 2;6364/**65* service with host name as instance (telnet, rcommands) name type.66*/6768public static final int KRB_NT_SRV_HST = 3;6970/**71* service with host as remaining components name type.72*/7374public static final int KRB_NT_SRV_XHST = 4;7576/**77* unique ID name type.78*/7980public static final int KRB_NT_UID = 5;8182/**83* Enterprise name (alias)84*85* @since 1386*/87public static final int KRB_NT_ENTERPRISE = 10;8889private transient String fullName;9091private transient String realm;9293private transient int nameType;949596/**97* Constructs a {@code KerberosPrincipal} from the provided string input.98* The name type for this principal defaults to99* {@link #KRB_NT_PRINCIPAL KRB_NT_PRINCIPAL}100* This string is assumed to contain a name in the format101* that is specified in Section 2.1.1. (Kerberos Principal Name Form) of102* <a href=http://www.ietf.org/rfc/rfc1964.txt> RFC 1964 </a>103* (for example, <i>[email protected]</i>, where <i>duke</i>104* represents a principal, and <i>FOO.COM</i> represents a realm).105*106* <p>If the input name does not contain a realm, the default realm107* is used. The default realm can be specified either in a Kerberos108* configuration file or via the {@code java.security.krb5.realm}109* system property. For more information, see the110* {@extLink security_guide_jgss_tutorial Kerberos Requirements}.111*112* <p>Note that when this class or any other Kerberos-related class is113* initially loaded and initialized, it may read and cache the default114* realm from the Kerberos configuration file or via the115* java.security.krb5.realm system property (the value will be empty if116* no default realm is specified), such that any subsequent calls to set117* or change the default realm by setting the java.security.krb5.realm118* system property may be ignored.119*120* <p>Additionally, if a security manager is121* installed, a {@link ServicePermission} must be granted and the service122* principal of the permission must minimally be inside the123* {@code KerberosPrincipal}'s realm. For example, if the result of124* {@code new KerberosPrincipal("user")} is {@code [email protected]},125* then a {@code ServicePermission} with service principal126* {@code host/[email protected]} (and any action)127* must be granted.128*129* @param name the principal name130* @throws IllegalArgumentException if name is improperly131* formatted, if name is null, or if name does not contain132* the realm to use and the default realm is not specified133* in either a Kerberos configuration file or via the134* java.security.krb5.realm system property.135* @throws SecurityException if a security manager is installed and136* {@code name} does not contain the realm to use, and a proper137* {@link ServicePermission} as described above is not granted.138*/139public KerberosPrincipal(String name) {140this(name, KRB_NT_PRINCIPAL);141}142143/**144* Constructs a {@code KerberosPrincipal} from the provided string and145* name type input. The string is assumed to contain a name in the146* format that is specified in Section 2.1 (Mandatory Name Forms) of147* <a href=http://www.ietf.org/rfc/rfc1964.txt>RFC 1964</a>.148* Valid name types are specified in Section 6.2 (Principal Names) of149* <a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>.150* The input name must be consistent with the provided name type.151* (for example, <i>[email protected]</i>, is a valid input string for the152* name type, KRB_NT_PRINCIPAL where <i>duke</i>153* represents a principal, and <i>FOO.COM</i> represents a realm).154*155* <p>If the input name does not contain a realm, the default realm156* is used. The default realm can be specified either in a Kerberos157* configuration file or via the {@code java.security.krb5.realm}158* system property. For more information, see the159* {@extLink security_guide_jgss_tutorial Kerberos Requirements}.160*161* <p>Note that when this class or any other Kerberos-related class is162* initially loaded and initialized, it may read and cache the default163* realm from the Kerberos configuration file or via the164* java.security.krb5.realm system property (the value will be empty if165* no default realm is specified), such that any subsequent calls to set166* or change the default realm by setting the java.security.krb5.realm167* system property may be ignored.168*169* <p>Additionally, if a security manager is170* installed, a {@link ServicePermission} must be granted and the service171* principal of the permission must minimally be inside the172* {@code KerberosPrincipal}'s realm. For example, if the result of173* {@code new KerberosPrincipal("user")} is {@code [email protected]},174* then a {@code ServicePermission} with service principal175* {@code host/[email protected]} (and any action)176* must be granted.177*178* @param name the principal name179* @param nameType the name type of the principal180* @throws IllegalArgumentException if name is improperly181* formatted, if name is null, if the nameType is not supported,182* or if name does not contain the realm to use and the default183* realm is not specified in either a Kerberos configuration184* file or via the java.security.krb5.realm system property.185* @throws SecurityException if a security manager is installed and186* {@code name} does not contain the realm to use, and a proper187* {@link ServicePermission} as described above is not granted.188*/189190public KerberosPrincipal(String name, int nameType) {191192PrincipalName krb5Principal = null;193194try {195// Appends the default realm if it is missing196krb5Principal = new PrincipalName(name,nameType);197} catch (KrbException e) {198throw new IllegalArgumentException(e.getMessage());199}200201if (krb5Principal.isRealmDeduced() && !Realm.AUTODEDUCEREALM) {202@SuppressWarnings("removal")203SecurityManager sm = System.getSecurityManager();204if (sm != null) {205try {206sm.checkPermission(new ServicePermission(207"@" + krb5Principal.getRealmAsString(), "-"));208} catch (SecurityException se) {209// Swallow the actual exception to hide info210throw new SecurityException("Cannot read realm info");211}212}213}214this.nameType = nameType;215fullName = krb5Principal.toString();216realm = krb5Principal.getRealmString();217}218/**219* Returns the realm component of this Kerberos principal.220*221* @return the realm component of this Kerberos principal.222*/223public String getRealm() {224return realm;225}226227/**228* Returns a hash code for this {@code KerberosPrincipal}. The hash code229* is defined to be the result of the following calculation:230* <pre>{@code231* hashCode = getName().hashCode();232* }</pre>233*234* @return a hash code for this {@code KerberosPrincipal}.235*/236public int hashCode() {237return getName().hashCode();238}239240/**241* Compares the specified object with this principal for equality.242* Returns true if the given object is also a243* {@code KerberosPrincipal} and the two244* {@code KerberosPrincipal} instances are equivalent.245* More formally two {@code KerberosPrincipal} instances are equal246* if the values returned by {@code getName()} are equal.247*248* @param other the object to compare to249* @return true if the object passed in represents the same principal250* as this one, false otherwise.251*/252public boolean equals(Object other) {253254if (other == this)255return true;256257if (! (other instanceof KerberosPrincipal)) {258return false;259}260String myFullName = getName();261String otherFullName = ((KerberosPrincipal) other).getName();262return myFullName.equals(otherFullName);263}264265/**266* Save the {@code KerberosPrincipal} object to a stream267*268* @param oos the {@code ObjectOutputStream} to which data is written269* @throws IOException if an I/O error occurs270*271* @serialData this {@code KerberosPrincipal} is serialized272* by writing out the PrincipalName and the273* Realm in their DER-encoded form as specified in Section 5.2.2 of274* <a href=http://www.ietf.org/rfc/rfc4120.txt> RFC4120</a>.275*/276private void writeObject(ObjectOutputStream oos)277throws IOException {278279PrincipalName krb5Principal;280try {281krb5Principal = new PrincipalName(fullName, nameType);282oos.writeObject(krb5Principal.asn1Encode());283oos.writeObject(krb5Principal.getRealm().asn1Encode());284} catch (Exception e) {285throw new IOException(e);286}287}288289/**290* Reads this object from a stream (i.e., deserializes it)291*292* @param ois the {@code ObjectInputStream} from which data is read293* @throws IOException if an I/O error occurs294* @throws ClassNotFoundException if a serialized class cannot be loaded295*/296private void readObject(ObjectInputStream ois)297throws IOException, ClassNotFoundException {298byte[] asn1EncPrincipal = (byte [])ois.readObject();299byte[] encRealm = (byte [])ois.readObject();300try {301Realm realmObject = new Realm(new DerValue(encRealm));302PrincipalName krb5Principal = new PrincipalName(303new DerValue(asn1EncPrincipal), realmObject);304realm = realmObject.toString();305fullName = krb5Principal.toString();306nameType = krb5Principal.getNameType();307} catch (Exception e) {308throw new IOException(e);309}310}311312/**313* The returned string corresponds to the single-string314* representation of a Kerberos Principal name as specified in315* Section 2.1 of <a href=http://www.ietf.org/rfc/rfc1964.txt>RFC 1964</a>.316*317* @return the principal name.318*/319public String getName() {320return fullName;321}322323/**324* Returns the name type of the {@code KerberosPrincipal}. Valid name types325* are specified in Section 6.2 of326* <a href=http://www.ietf.org/rfc/rfc4120.txt> RFC4120</a>.327*328* @return the name type.329*/330public int getNameType() {331return nameType;332}333334/**335* Returns an informative textual representation of this {@code KerberosPrincipal}.336*337* @return an informative textual representation of this {@code KerberosPrincipal}.338*/339public String toString() {340return getName();341}342}343344345