8016594: Native Windows ccache still reads DES tickets
Reviewed-by: dsamersoff, xuelei
--- a/jdk/src/share/classes/sun/security/krb5/Credentials.java Thu Aug 08 09:16:16 2013 +0400
+++ b/jdk/src/share/classes/sun/security/krb5/Credentials.java Thu Aug 08 21:13:01 2013 +0800
@@ -62,7 +62,9 @@
private static CredentialsCache cache;
static boolean alreadyLoaded = false;
private static boolean alreadyTried = false;
- private static native Credentials acquireDefaultNativeCreds();
+
+ // Read native ticket with session key type in the given list
+ private static native Credentials acquireDefaultNativeCreds(int[] eTypes);
public Credentials(Ticket new_ticket,
PrincipalName new_client,
@@ -373,6 +375,8 @@
// It assumes that the GSS call has
// the privilege to access the default cache file.
+ // This method is only called on Windows and Mac OS X, the native
+ // acquireDefaultNativeCreds is also available on these platforms.
public static synchronized Credentials acquireDefaultCreds() {
Credentials result = null;
@@ -416,10 +420,15 @@
}
if (alreadyLoaded) {
// There is some native code
- if (DEBUG)
- System.out.println(">> Acquire default native Credentials");
- result = acquireDefaultNativeCreds();
- // only TGT with DES key will be returned by native method
+ if (DEBUG) {
+ System.out.println(">> Acquire default native Credentials");
+ }
+ try {
+ result = acquireDefaultNativeCreds(
+ EType.getDefaults("default_tkt_enctypes"));
+ } catch (KrbException ke) {
+ // when there is no default_tkt_enctypes.
+ }
}
}
return result;
--- a/jdk/src/share/native/sun/security/krb5/nativeccache.c Thu Aug 08 09:16:16 2013 +0400
+++ b/jdk/src/share/native/sun/security/krb5/nativeccache.c Thu Aug 08 21:13:01 2013 +0800
@@ -264,13 +264,21 @@
}
+int isIn(krb5_enctype e, int n, jint* etypes)
+{
+ int i;
+ for (i=0; i<n; i++) {
+ if (e == etypes[i]) return 1;
+ }
+ return 0;
+}
/*
* Class: sun_security_krb5_Credentials
* Method: acquireDefaultNativeCreds
- * Signature: ()Lsun/security/krb5/Credentials;
+ * Signature: ([I])Lsun/security/krb5/Credentials;
*/
JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds
-(JNIEnv *env, jclass krbcredsClass)
+(JNIEnv *env, jclass krbcredsClass, jintArray jetypes)
{
jobject krbCreds = NULL;
krb5_error_code err = 0;
@@ -280,6 +288,9 @@
krb5_flags flags = 0;
krb5_context kcontext = NULL;
+ int netypes;
+ jint *etypes = NULL;
+
/* Initialize the Kerberos 5 context */
err = krb5_init_context (&kcontext);
@@ -295,6 +306,9 @@
err = krb5_cc_start_seq_get (kcontext, ccache, &cursor);
}
+ netypes = (*env)->GetArrayLength(env, jetypes);
+ etypes = (jint *) (*env)->GetIntArrayElements(env, jetypes, NULL);
+
if (!err) {
while ((err = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) {
char *serverName = NULL;
@@ -305,7 +319,8 @@
}
if (!err) {
- if (strncmp (serverName, "krbtgt", strlen("krbtgt")) == 0) {
+ if (strncmp (serverName, "krbtgt", sizeof("krbtgt")-1) == 0 &&
+ isIn(creds.keyblock.enctype, netypes, etypes)) {
jobject ticket, clientPrincipal, targetPrincipal, encryptionKey;
jobject ticketFlags, startTime, endTime;
jobject authTime, renewTillTime, hostAddresses;
@@ -321,7 +336,7 @@
targetPrincipal = BuildClientPrincipal(env, kcontext, creds.server);
if (targetPrincipal == NULL) goto cleanup;
- // Build a com.ibm.security.krb5.Ticket
+ // Build a sun/security/krb5/internal/Ticket
ticket = BuildTicket(env, &creds.ticket);
if (ticket == NULL) goto cleanup;
@@ -353,7 +368,7 @@
krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "<init>",
"(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V");
if (krbcredsConstructor == 0) {
- printf("Couldn't find com.ibm.security.krb5.Credentials constructor\n");
+ printf("Couldn't find sun.security.krb5.internal.Ticket constructor\n");
break;
}
}
@@ -409,6 +424,10 @@
printiferr (err, "while finishing ticket retrieval");
}
+ if (etypes != NULL) {
+ (*env)->ReleaseIntArrayElements(env, jetypes, etypes, 0);
+ }
+
krb5_free_context (kcontext);
return krbCreds;
}
--- a/jdk/src/windows/native/sun/security/krb5/NativeCreds.c Thu Aug 08 09:16:16 2013 +0400
+++ b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c Thu Aug 08 21:13:01 2013 +0800
@@ -367,11 +367,12 @@
/*
* Class: sun_security_krb5_Credentials
* Method: acquireDefaultNativeCreds
- * Signature: ()Lsun/security/krb5/Credentials;
+ * Signature: ([I])Lsun/security/krb5/Credentials;
*/
JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds(
JNIEnv *env,
- jclass krbcredsClass) {
+ jclass krbcredsClass,
+ jintArray jetypes) {
KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
PKERB_RETRIEVE_TKT_RESPONSE TktCacheResponse = NULL;
@@ -387,9 +388,12 @@
jobject ticketFlags, startTime, endTime, krbCreds = NULL;
jobject authTime, renewTillTime, hostAddresses = NULL;
KERB_EXTERNAL_TICKET *msticket;
- int ignore_cache = 0;
+ int found_in_cache = 0;
FILETIME Now, EndTime, LocalEndTime;
+ int i, netypes;
+ jint *etypes = NULL;
+
while (TRUE) {
if (krbcredsConstructor == 0) {
@@ -456,31 +460,33 @@
// got the native MS TGT
msticket = &(TktCacheResponse->Ticket);
+ netypes = (*env)->GetArrayLength(env, jetypes);
+ etypes = (jint *) (*env)->GetIntArrayElements(env, jetypes, NULL);
+
// check TGT validity
- switch (msticket->SessionKey.KeyType) {
- case KERB_ETYPE_DES_CBC_CRC:
- case KERB_ETYPE_DES_CBC_MD5:
- case KERB_ETYPE_NULL:
- case KERB_ETYPE_RC4_HMAC_NT:
- GetSystemTimeAsFileTime(&Now);
- EndTime.dwLowDateTime = msticket->EndTime.LowPart;
- EndTime.dwHighDateTime = msticket->EndTime.HighPart;
- FileTimeToLocalFileTime(&EndTime, &LocalEndTime);
- if (CompareFileTime(&Now, &LocalEndTime) >= 0) {
- ignore_cache = 1;
- }
- if (msticket->TicketFlags & KERB_TICKET_FLAGS_invalid) {
- ignore_cache = 1;
- }
- break;
- case KERB_ETYPE_RC4_MD4:
- default:
- // not supported
- ignore_cache = 1;
- break;
+ if (native_debug) {
+ printf("LSA: TICKET SessionKey KeyType is %d\n", msticket->SessionKey.KeyType);
}
- if (ignore_cache) {
+ if ((msticket->TicketFlags & KERB_TICKET_FLAGS_invalid) == 0) {
+ GetSystemTimeAsFileTime(&Now);
+ EndTime.dwLowDateTime = msticket->EndTime.LowPart;
+ EndTime.dwHighDateTime = msticket->EndTime.HighPart;
+ FileTimeToLocalFileTime(&EndTime, &LocalEndTime);
+ if (CompareFileTime(&Now, &LocalEndTime) < 0) {
+ for (i=0; i<netypes; i++) {
+ if (etypes[i] == msticket->SessionKey.KeyType) {
+ found_in_cache = 1;
+ if (native_debug) {
+ printf("LSA: Valid etype found: %d\n", etypes[i]);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if (!found_in_cache) {
if (native_debug) {
printf("LSA: MS TGT in cache is invalid/not supported; request new ticket\n");
}
@@ -494,34 +500,41 @@
}
pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage;
- pTicketRequest->EncryptionType = KERB_ETYPE_DES_CBC_MD5;
pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_DONT_USE_CACHE;
- Status = LsaCallAuthenticationPackage(
- LogonHandle,
- PackageId,
- pTicketRequest,
- requestSize,
- &pTicketResponse,
- &responseSize,
- &SubStatus
- );
+ for (i=0; i<netypes; i++) {
+ pTicketRequest->EncryptionType = etypes[i];
+ Status = LsaCallAuthenticationPackage(
+ LogonHandle,
+ PackageId,
+ pTicketRequest,
+ requestSize,
+ &pTicketResponse,
+ &responseSize,
+ &SubStatus
+ );
- if (native_debug) {
- printf("LSA: Response size is %d\n", responseSize);
- }
+ if (native_debug) {
+ printf("LSA: Response size is %d for %d\n", responseSize, etypes[i]);
+ }
- if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus)) {
- if (!LSA_SUCCESS(Status)) {
- ShowNTError("LsaCallAuthenticationPackage", Status);
- } else {
- ShowNTError("Protocol status", SubStatus);
+ if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus)) {
+ if (!LSA_SUCCESS(Status)) {
+ ShowNTError("LsaCallAuthenticationPackage", Status);
+ } else {
+ ShowNTError("Protocol status", SubStatus);
+ }
+ continue;
}
+
+ // got the native MS Kerberos TGT
+ msticket = &(pTicketResponse->Ticket);
break;
}
+ }
- // got the native MS Kerberos TGT
- msticket = &(pTicketResponse->Ticket);
+ if (etypes != NULL) {
+ (*env)->ReleaseIntArrayElements(env, jetypes, etypes, 0);
}
/*
@@ -644,7 +657,7 @@
hostAddresses);
break;
- } // end of WHILE
+ } // end of WHILE. This WHILE will never loop.
// clean up resources
if (TktCacheResponse != NULL) {