/* * Class: sun_security_krb5_Credentials * Method: acquireDefaultNativeCreds * Signature: ([I])Lsun/security/krb5/Credentials; */ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds (JNIEnv *env, jclass krbcredsClass, jintArray jetypes) { jobject krbCreds = NULL; krb5_error_code err = 0; krb5_ccache ccache = NULL; krb5_cc_cursor cursor = NULL; krb5_creds creds; krb5_flags flags = 0; krb5_context kcontext = NULL; int netypes; jint *etypes = NULL; /* Initialize the Kerberos 5 context */ err = krb5_init_context (&kcontext); if (!err) { err = krb5_cc_default (kcontext, &ccache); } if (!err) { err = krb5_cc_set_flags (kcontext, ccache, flags); /* turn off OPENCLOSE */ } if (!err) { err = krb5_cc_start_seq_get (kcontext, ccache, &cursor); } netypes = (*env)->GetArrayLength(env, jetypes); etypes = (jint *) (*env)->GetIntArrayElements(env, jetypes, NULL); if (etypes != NULL && !err) { while ((err = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) { char *serverName = NULL; if (!err) { err = krb5_unparse_name (kcontext, creds.server, &serverName); printiferr (err, "while unparsing server name"); } if (!err) { 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; ticket = clientPrincipal = targetPrincipal = encryptionKey = NULL; ticketFlags = startTime = endTime = NULL; authTime = renewTillTime = hostAddresses = NULL; // For the default credentials we're only interested in the krbtgt server. clientPrincipal = BuildClientPrincipal(env, kcontext, creds.client); if (clientPrincipal == NULL) goto cleanup; targetPrincipal = BuildClientPrincipal(env, kcontext, creds.server); if (targetPrincipal == NULL) goto cleanup; // Build a sun/security/krb5/internal/Ticket ticket = BuildTicket(env, &creds.ticket); if (ticket == NULL) goto cleanup; // Get the encryption key encryptionKey = BuildEncryptionKey(env, &creds.keyblock); if (encryptionKey == NULL) goto cleanup; // and the ticket flags ticketFlags = BuildTicketFlags(env, creds.ticket_flags); if (ticketFlags == NULL) goto cleanup; // Get the timestamps out. startTime = BuildKerberosTime(env, creds.times.starttime); if (startTime == NULL) goto cleanup; authTime = BuildKerberosTime(env, creds.times.authtime); if (authTime == NULL) goto cleanup; endTime = BuildKerberosTime(env, creds.times.endtime); if (endTime == NULL) goto cleanup; renewTillTime = BuildKerberosTime(env, creds.times.renew_till); if (renewTillTime == NULL) goto cleanup; // Create the addresses object. hostAddresses = BuildAddressList(env, creds.addresses); if (krbcredsConstructor == 0) { 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 sun.security.krb5.internal.Ticket constructor\n"); break; } } // and now go build a KrbCreds object krbCreds = (*env)->NewObject( env, krbcredsClass, krbcredsConstructor, ticket, clientPrincipal, targetPrincipal, encryptionKey, ticketFlags, authTime, startTime, endTime, renewTillTime, hostAddresses); cleanup: if (ticket) (*env)->DeleteLocalRef(env, ticket); if (clientPrincipal) (*env)->DeleteLocalRef(env, clientPrincipal); if (targetPrincipal) (*env)->DeleteLocalRef(env, targetPrincipal); if (encryptionKey) (*env)->DeleteLocalRef(env, encryptionKey); if (ticketFlags) (*env)->DeleteLocalRef(env, ticketFlags); if (authTime) (*env)->DeleteLocalRef(env, authTime); if (startTime) (*env)->DeleteLocalRef(env, startTime); 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); } krb5_free_cred_contents (kcontext, &creds); } if (err == KRB5_CC_END) { err = 0; } printiferr (err, "while retrieving a ticket"); } if (!err) { err = krb5_cc_end_seq_get (kcontext, ccache, &cursor); printiferr (err, "while finishing ticket retrieval"); } if (!err) { flags = KRB5_TC_OPENCLOSE; /* restore OPENCLOSE mode */ err = krb5_cc_set_flags (kcontext, ccache, flags); printiferr (err, "while finishing ticket retrieval"); } if (etypes != NULL) { (*env)->ReleaseIntArrayElements(env, jetypes, etypes, 0); } krb5_free_context (kcontext); return krbCreds; }
/* * Class: sun_security_krb5_Credentials * Method: acquireDefaultNativeCreds * Signature: ()Lsun/security/krb5/Credentials; */ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds (JNIEnv *env, jclass krbcredsClass) { jobject krbCreds = NULL; krb5_error_code err = 0; krb5_ccache ccache = NULL; krb5_cc_cursor cursor = NULL; krb5_creds creds; krb5_flags flags = 0; krb5_context kcontext = NULL; /* Initialize the Kerberos 5 context */ err = krb5_init_context (&kcontext); if (!err) { err = krb5_cc_default (kcontext, &ccache); } if (!err) { err = krb5_cc_set_flags (kcontext, ccache, flags); /* turn off OPENCLOSE */ } if (!err) { err = krb5_cc_start_seq_get (kcontext, ccache, &cursor); } if (!err) { while ((err = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) { char *serverName = NULL; if (!err) { err = krb5_unparse_name (kcontext, creds.server, &serverName); printiferr (err, "while unparsing server name"); } if (!err) { if (strncmp (serverName, "krbtgt", strlen("krbtgt")) == 0) { jobject ticket, clientPrincipal, targetPrincipal, encryptionKey; jobject ticketFlags, startTime, endTime; jobject authTime, renewTillTime, hostAddresses; ticket = clientPrincipal = targetPrincipal = encryptionKey = NULL; ticketFlags = startTime = endTime = NULL; authTime = renewTillTime = hostAddresses = NULL; // For the default credentials we're only interested in the krbtgt server. clientPrincipal = BuildClientPrincipal(env, kcontext, creds.client); if (clientPrincipal == NULL) goto cleanup; targetPrincipal = BuildClientPrincipal(env, kcontext, creds.server); if (targetPrincipal == NULL) goto cleanup; // Build a com.ibm.security.krb5.Ticket ticket = BuildTicket(env, &creds.ticket); if (ticket == NULL) goto cleanup; // Get the encryption key encryptionKey = BuildEncryptionKey(env, &creds.keyblock); if (encryptionKey == NULL) goto cleanup; // and the ticket flags ticketFlags = BuildTicketFlags(env, creds.ticket_flags); if (ticketFlags == NULL) goto cleanup; // Get the timestamps out. startTime = BuildKerberosTime(env, creds.times.starttime); if (startTime == NULL) goto cleanup; authTime = BuildKerberosTime(env, creds.times.authtime); if (authTime == NULL) goto cleanup; endTime = BuildKerberosTime(env, creds.times.endtime); if (endTime == NULL) goto cleanup; renewTillTime = BuildKerberosTime(env, creds.times.renew_till); if (renewTillTime == NULL) goto cleanup; // Create the addresses object. hostAddresses = BuildAddressList(env, creds.addresses); if (krbcredsConstructor == 0) { 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"); break; } } // and now go build a KrbCreds object krbCreds = (*env)->NewObject( env, krbcredsClass, krbcredsConstructor, ticket, clientPrincipal, targetPrincipal, encryptionKey, ticketFlags, authTime, startTime, endTime, renewTillTime, hostAddresses); cleanup: if (ticket) (*env)->DeleteLocalRef(env, ticket); if (clientPrincipal) (*env)->DeleteLocalRef(env, clientPrincipal); if (targetPrincipal) (*env)->DeleteLocalRef(env, targetPrincipal); if (encryptionKey) (*env)->DeleteLocalRef(env, encryptionKey); if (ticketFlags) (*env)->DeleteLocalRef(env, ticketFlags); if (authTime) (*env)->DeleteLocalRef(env, authTime); if (startTime) (*env)->DeleteLocalRef(env, startTime); if (endTime) (*env)->DeleteLocalRef(env, endTime); if (renewTillTime) (*env)->DeleteLocalRef(env, renewTillTime); if (hostAddresses) (*env)->DeleteLocalRef(env, hostAddresses); } } if (serverName != NULL) { krb5_free_unparsed_name (kcontext, serverName); } krb5_free_cred_contents (kcontext, &creds); } if (err == KRB5_CC_END) { err = 0; } printiferr (err, "while retrieving a ticket"); } if (!err) { err = krb5_cc_end_seq_get (kcontext, ccache, &cursor); printiferr (err, "while finishing ticket retrieval"); } if (!err) { flags = KRB5_TC_OPENCLOSE; /* restore OPENCLOSE mode */ err = krb5_cc_set_flags (kcontext, ccache, flags); printiferr (err, "while finishing ticket retrieval"); } krb5_free_context (kcontext); return krbCreds; }