History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/krb5/Credentials.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/krb5/Credentials.java+497−0
@@ -0,0 +1,497 @@
1+/*
2+ * Copyright (c) 2000, 2010, 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+
26+/*
27+ *
28+ * (C) Copyright IBM Corp. 1999 All Rights Reserved.
29+ * Copyright 1997 The Open Group Research Institute. All rights reserved.
30+ */
31+
32+package sun.security.krb5;
33+
34+import sun.security.krb5.internal.*;
35+import sun.security.krb5.internal.ccache.CredentialsCache;
36+import sun.security.krb5.internal.crypto.EType;
37+import java.io.IOException;
38+import java.util.Date;
39+import java.util.Locale;
40+import java.net.InetAddress;
41+
42+/**
43+ * This class encapsulates the concept of a Kerberos service
44+ * credential. That includes a Kerberos ticket and an associated
45+ * session key.
46+ */
47+public class Credentials {
48+
49+ Ticket ticket;
50+ PrincipalName client;
51+ PrincipalName server;
52+ EncryptionKey key;
53+ TicketFlags flags;
54+ KerberosTime authTime;
55+ KerberosTime startTime;
56+ KerberosTime endTime;
57+ KerberosTime renewTill;
58+ HostAddresses cAddr;
59+ EncryptionKey serviceKey;
60+ AuthorizationData authzData;
61+ private static boolean DEBUG = Krb5.DEBUG;
62+ private static CredentialsCache cache;
63+ static boolean alreadyLoaded = false;
64+ private static boolean alreadyTried = false;
65+ private static native Credentials acquireDefaultNativeCreds();
66+
67+ public Credentials(Ticket new_ticket,
68+ PrincipalName new_client,
69+ PrincipalName new_server,
70+ EncryptionKey new_key,
71+ TicketFlags new_flags,
72+ KerberosTime authTime,
73+ KerberosTime new_startTime,
74+ KerberosTime new_endTime,
75+ KerberosTime renewTill,
76+ HostAddresses cAddr,
77+ AuthorizationData authzData) {
78+ this(new_ticket, new_client, new_server, new_key, new_flags,
79+ authTime, new_startTime, new_endTime, renewTill, cAddr);
80+ this.authzData = authzData;
81+ }
82+
83+ public Credentials(Ticket new_ticket,
84+ PrincipalName new_client,
85+ PrincipalName new_server,
86+ EncryptionKey new_key,
87+ TicketFlags new_flags,
88+ KerberosTime authTime,
89+ KerberosTime new_startTime,
90+ KerberosTime new_endTime,
91+ KerberosTime renewTill,
92+ HostAddresses cAddr) {
93+ ticket = new_ticket;
94+ client = new_client;
95+ server = new_server;
96+ key = new_key;
97+ flags = new_flags;
98+ this.authTime = authTime;
99+ startTime = new_startTime;
100+ endTime = new_endTime;
101+ this.renewTill = renewTill;
102+ this.cAddr = cAddr;
103+ }
104+
105+ public Credentials(byte[] encoding,
106+ String client,
107+ String server,
108+ byte[] keyBytes,
109+ int keyType,
110+ boolean[] flags,
111+ Date authTime,
112+ Date startTime,
113+ Date endTime,
114+ Date renewTill,
115+ InetAddress[] cAddrs) throws KrbException, IOException {
116+ this(new Ticket(encoding),
117+ new PrincipalName(client, PrincipalName.KRB_NT_PRINCIPAL),
118+ new PrincipalName(server, PrincipalName.KRB_NT_SRV_INST),
119+ new EncryptionKey(keyType, keyBytes),
120+ (flags == null? null: new TicketFlags(flags)),
121+ (authTime == null? null: new KerberosTime(authTime)),
122+ (startTime == null? null: new KerberosTime(startTime)),
123+ (endTime == null? null: new KerberosTime(endTime)),
124+ (renewTill == null? null: new KerberosTime(renewTill)),
125+ null); // caddrs are in the encoding at this point
126+ }
127+
128+ /**
129+ * Acquires a service ticket for the specified service
130+ * principal. If the service ticket is not already available, it
131+ * obtains a new one from the KDC.
132+ */
133+ /*
134+ public Credentials(Credentials tgt, PrincipalName service)
135+ throws KrbException {
136+ }
137+ */
138+
139+ public final PrincipalName getClient() {
140+ return client;
141+ }
142+
143+ public final PrincipalName getServer() {
144+ return server;
145+ }
146+
147+ public final EncryptionKey getSessionKey() {
148+ return key;
149+ }
150+
151+ public final Date getAuthTime() {
152+ if (authTime != null) {
153+ return authTime.toDate();
154+ } else {
155+ return null;
156+ }
157+ }
158+
159+ public final Date getStartTime() {
160+ if (startTime != null)
161+ {
162+ return startTime.toDate();
163+ }
164+ return null;
165+ }
166+
167+ public final Date getEndTime() {
168+ if (endTime != null)
169+ {
170+ return endTime.toDate();
171+ }
172+ return null;
173+ }
174+
175+ public final Date getRenewTill() {
176+ if (renewTill != null)
177+ {
178+ return renewTill.toDate();
179+ }
180+ return null;
181+ }
182+
183+ public final boolean[] getFlags() {
184+ if (flags == null) // Can be in a KRB-CRED
185+ return null;
186+ return flags.toBooleanArray();
187+ }
188+
189+ public final InetAddress[] getClientAddresses() {
190+
191+ if (cAddr == null)
192+ return null;
193+
194+ return cAddr.getInetAddresses();
195+ }
196+
197+ public final byte[] getEncoded() {
198+ byte[] retVal = null;
199+ try {
200+ retVal = ticket.asn1Encode();
201+ } catch (Asn1Exception e) {
202+ if (DEBUG)
203+ System.out.println(e);
204+ } catch (IOException ioe) {
205+ if (DEBUG)
206+ System.out.println(ioe);
207+ }
208+ return retVal;
209+ }
210+
211+ public boolean isForwardable() {
212+ return flags.get(Krb5.TKT_OPTS_FORWARDABLE);
213+ }
214+
215+ public boolean isRenewable() {
216+ return flags.get(Krb5.TKT_OPTS_RENEWABLE);
217+ }
218+
219+ public Ticket getTicket() {
220+ return ticket;
221+ }
222+
223+ public TicketFlags getTicketFlags() {
224+ return flags;
225+ }
226+
227+ public AuthorizationData getAuthzData() {
228+ return authzData;
229+ }
230+ /**
231+ * Checks if the service ticket returned by the KDC has the OK-AS-DELEGATE
232+ * flag set
233+ * @return true if OK-AS_DELEGATE flag is set, otherwise, return false.
234+ */
235+ public boolean checkDelegate() {
236+ return flags.get(Krb5.TKT_OPTS_DELEGATE);
237+ }
238+
239+ /**
240+ * Reset TKT_OPTS_DELEGATE to false, called at credentials acquirement
241+ * when one of the cross-realm TGTs does not have the OK-AS-DELEGATE
242+ * flag set. This info must be preservable and restorable through
243+ * the Krb5Util.credsToTicket/ticketToCreds() methods so that even if
244+ * the service ticket is cached it still remembers the cross-realm
245+ * authentication result.
246+ */
247+ public void resetDelegate() {
248+ flags.set(Krb5.TKT_OPTS_DELEGATE, false);
249+ }
250+
251+ public Credentials renew() throws KrbException, IOException {
252+ KDCOptions options = new KDCOptions();
253+ options.set(KDCOptions.RENEW, true);
254+ /*
255+ * Added here to pass KrbKdcRep.check:73
256+ */
257+ options.set(KDCOptions.RENEWABLE, true);
258+
259+ return new KrbTgsReq(options,
260+ this,
261+ server,
262+ null, // from
263+ null, // till
264+ null, // rtime
265+ null, // eTypes
266+ cAddr,
267+ null,
268+ null,
269+ null).sendAndGetCreds();
270+ }
271+
272+ /**
273+ * Returns a TGT for the given client principal from a ticket cache.
274+ *
275+ * @param princ the client principal. A value of null means that the
276+ * default principal name in the credentials cache will be used.
277+ * @param ticketCache the path to the tickets file. A value
278+ * of null will be accepted to indicate that the default
279+ * path should be searched
280+ * @returns the TGT credentials or null if none were found. If the tgt
281+ * expired, it is the responsibility of the caller to determine this.
282+ */
283+ public static Credentials acquireTGTFromCache(PrincipalName princ,
284+ String ticketCache)
285+ throws KrbException, IOException {
286+
287+ if (ticketCache == null) {
288+ // The default ticket cache on Windows is not a file.
289+ String os = java.security.AccessController.doPrivileged(
290+ new sun.security.action.GetPropertyAction("os.name"));
291+ if (os.toUpperCase(Locale.ENGLISH).startsWith("WINDOWS")) {
292+ Credentials creds = acquireDefaultCreds();
293+ if (creds == null) {
294+ if (DEBUG) {
295+ System.out.println(">>> Found no TGT's in LSA");
296+ }
297+ return null;
298+ }
299+ if (princ != null) {
300+ if (creds.getClient().equals(princ)) {
301+ if (DEBUG) {
302+ System.out.println(">>> Obtained TGT from LSA: "
303+ + creds);
304+ }
305+ return creds;
306+ } else {
307+ if (DEBUG) {
308+ System.out.println(">>> LSA contains TGT for "
309+ + creds.getClient()
310+ + " not "
311+ + princ);
312+ }
313+ return null;
314+ }
315+ } else {
316+ if (DEBUG) {
317+ System.out.println(">>> Obtained TGT from LSA: "
318+ + creds);
319+ }
320+ return creds;
321+ }
322+ }
323+ }
324+
325+ /*
326+ * Returns the appropriate cache. If ticketCache is null, it is the
327+ * default cache otherwise it is the cache filename contained in it.
328+ */
329+ CredentialsCache ccache =
330+ CredentialsCache.getInstance(princ, ticketCache);
331+
332+ if (ccache == null)
333+ return null;
334+
335+ sun.security.krb5.internal.ccache.Credentials tgtCred =
336+ ccache.getDefaultCreds();
337+
338+ if (EType.isSupported(tgtCred.getEType())) {
339+ return tgtCred.setKrbCreds();
340+ } else {
341+ if (DEBUG) {
342+ System.out.println(
343+ ">>> unsupported key type found the default TGT: " +
344+ tgtCred.getEType());
345+ }
346+ return null;
347+ }
348+ }
349+
350+ /**
351+ * Acquires default credentials.
352+ * <br>The possible locations for default credentials cache is searched in
353+ * the following order:
354+ * <ol>
355+ * <li> The directory and cache file name specified by "KRB5CCNAME" system.
356+ * property.
357+ * <li> The directory and cache file name specified by "KRB5CCNAME"
358+ * environment variable.
359+ * <li> A cache file named krb5cc_{user.name} at {user.home} directory.
360+ * </ol>
361+ * @return a <code>KrbCreds</code> object if the credential is found,
362+ * otherwise return null.
363+ */
364+
365+ // this method is intentionally changed to not check if the caller's
366+ // principal name matches cache file's principal name.
367+ // It assumes that the GSS call has
368+ // the privilege to access the default cache file.
369+
370+ public static synchronized Credentials acquireDefaultCreds() {
371+ Credentials result = null;
372+
373+ if (cache == null) {
374+ cache = CredentialsCache.getInstance();
375+ }
376+ if (cache != null) {
377+ if (DEBUG) {
378+ System.out.println(">>> KrbCreds found the default ticket " +
379+ "granting ticket in credential cache.");
380+ }
381+ sun.security.krb5.internal.ccache.Credentials temp =
382+ cache.getDefaultCreds();
383+ if (EType.isSupported(temp.getEType())) {
384+ result = temp.setKrbCreds();
385+ } else {
386+ if (DEBUG) {
387+ System.out.println(
388+ ">>> unsupported key type found the default TGT: " +
389+ temp.getEType());
390+ }
391+ }
392+ }
393+ if (result == null) {
394+ // Doesn't seem to be a default cache on this system or
395+ // TGT has unsupported encryption type
396+
397+ if (!alreadyTried) {
398+ // See if there's any native code to load
399+ try {
400+ ensureLoaded();
401+ } catch (Exception e) {
402+ if (DEBUG) {
403+ System.out.println("Can not load credentials cache");
404+ e.printStackTrace();
405+ }
406+ alreadyTried = true;
407+ }
408+ }
409+ if (alreadyLoaded) {
410+ // There is some native code
411+ if (DEBUG)
412+ System.out.println(">> Acquire default native Credentials");
413+ result = acquireDefaultNativeCreds();
414+ // only TGT with DES key will be returned by native method
415+ }
416+ }
417+ return result;
418+ }
419+
420+ /**
421+ * Acquires credentials for a specified service using initial credential.
422+ * When the service has a different realm
423+ * from the initial credential, we do cross-realm authentication
424+ * - first, we use the current credential to get
425+ * a cross-realm credential from the local KDC, then use that
426+ * cross-realm credential to request service credential
427+ * from the foreigh KDC.
428+ *
429+ * @param service the name of service principal using format
430+ * components@realm
431+ * @param ccreds client's initial credential.
432+ * @exception IOException if an error occurs in reading the credentials
433+ * cache
434+ * @exception KrbException if an error occurs specific to Kerberos
435+ * @return a <code>Credentials</code> object.
436+ */
437+
438+ public static Credentials acquireServiceCreds(String service,
439+ Credentials ccreds)
440+ throws KrbException, IOException {
441+ return CredentialsUtil.acquireServiceCreds(service, ccreds);
442+ }
443+
444+ public CredentialsCache getCache() {
445+ return cache;
446+ }
447+
448+ public EncryptionKey getServiceKey() {
449+ return serviceKey;
450+ }
451+
452+ /*
453+ * Prints out debug info.
454+ */
455+ public static void printDebug(Credentials c) {
456+ System.out.println(">>> DEBUG: ----Credentials----");
457+ System.out.println("\tclient: " + c.client.toString());
458+ System.out.println("\tserver: " + c.server.toString());
459+ System.out.println("\tticket: realm: " + c.ticket.realm.toString());
460+ System.out.println("\t sname: " + c.ticket.sname.toString());
461+ if (c.startTime != null) {
462+ System.out.println("\tstartTime: " + c.startTime.getTime());
463+ }
464+ System.out.println("\tendTime: " + c.endTime.getTime());
465+ System.out.println(" ----Credentials end----");
466+ }
467+
468+
469+ static void ensureLoaded() {
470+ java.security.AccessController.doPrivileged(
471+ new java.security.PrivilegedAction<Void> () {
472+ public Void run() {
473+ System.loadLibrary("w2k_lsa_auth");
474+ return null;
475+ }
476+ });
477+ alreadyLoaded = true;
478+ }
479+
480+ public String toString() {
481+ StringBuffer buffer = new StringBuffer("Credentials:");
482+ buffer.append("\nclient=").append(client);
483+ buffer.append("\nserver=").append(server);
484+ if (authTime != null) {
485+ buffer.append("\nauthTime=").append(authTime);
486+ }
487+ if (startTime != null) {
488+ buffer.append("\nstartTime=").append(startTime);
489+ }
490+ buffer.append("\nendTime=").append(endTime);
491+ buffer.append("\nrenewTill=").append(renewTill);
492+ buffer.append("\nflags: ").append(flags);
493+ buffer.append("\nEType (int): ").append(key.getEType());
494+ return buffer.toString();
495+ }
496+
497+}