001 /*
002 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.security.auth.kerberos;
027
028 import java.io.*;
029 import sun.security.krb5.Asn1Exception;
030 import sun.security.krb5.KrbException;
031 import sun.security.krb5.PrincipalName;
032 import sun.security.krb5.Realm;
033 import sun.security.util.*;
034
035 /**
036 * This class encapsulates a Kerberos principal.
037 *
038 * @author Mayank Upadhyay
039 * @version 1.29, 05/05/07
040 * @since 1.4
041 */
042
043 public final class KerberosPrincipal implements
044 java.security.Principal, java.io.Serializable {
045
046 private static final long serialVersionUID = -7374788026156829911L;
047
048 //name types
049
050 /**
051 * unknown name type.
052 */
053
054 public static final int KRB_NT_UNKNOWN = 0;
055
056 /**
057 * user principal name type.
058 */
059
060 public static final int KRB_NT_PRINCIPAL = 1;
061
062 /**
063 * service and other unique instance (krbtgt) name type.
064 */
065 public static final int KRB_NT_SRV_INST = 2;
066
067 /**
068 * service with host name as instance (telnet, rcommands) name type.
069 */
070
071 public static final int KRB_NT_SRV_HST = 3;
072
073 /**
074 * service with host as remaining components name type.
075 */
076
077 public static final int KRB_NT_SRV_XHST = 4;
078
079 /**
080 * unique ID name type.
081 */
082
083 public static final int KRB_NT_UID = 5;
084
085 private transient String fullName;
086
087 private transient String realm;
088
089 private transient int nameType;
090
091 private static final char NAME_REALM_SEPARATOR = '@';
092
093 /**
094 * Constructs a KerberosPrincipal from the provided string input. The
095 * name type for this principal defaults to
096 * {@link #KRB_NT_PRINCIPAL KRB_NT_PRINCIPAL}
097 * This string is assumed to contain a name in the format
098 * that is specified in Section 2.1.1. (Kerberos Principal Name Form) of
099 * <a href=http://www.ietf.org/rfc/rfc1964.txt> RFC 1964 </a>
100 * (for example, <i>duke@FOO.COM</i>, where <i>duke</i>
101 * represents a principal, and <i>FOO.COM</i> represents a realm).
102 *
103 * <p>If the input name does not contain a realm, the default realm
104 * is used. The default realm can be specified either in a Kerberos
105 * configuration file or via the java.security.krb5.realm
106 * system property. For more information,
107 * <a href="../../../../../technotes/guides/security/jgss/tutorials/index.html">
108 * Kerberos Requirements </a>
109 *
110 * @param name the principal name
111 * @throws IllegalArgumentException if name is improperly
112 * formatted, if name is null, or if name does not contain
113 * the realm to use and the default realm is not specified
114 * in either a Kerberos configuration file or via the
115 * java.security.krb5.realm system property.
116 */
117 public KerberosPrincipal(String name) {
118
119 PrincipalName krb5Principal = null;
120
121 try {
122 // Appends the default realm if it is missing
123 krb5Principal = new PrincipalName(name, KRB_NT_PRINCIPAL);
124 } catch (KrbException e) {
125 throw new IllegalArgumentException(e.getMessage());
126 }
127 nameType = KRB_NT_PRINCIPAL; // default name type
128 fullName = krb5Principal.toString();
129 realm = krb5Principal.getRealmString();
130 }
131
132 /**
133 * Constructs a KerberosPrincipal from the provided string and
134 * name type input. The string is assumed to contain a name in the
135 * format that is specified in Section 2.1 (Mandatory Name Forms) of
136 * <a href=http://www.ietf.org/rfc/rfc1964.txt>RFC 1964</a>.
137 * Valid name types are specified in Section 6.2 (Principal Names) of
138 * <a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>.
139 * The input name must be consistent with the provided name type.
140 * (for example, <i>duke@FOO.COM</i>, is a valid input string for the
141 * name type, KRB_NT_PRINCIPAL where <i>duke</i>
142 * represents a principal, and <i>FOO.COM</i> represents a realm).
143
144 * <p> If the input name does not contain a realm, the default realm
145 * is used. The default realm can be specified either in a Kerberos
146 * configuration file or via the java.security.krb5.realm
147 * system property. For more information, see
148 * <a href="../../../../../technotes/guides/security/jgss/tutorials/index.html">
149 * Kerberos Requirements</a>.
150 *
151 * @param name the principal name
152 * @param nameType the name type of the principal
153 * @throws IllegalArgumentException if name is improperly
154 * formatted, if name is null, if the nameType is not supported,
155 * or if name does not contain the realm to use and the default
156 * realm is not specified in either a Kerberos configuration
157 * file or via the java.security.krb5.realm system property.
158 */
159
160 public KerberosPrincipal(String name, int nameType) {
161
162 PrincipalName krb5Principal = null;
163
164 try {
165 // Appends the default realm if it is missing
166 krb5Principal = new PrincipalName(name, nameType);
167 } catch (KrbException e) {
168 throw new IllegalArgumentException(e.getMessage());
169 }
170
171 this .nameType = nameType;
172 fullName = krb5Principal.toString();
173 realm = krb5Principal.getRealmString();
174 }
175
176 /**
177 * Returns the realm component of this Kerberos principal.
178 *
179 * @return the realm component of this Kerberos principal.
180 */
181 public String getRealm() {
182 return realm;
183 }
184
185 /**
186 * Returns a hashcode for this principal. The hash code is defined to
187 * be the result of the following calculation:
188 * <pre><code>
189 * hashCode = getName().hashCode();
190 * </code></pre>
191 *
192 * @return a hashCode() for the <code>KerberosPrincipal</code>
193 */
194 public int hashCode() {
195 return getName().hashCode();
196 }
197
198 /**
199 * Compares the specified Object with this Principal for equality.
200 * Returns true if the given object is also a
201 * <code>KerberosPrincipal</code> and the two
202 * <code>KerberosPrincipal</code> instances are equivalent.
203 * More formally two <code>KerberosPrincipal</code> instances are equal
204 * if the values returned by <code>getName()</code> are equal and the
205 * values returned by <code>getNameType()</code> are equal.
206 *
207 * @param other the Object to compare to
208 * @return true if the Object passed in represents the same principal
209 * as this one, false otherwise.
210 */
211 public boolean equals(Object other) {
212
213 if (other == this )
214 return true;
215
216 if (!(other instanceof KerberosPrincipal)) {
217 return false;
218 } else {
219 String myFullName = getName();
220 String otherFullName = ((KerberosPrincipal) other)
221 .getName();
222 if (nameType == ((KerberosPrincipal) other).nameType
223 && myFullName.equals(otherFullName)) {
224 return true;
225 }
226 }
227 return false;
228 }
229
230 /**
231 * Save the KerberosPrincipal object to a stream
232 *
233 * @serialData this <code>KerberosPrincipal</code> is serialized
234 * by writing out the PrincipalName and the
235 * realm in their DER-encoded form as specified in Section 5.2.2 of
236 * <a href=http://www.ietf.org/rfc/rfc4120.txt> RFC4120</a>.
237 */
238
239 private void writeObject(ObjectOutputStream oos) throws IOException {
240
241 PrincipalName krb5Principal = null;
242 try {
243 krb5Principal = new PrincipalName(fullName, nameType);
244 oos.writeObject(krb5Principal.asn1Encode());
245 oos.writeObject(krb5Principal.getRealm().asn1Encode());
246 } catch (Exception e) {
247 IOException ioe = new IOException(e.getMessage());
248 ioe.initCause(e);
249 throw ioe;
250 }
251 }
252
253 /**
254 * Reads this object from a stream (i.e., deserializes it)
255 */
256
257 private void readObject(ObjectInputStream ois) throws IOException,
258 ClassNotFoundException {
259 byte[] asn1EncPrincipal = (byte[]) ois.readObject();
260 byte[] encRealm = (byte[]) ois.readObject();
261 try {
262 PrincipalName krb5Principal = new PrincipalName(
263 new DerValue(asn1EncPrincipal));
264 realm = (new Realm(new DerValue(encRealm))).toString();
265 fullName = krb5Principal.toString() + NAME_REALM_SEPARATOR
266 + realm.toString();
267 nameType = krb5Principal.getNameType();
268 } catch (Exception e) {
269 IOException ioe = new IOException(e.getMessage());
270 ioe.initCause(e);
271 throw ioe;
272 }
273 }
274
275 /**
276 * The returned string corresponds to the single-string
277 * representation of a Kerberos Principal name as specified in
278 * Section 2.1 of <a href=http://www.ietf.org/rfc/rfc1964.txt>RFC 1964</a>.
279 *
280 * @return the principal name.
281 */
282 public String getName() {
283 return fullName;
284 }
285
286 /**
287 * Returns the name type of the KerberosPrincipal. Valid name types
288 * are specified in Section 6.2 of
289 * <a href=http://www.ietf.org/rfc/rfc4120.txt> RFC4120</a>.
290 *
291 * @return the name type.
292 *
293 */
294
295 public int getNameType() {
296 return nameType;
297 }
298
299 // Inherits javadocs from Object
300 public String toString() {
301 return getName();
302 }
303 }
|