# HG changeset patch # User weijun # Date 1392777682 -28800 # Node ID d2db7c5718ca766640e700a3438b868e933e0a70 # Parent e9654c36f56d7a82fcedbbf8cbcb79a5ed99463e 8034033: [parfait] JNI exception pending in share/native/sun/security/krb5/nativeccache.c Reviewed-by: valeriep diff -r e9654c36f56d -r d2db7c5718ca jdk/src/share/native/sun/security/krb5/nativeccache.c --- a/jdk/src/share/native/sun/security/krb5/nativeccache.c Tue Feb 18 10:53:18 2014 -0800 +++ b/jdk/src/share/native/sun/security/krb5/nativeccache.c Wed Feb 19 10:41:22 2014 +0800 @@ -141,7 +141,7 @@ #endif /* DEBUG */ ticketConstructor = (*env)->GetMethodID(env, ticketClass, "", "(Lsun/security/util/DerValue;)V"); - if (derValueConstructor == 0) { + if (ticketConstructor == 0) { printf("Couldn't find Ticket constructor\n"); return JNI_ERR; } @@ -272,6 +272,7 @@ } return 0; } + /* * Class: sun_security_krb5_Credentials * Method: acquireDefaultNativeCreds @@ -309,7 +310,7 @@ netypes = (*env)->GetArrayLength(env, jetypes); etypes = (jint *) (*env)->GetIntArrayElements(env, jetypes, NULL); - if (!err) { + if (etypes != NULL && !err) { while ((err = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) { char *serverName = NULL; @@ -319,8 +320,16 @@ } if (!err) { - if (strncmp (serverName, "krbtgt", sizeof("krbtgt")-1) == 0 && - isIn(creds.keyblock.enctype, netypes, etypes)) { + char* slash = strchr(serverName, '/'); + char* at = strchr(serverName, '@'); + // Make sure the server's name is krbtgt/REALM@REALM, the etype + // is supported, and the ticket has not expired + if (slash && at && + strncmp (serverName, "krbtgt", slash-serverName) == 0 && + // the ablove line shows at must be after slash + strncmp (slash+1, at+1, at-slash-1) == 0 && + isIn (creds.keyblock.enctype, netypes, etypes) && + creds.times.endtime > time(0)) { jobject ticket, clientPrincipal, targetPrincipal, encryptionKey; jobject ticketFlags, startTime, endTime; jobject authTime, renewTillTime, hostAddresses; @@ -399,8 +408,12 @@ if (endTime) (*env)->DeleteLocalRef(env, endTime); if (renewTillTime) (*env)->DeleteLocalRef(env, renewTillTime); if (hostAddresses) (*env)->DeleteLocalRef(env, hostAddresses); + + // Stop if there is an exception or we already found the initial TGT + if ((*env)->ExceptionCheck(env) || krbCreds) { + break; + } } - } if (serverName != NULL) { krb5_free_unparsed_name (kcontext, serverName); } @@ -410,7 +423,6 @@ if (err == KRB5_CC_END) { err = 0; } printiferr (err, "while retrieving a ticket"); - } if (!err) { @@ -445,25 +457,25 @@ jbyteArray ary; ary = (*env)->NewByteArray(env, encodedTicket->length); - if ((*env)->ExceptionOccurred(env)) { + if ((*env)->ExceptionCheck(env)) { return (jobject) NULL; } (*env)->SetByteArrayRegion(env, ary, (jsize) 0, encodedTicket->length, (jbyte *)encodedTicket->data); - if ((*env)->ExceptionOccurred(env)) { + if ((*env)->ExceptionCheck(env)) { (*env)->DeleteLocalRef(env, ary); return (jobject) NULL; } derValue = (*env)->NewObject(env, derValueClass, derValueConstructor, ary); - if ((*env)->ExceptionOccurred(env)) { + if ((*env)->ExceptionCheck(env)) { (*env)->DeleteLocalRef(env, ary); return (jobject) NULL; } (*env)->DeleteLocalRef(env, ary); ticket = (*env)->NewObject(env, ticketClass, ticketConstructor, derValue); - if ((*env)->ExceptionOccurred(env)) { + if ((*env)->ExceptionCheck(env)) { (*env)->DeleteLocalRef(env, derValue); return (jobject) NULL; } @@ -480,6 +492,10 @@ if (!err) { // Make a PrincipalName from the full string and the type. Let the PrincipalName class parse it out. jstring principalStringObj = (*env)->NewStringUTF(env, principalString); + if (principalStringObj == NULL) { + if (principalString != NULL) { krb5_free_unparsed_name (kcontext, principalString); } + return (jobject) NULL; + } principal = (*env)->NewObject(env, principalNameClass, principalNameConstructor, principalStringObj, principalName->type); if (principalString != NULL) { krb5_free_unparsed_name (kcontext, principalString); } (*env)->DeleteLocalRef(env, principalStringObj); @@ -494,8 +510,13 @@ jobject encryptionKey = NULL; ary = (*env)->NewByteArray(env,cryptoKey->length); + + if (ary == NULL) { + return (jobject) NULL; + } + (*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->length, (jbyte *)cryptoKey->contents); - if (!(*env)->ExceptionOccurred(env)) { + if (!(*env)->ExceptionCheck(env)) { encryptionKey = (*env)->NewObject(env, encryptionKeyClass, encryptionKeyConstructor, cryptoKey->enctype, ary); } @@ -514,9 +535,14 @@ unsigned long nlflags = htonl(flags); ary = (*env)->NewByteArray(env, sizeof(flags)); + + if (ary == NULL) { + return (jobject) NULL; + } + (*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(flags), (jbyte *)&nlflags); - if (!(*env)->ExceptionOccurred(env)) { + if (!(*env)->ExceptionCheck(env)) { ticketFlags = (*env)->NewObject(env, ticketFlagsClass, ticketFlagsConstructor, sizeof(flags)*8, ary); } @@ -550,6 +576,10 @@ jobject address_list = (*env)->NewObjectArray(env, addressCount, hostAddressClass, NULL); + if (address_list == NULL) { + return (jobject) NULL; + } + // Create a new HostAddress object for each address block. // First, reset the iterator. p = addresses; @@ -567,9 +597,16 @@ (*env)->DeleteLocalRef(env, ary); + if (address == NULL) { + return (jobject) NULL; + } // Add the HostAddress to the arrray. (*env)->SetObjectArrayElement(env, address_list, index, address); + if ((*env)->ExceptionCheck(env)) { + return (jobject) NULL; + } + index++; p++; }