From dc14220ea62b3cecf30d315f7edf8b1666b0237f Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 8 Aug 2013 21:13:01 +0800 Subject: [PATCH] 8016594: Native Windows ccache still reads DES tickets Reviewed-by: dsamersoff, xuelei --- .../sun/security/krb5/Credentials.java | 19 +++- .../native/sun/security/krb5/nativeccache.c | 29 ++++- .../native/sun/security/krb5/NativeCreds.c | 107 ++++++++++-------- 3 files changed, 98 insertions(+), 57 deletions(-) diff --git a/jdk/src/share/classes/sun/security/krb5/Credentials.java b/jdk/src/share/classes/sun/security/krb5/Credentials.java index bf4d57bb2b6..e0037da8846 100644 --- a/jdk/src/share/classes/sun/security/krb5/Credentials.java +++ b/jdk/src/share/classes/sun/security/krb5/Credentials.java @@ -62,7 +62,9 @@ public class Credentials { 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 @@ public class Credentials { // 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 @@ public class Credentials { } 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; diff --git a/jdk/src/share/native/sun/security/krb5/nativeccache.c b/jdk/src/share/native/sun/security/krb5/nativeccache.c index 5928dedb955..ccc7952c194 100644 --- a/jdk/src/share/native/sun/security/krb5/nativeccache.c +++ b/jdk/src/share/native/sun/security/krb5/nativeccache.c @@ -264,13 +264,21 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved) } +int isIn(krb5_enctype e, int n, jint* etypes) +{ + int i; + for (i=0; iGetArrayLength(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 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ } 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 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ 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 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "", "(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 @@ cleanup: printiferr (err, "while finishing ticket retrieval"); } + if (etypes != NULL) { + (*env)->ReleaseIntArrayElements(env, jetypes, etypes, 0); + } + krb5_free_context (kcontext); return krbCreds; } diff --git a/jdk/src/windows/native/sun/security/krb5/NativeCreds.c b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c index fce83640b63..db2940d9b72 100644 --- a/jdk/src/windows/native/sun/security/krb5/NativeCreds.c +++ b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c @@ -367,11 +367,12 @@ JNIEXPORT void JNICALL JNI_OnUnload( /* * 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 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ 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 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ // 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; iSessionKey.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 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ } 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; iEncryptionType = etypes[i]; + Status = LsaCallAuthenticationPackage( + LogonHandle, + PackageId, + pTicketRequest, + requestSize, + &pTicketResponse, + &responseSize, + &SubStatus + ); - if (native_debug) { - printf("LSA: Response size is %d\n", responseSize); - } - - if (!LSA_SUCCESS(Status) || !LSA_SUCCESS(SubStatus)) { - if (!LSA_SUCCESS(Status)) { - ShowNTError("LsaCallAuthenticationPackage", Status); - } else { - ShowNTError("Protocol status", SubStatus); + 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); + } + 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 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ hostAddresses); break; - } // end of WHILE + } // end of WHILE. This WHILE will never loop. // clean up resources if (TktCacheResponse != NULL) {