KerberosPrincipal.java revision 10444:f08705540498
1/* 2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package javax.security.auth.kerberos; 27 28import java.io.*; 29import sun.security.krb5.KrbException; 30import sun.security.krb5.PrincipalName; 31import sun.security.krb5.Realm; 32import sun.security.util.*; 33 34/** 35 * This class encapsulates a Kerberos principal. 36 * 37 * @author Mayank Upadhyay 38 * @since 1.4 39 */ 40 41public final class KerberosPrincipal 42 implements java.security.Principal, java.io.Serializable { 43 44 private static final long serialVersionUID = -7374788026156829911L; 45 46 //name types 47 48 /** 49 * unknown name type. 50 */ 51 52 public static final int KRB_NT_UNKNOWN = 0; 53 54 /** 55 * user principal name type. 56 */ 57 58 public static final int KRB_NT_PRINCIPAL = 1; 59 60 /** 61 * service and other unique instance (krbtgt) name type. 62 */ 63 public static final int KRB_NT_SRV_INST = 2; 64 65 /** 66 * service with host name as instance (telnet, rcommands) name type. 67 */ 68 69 public static final int KRB_NT_SRV_HST = 3; 70 71 /** 72 * service with host as remaining components name type. 73 */ 74 75 public static final int KRB_NT_SRV_XHST = 4; 76 77 /** 78 * unique ID name type. 79 */ 80 81 public static final int KRB_NT_UID = 5; 82 83 private transient String fullName; 84 85 private transient String realm; 86 87 private transient int nameType; 88 89 90 /** 91 * Constructs a KerberosPrincipal from the provided string input. The 92 * name type for this principal defaults to 93 * {@link #KRB_NT_PRINCIPAL KRB_NT_PRINCIPAL} 94 * This string is assumed to contain a name in the format 95 * that is specified in Section 2.1.1. (Kerberos Principal Name Form) of 96 * <a href=http://www.ietf.org/rfc/rfc1964.txt> RFC 1964 </a> 97 * (for example, <i>duke@FOO.COM</i>, where <i>duke</i> 98 * represents a principal, and <i>FOO.COM</i> represents a realm). 99 * 100 * <p>If the input name does not contain a realm, the default realm 101 * is used. The default realm can be specified either in a Kerberos 102 * configuration file or via the java.security.krb5.realm 103 * system property. For more information, 104 * <a href="../../../../../technotes/guides/security/jgss/tutorials/index.html"> 105 * Kerberos Requirements </a> 106 * 107 * @param name the principal name 108 * @throws IllegalArgumentException if name is improperly 109 * formatted, if name is null, or if name does not contain 110 * the realm to use and the default realm is not specified 111 * in either a Kerberos configuration file or via the 112 * java.security.krb5.realm system property. 113 */ 114 public KerberosPrincipal(String name) { 115 116 PrincipalName krb5Principal = null; 117 118 try { 119 // Appends the default realm if it is missing 120 krb5Principal = new PrincipalName(name, KRB_NT_PRINCIPAL); 121 } catch (KrbException e) { 122 throw new IllegalArgumentException(e.getMessage()); 123 } 124 nameType = KRB_NT_PRINCIPAL; // default name type 125 fullName = krb5Principal.toString(); 126 realm = krb5Principal.getRealmString(); 127 } 128 129 /** 130 * Constructs a KerberosPrincipal from the provided string and 131 * name type input. The string is assumed to contain a name in the 132 * format that is specified in Section 2.1 (Mandatory Name Forms) of 133 * <a href=http://www.ietf.org/rfc/rfc1964.txt>RFC 1964</a>. 134 * Valid name types are specified in Section 6.2 (Principal Names) of 135 * <a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>. 136 * The input name must be consistent with the provided name type. 137 * (for example, <i>duke@FOO.COM</i>, is a valid input string for the 138 * name type, KRB_NT_PRINCIPAL where <i>duke</i> 139 * represents a principal, and <i>FOO.COM</i> represents a realm). 140 141 * <p> If the input name does not contain a realm, the default realm 142 * is used. The default realm can be specified either in a Kerberos 143 * configuration file or via the java.security.krb5.realm 144 * system property. For more information, see 145 * <a href="../../../../../technotes/guides/security/jgss/tutorials/index.html"> 146 * Kerberos Requirements</a>. 147 * 148 * @param name the principal name 149 * @param nameType the name type of the principal 150 * @throws IllegalArgumentException if name is improperly 151 * formatted, if name is null, if the nameType is not supported, 152 * or if name does not contain the realm to use and the default 153 * realm is not specified in either a Kerberos configuration 154 * file or via the java.security.krb5.realm system property. 155 */ 156 157 public KerberosPrincipal(String name, int nameType) { 158 159 PrincipalName krb5Principal = null; 160 161 try { 162 // Appends the default realm if it is missing 163 krb5Principal = new PrincipalName(name,nameType); 164 } catch (KrbException e) { 165 throw new IllegalArgumentException(e.getMessage()); 166 } 167 168 this.nameType = nameType; 169 fullName = krb5Principal.toString(); 170 realm = krb5Principal.getRealmString(); 171 } 172 /** 173 * Returns the realm component of this Kerberos principal. 174 * 175 * @return the realm component of this Kerberos principal. 176 */ 177 public String getRealm() { 178 return realm; 179 } 180 181 /** 182 * Returns a hashcode for this principal. The hash code is defined to 183 * be the result of the following calculation: 184 * <pre>{@code 185 * hashCode = getName().hashCode(); 186 * }</pre> 187 * 188 * @return a hashCode() for the {@code KerberosPrincipal} 189 */ 190 public int hashCode() { 191 return getName().hashCode(); 192 } 193 194 /** 195 * Compares the specified Object with this Principal for equality. 196 * Returns true if the given object is also a 197 * {@code KerberosPrincipal} and the two 198 * {@code KerberosPrincipal} instances are equivalent. 199 * More formally two {@code KerberosPrincipal} instances are equal 200 * if the values returned by {@code getName()} are equal. 201 * 202 * @param other the Object to compare to 203 * @return true if the Object passed in represents the same principal 204 * as this one, false otherwise. 205 */ 206 public boolean equals(Object other) { 207 208 if (other == this) 209 return true; 210 211 if (! (other instanceof KerberosPrincipal)) { 212 return false; 213 } 214 String myFullName = getName(); 215 String otherFullName = ((KerberosPrincipal) other).getName(); 216 return myFullName.equals(otherFullName); 217 } 218 219 /** 220 * Save the KerberosPrincipal object to a stream 221 * 222 * @serialData this {@code KerberosPrincipal} is serialized 223 * by writing out the PrincipalName and the 224 * realm in their DER-encoded form as specified in Section 5.2.2 of 225 * <a href=http://www.ietf.org/rfc/rfc4120.txt> RFC4120</a>. 226 */ 227 private void writeObject(ObjectOutputStream oos) 228 throws IOException { 229 230 PrincipalName krb5Principal; 231 try { 232 krb5Principal = new PrincipalName(fullName, nameType); 233 oos.writeObject(krb5Principal.asn1Encode()); 234 oos.writeObject(krb5Principal.getRealm().asn1Encode()); 235 } catch (Exception e) { 236 throw new IOException(e); 237 } 238 } 239 240 /** 241 * Reads this object from a stream (i.e., deserializes it) 242 */ 243 private void readObject(ObjectInputStream ois) 244 throws IOException, ClassNotFoundException { 245 byte[] asn1EncPrincipal = (byte [])ois.readObject(); 246 byte[] encRealm = (byte [])ois.readObject(); 247 try { 248 Realm realmObject = new Realm(new DerValue(encRealm)); 249 PrincipalName krb5Principal = new PrincipalName( 250 new DerValue(asn1EncPrincipal), realmObject); 251 realm = realmObject.toString(); 252 fullName = krb5Principal.toString(); 253 nameType = krb5Principal.getNameType(); 254 } catch (Exception e) { 255 throw new IOException(e); 256 } 257 } 258 259 /** 260 * The returned string corresponds to the single-string 261 * representation of a Kerberos Principal name as specified in 262 * Section 2.1 of <a href=http://www.ietf.org/rfc/rfc1964.txt>RFC 1964</a>. 263 * 264 * @return the principal name. 265 */ 266 public String getName() { 267 return fullName; 268 } 269 270 /** 271 * Returns the name type of the KerberosPrincipal. Valid name types 272 * are specified in Section 6.2 of 273 * <a href=http://www.ietf.org/rfc/rfc4120.txt> RFC4120</a>. 274 * 275 * @return the name type. 276 */ 277 public int getNameType() { 278 return nameType; 279 } 280 281 // Inherits javadocs from Object 282 public String toString() { 283 return getName(); 284 } 285} 286