8034033: [parfait] JNI exception pending in share/native/sun/security/krb5/nativeccache.c
authorweijun
Wed, 19 Feb 2014 10:41:22 +0800
changeset 22986 d2db7c5718ca
parent 22985 e9654c36f56d
child 22987 c1ed1403241e
8034033: [parfait] JNI exception pending in share/native/sun/security/krb5/nativeccache.c Reviewed-by: valeriep
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, "<init>", "(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++;
     }