--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java Tue Aug 11 12:20:32 2009 +0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.security.jgss;
+
+/**
+ * Kerberos 5 AuthorizationData entry.
+ */
+final public class AuthorizationDataEntry {
+
+ private final int type;
+ private final byte[] data;
+
+ /**
+ * Create an AuthorizationDataEntry object.
+ * @param type the ad-type
+ * @param data the ad-data, a copy of the data will be saved
+ * inside the object.
+ */
+ public AuthorizationDataEntry(int type, byte[] data) {
+ this.type = type;
+ this.data = data.clone();
+ }
+
+ /**
+ * Get the ad-type field.
+ * @return ad-type
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Get a copy of the ad-data field.
+ * @return ad-data
+ */
+ public byte[] getData() {
+ return data.clone();
+ }
+
+ public String toString() {
+ return "AuthorizationDataEntry: type="+type+", data=" +
+ data.length + " bytes:\n" +
+ new sun.misc.HexDumpEncoder().encode(data);
+ }
+}
--- a/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java Tue Aug 11 12:17:13 2009 +0800
+++ b/jdk/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java Tue Aug 11 12:20:32 2009 +0800
@@ -39,6 +39,11 @@
* For each supported attribute type, the type for the output are
* defined below.
* <ol>
+ * <li>{@code KRB5_GET_TKT_FLAGS}:
+ * the returned object is a boolean array for the service ticket flags,
+ * which is long enough to contain all true bits. This means if
+ * the user wants to get the <em>n</em>'th bit but the length of the
+ * returned array is less than <em>n</em>, it is regarded as false.
* <li>{@code KRB5_GET_SESSION_KEY}:
* the returned object is an instance of {@link java.security.Key},
* which has the following properties:
@@ -48,6 +53,13 @@
* <li>Format: "RAW"
* <li>Encoded form: the raw key bytes, not in any ASN.1 encoding
* </ul>
+ * <li>{@code KRB5_GET_AUTHZ_DATA}:
+ * the returned object is an array of
+ * {@link com.sun.security.jgss.AuthorizationDataEntry}, or null if the
+ * optional field is missing in the service ticket.
+ * <li>{@code KRB5_GET_AUTHTIME}:
+ * the returned object is a String object in the standard KerberosTime
+ * format defined in RFC 4120 5.2.3
* </ol>
*
* If there is a security manager, an {@link InquireSecContextPermission}
--- a/jdk/src/share/classes/com/sun/security/jgss/InquireType.java Tue Aug 11 12:17:13 2009 +0800
+++ b/jdk/src/share/classes/com/sun/security/jgss/InquireType.java Tue Aug 11 12:20:32 2009 +0800
@@ -32,7 +32,23 @@
public enum InquireType {
/**
* Attribute type for retrieving the session key of an
- * established security context.
+ * established Kerberos 5 security context.
+ */
+ KRB5_GET_SESSION_KEY,
+ /**
+ * Attribute type for retrieving the service ticket flags of an
+ * established Kerberos 5 security context.
*/
- KRB5_GET_SESSION_KEY
+ KRB5_GET_TKT_FLAGS,
+ /**
+ * Attribute type for retrieving the authorization data in the
+ * service ticket of an established Kerberos 5 security context.
+ * Only supported on the acceptor side.
+ */
+ KRB5_GET_AUTHZ_DATA,
+ /**
+ * Attribute type for retrieving the authtime in the service ticket
+ * of an established Kerberos 5 security context.
+ */
+ KRB5_GET_AUTHTIME
}
--- a/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java Tue Aug 11 12:17:13 2009 +0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java Tue Aug 11 12:20:32 2009 +0800
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc. 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
@@ -25,12 +25,14 @@
package sun.security.jgss.krb5;
+import com.sun.security.jgss.AuthorizationDataEntry;
import org.ietf.jgss.*;
import java.io.InputStream;
-import java.io.OutputStream;
import java.io.IOException;
import sun.security.krb5.*;
import java.net.InetAddress;
+import sun.security.krb5.internal.AuthorizationData;
+import sun.security.krb5.internal.KerberosTime;
class InitSecContextToken extends InitialToken {
@@ -59,6 +61,9 @@
Checksum checksum = gssChecksum.getChecksum();
+ context.setTktFlags(serviceTicket.getFlags());
+ context.setAuthTime(
+ new KerberosTime(serviceTicket.getAuthTime()).toString());
apReq = new KrbApReq(serviceTicket,
mutualRequired,
useSubkey,
@@ -143,6 +148,21 @@
// Use the same sequence number as the peer
// (Behaviour exhibited by the Windows SSPI server)
context.resetMySequenceNumber(peerSeqNumber);
+ context.setAuthTime(
+ new KerberosTime(apReq.getCreds().getAuthTime()).toString());
+ context.setTktFlags(apReq.getCreds().getFlags());
+ AuthorizationData ad = apReq.getCreds().getAuthzData();
+ if (ad == null) {
+ context.setAuthzData(null);
+ } else {
+ AuthorizationDataEntry[] authzData =
+ new AuthorizationDataEntry[ad.count()];
+ for (int i=0; i<ad.count(); i++) {
+ authzData[i] = new AuthorizationDataEntry(
+ ad.item(i).adType, ad.item(i).adData);
+ }
+ context.setAuthzData(authzData);
+ }
}
public final KrbApReq getKrbApReq() {
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java Tue Aug 11 12:17:13 2009 +0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java Tue Aug 11 12:20:32 2009 +0800
@@ -1290,7 +1290,7 @@
* The session key returned by inquireSecContext(KRB5_INQ_SSPI_SESSION_KEY)
*/
static class KerberosSessionKey implements Key {
- private EncryptionKey key;
+ private final EncryptionKey key;
KerberosSessionKey(EncryptionKey key) {
this.key = key;
@@ -1320,19 +1320,46 @@
/**
* Return the mechanism-specific attribute associated with {@code type}.
- * Only KRB5_GET_SESSION_KEY is supported now.
*/
public Object inquireSecContext(InquireType type)
throws GSSException {
- if (type == InquireType.KRB5_GET_SESSION_KEY) {
- if (key == null) {
- throw new GSSException(GSSException.NO_CONTEXT, -1,
- "Session key not established.");
- } else {
+ if (!isEstablished()) {
+ throw new GSSException(GSSException.NO_CONTEXT, -1,
+ "Security context not established.");
+ }
+ switch (type) {
+ case KRB5_GET_SESSION_KEY:
return new KerberosSessionKey(key);
- }
+ case KRB5_GET_TKT_FLAGS:
+ return tktFlags.clone();
+ case KRB5_GET_AUTHZ_DATA:
+ if (isInitiator()) {
+ throw new GSSException(GSSException.UNAVAILABLE, -1,
+ "AuthzData not available on initiator side.");
+ } else {
+ return (authzData==null)?null:authzData.clone();
+ }
+ case KRB5_GET_AUTHTIME:
+ return authTime;
}
throw new GSSException(GSSException.UNAVAILABLE, -1,
"Inquire type not supported.");
}
+
+ // Helpers for inquireSecContext
+ private boolean[] tktFlags;
+ private String authTime;
+ private com.sun.security.jgss.AuthorizationDataEntry[] authzData;
+
+ public void setTktFlags(boolean[] tktFlags) {
+ this.tktFlags = tktFlags;
+ }
+
+ public void setAuthTime(String authTime) {
+ this.authTime = authTime;
+ }
+
+ public void setAuthzData(com.sun.security.jgss.AuthorizationDataEntry[] authzData) {
+ this.authzData = authzData;
+ }
}
--- a/jdk/src/share/classes/sun/security/krb5/Credentials.java Tue Aug 11 12:17:13 2009 +0800
+++ b/jdk/src/share/classes/sun/security/krb5/Credentials.java Tue Aug 11 12:20:32 2009 +0800
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-2009 Sun Microsystems, Inc. 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
@@ -63,6 +63,7 @@
KerberosTime renewTill;
HostAddresses cAddr;
EncryptionKey serviceKey;
+ AuthorizationData authzData;
private static boolean DEBUG = Krb5.DEBUG;
private static CredentialsCache cache;
static boolean alreadyLoaded = false;
@@ -78,6 +79,22 @@
KerberosTime new_startTime,
KerberosTime new_endTime,
KerberosTime renewTill,
+ HostAddresses cAddr,
+ AuthorizationData authzData) {
+ this(new_ticket, new_client, new_server, new_key, new_flags,
+ authTime, new_startTime, new_endTime, renewTill, cAddr);
+ this.authzData = authzData;
+ }
+
+ public Credentials(Ticket new_ticket,
+ PrincipalName new_client,
+ PrincipalName new_server,
+ EncryptionKey new_key,
+ TicketFlags new_flags,
+ KerberosTime authTime,
+ KerberosTime new_startTime,
+ KerberosTime new_endTime,
+ KerberosTime renewTill,
HostAddresses cAddr) {
ticket = new_ticket;
client = new_client;
@@ -213,6 +230,9 @@
return flags;
}
+ public AuthorizationData getAuthzData() {
+ return authzData;
+ }
/**
* Checks if the service ticket returned by the KDC has the OK-AS-DELEGATE
* flag set
--- a/jdk/src/share/classes/sun/security/krb5/KrbApReq.java Tue Aug 11 12:17:13 2009 +0800
+++ b/jdk/src/share/classes/sun/security/krb5/KrbApReq.java Tue Aug 11 12:20:32 2009 +0800
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-2009 Sun Microsystems, Inc. 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
@@ -356,12 +356,13 @@
authenticator.cname,
apReqMessg.ticket.sname,
enc_ticketPart.key,
- null,
+ enc_ticketPart.flags,
enc_ticketPart.authtime,
enc_ticketPart.starttime,
enc_ticketPart.endtime,
enc_ticketPart.renewTill,
- enc_ticketPart.caddr);
+ enc_ticketPart.caddr,
+ enc_ticketPart.authorizationData);
if (DEBUG) {
System.out.println(">>> KrbApReq: authenticate succeed.");
}
--- a/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java Tue Aug 11 12:17:13 2009 +0800
+++ b/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java Tue Aug 11 12:20:32 2009 +0800
@@ -174,4 +174,12 @@
}
return retVal;
}
+
+ public int count() {
+ return entry.length;
+ }
+
+ public AuthorizationDataEntry item(int i) {
+ return (AuthorizationDataEntry)entry[i].clone();
+ }
}
--- a/jdk/src/share/classes/sun/security/tools/PolicyTool.java Tue Aug 11 12:17:13 2009 +0800
+++ b/jdk/src/share/classes/sun/security/tools/PolicyTool.java Tue Aug 11 12:20:32 2009 +0800
@@ -3962,7 +3962,10 @@
super("InquireSecContextPermission",
"com.sun.security.jgss.InquireSecContextPermission",
new String[] {
- "KRB5_GET_SESSION_KEY"
+ "KRB5_GET_SESSION_KEY",
+ "KRB5_GET_TKT_FLAGS",
+ "KRB5_GET_AUTHZ_DATA",
+ "KRB5_GET_AUTHTIME"
},
null);
}
--- a/jdk/test/sun/security/krb5/auto/Context.java Tue Aug 11 12:17:13 2009 +0800
+++ b/jdk/test/sun/security/krb5/auto/Context.java Tue Aug 11 12:20:32 2009 +0800
@@ -41,6 +41,7 @@
import org.ietf.jgss.Oid;
import com.sun.security.jgss.ExtendedGSSContext;
import com.sun.security.jgss.InquireType;
+import com.sun.security.jgss.AuthorizationDataEntry;
/**
* Context of a JGSS subject, encapsulating Subject and GSSContext.
@@ -288,6 +289,23 @@
throw new Exception("Session key cannot be null");
}
System.out.println("Session key is: " + k);
+ boolean[] flags = (boolean[])ex.inquireSecContext(
+ InquireType.KRB5_GET_TKT_FLAGS);
+ if (flags == null) {
+ throw new Exception("Ticket flags cannot be null");
+ }
+ System.out.println("Ticket flags is: " + Arrays.toString(flags));
+ String authTime = (String)ex.inquireSecContext(
+ InquireType.KRB5_GET_AUTHTIME);
+ if (authTime == null) {
+ throw new Exception("Auth time cannot be null");
+ }
+ System.out.println("AuthTime is: " + authTime);
+ if (!x.isInitiator()) {
+ AuthorizationDataEntry[] ad = (AuthorizationDataEntry[])ex.inquireSecContext(
+ InquireType.KRB5_GET_AUTHZ_DATA);
+ System.out.println("AuthzData is: " + Arrays.toString(ad));
+ }
}
}
}