8034033: [parfait] JNI exception pending in share/native/sun/security/krb5/nativeccache.c

Reviewed-by: valeriep
This commit is contained in:
Weijun Wang 2014-02-19 10:41:22 +08:00
parent 25167ae738
commit 368816ed8d

View File

@ -141,7 +141,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
#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 @@ int isIn(krb5_enctype e, int n, jint* etypes)
}
return 0;
}
/*
* Class: sun_security_krb5_Credentials
* Method: acquireDefaultNativeCreds
@ -309,7 +310,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ
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 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ
}
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 @@ cleanup:
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 @@ cleanup:
if (err == KRB5_CC_END) { err = 0; }
printiferr (err, "while retrieving a ticket");
}
if (!err) {
@ -445,25 +457,25 @@ jobject BuildTicket(JNIEnv *env, krb5_data *encodedTicket)
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 @@ jobject BuildClientPrincipal(JNIEnv *env, krb5_context kcontext, krb5_principal
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 BuildEncryptionKey(JNIEnv *env, krb5_keyblock *cryptoKey) {
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 @@ jobject BuildTicketFlags(JNIEnv *env, krb5_flags flags) {
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 BuildAddressList(JNIEnv *env, krb5_address **addresses) {
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 @@ jobject BuildAddressList(JNIEnv *env, krb5_address **addresses) {
(*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++;
}