int print_ccaches (const char *in_name) { kim_error err = 0; kim_ccache primary_cache = NULL; int found_tgt = 0; /* Start by printing out the main ccache... either the default or inName */ if (!err) { if (in_name) { err = kim_ccache_create_from_display_name (&primary_cache, in_name); printiferr (err, "while locating credentials cache '%s'", in_name); } else { err = kim_ccache_create_from_default (&primary_cache); printiferr (err, "while locating the default credentials cache"); } } /* print the v5 tickets in mainCCache */ if (!err) { int found = 0; err = print_ccache (primary_cache, &found); if (!err) { found_tgt += found; } } if (show_all) { kim_ccache_iterator iterator = NULL; if (!err) { err = kim_ccache_iterator_create (&iterator); } while (!err) { kim_ccache ccache = NULL; kim_comparison comparison; err = kim_ccache_iterator_next (iterator, &ccache); if (!err && !ccache) { break; } if (!err) { err = kim_ccache_compare (ccache, primary_cache, &comparison); } /* if we haven't printed this ccache already, print it */ if (!err && !kim_comparison_is_equal_to (comparison)) { int found; /* Print spacing between caches in the list */ printfiller ('-', 79); printmsg ("\n"); err = print_ccache (ccache, &found); if (!err) { found_tgt += found; } } kim_ccache_free (&ccache); } kim_ccache_iterator_free (&iterator); } kim_ccache_free (&primary_cache); return (err || !found_tgt) ? 1 : 0; }
int print_ccache (kim_ccache in_ccache, int *out_found_valid_tgt) { kim_error err = 0; kim_credential_iterator iterator = NULL; kim_identity ccache_identity = NULL; kim_string type = NULL; kim_string name = NULL; kim_string ccache_identity_string = NULL; int found_tickets = 0; *out_found_valid_tgt = 0; if (!err) { err = kim_ccache_get_type (in_ccache, &type); printiferr (err, "while getting the ccache type"); } if (!err) { err = kim_ccache_get_name (in_ccache, &name); printiferr (err, "while getting the ccache name"); } if (!err) { err = kim_ccache_get_client_identity (in_ccache, &ccache_identity); printiferr (err, "while getting the ccache principal"); } if (!err) { err = kim_identity_get_display_string (ccache_identity, &ccache_identity_string); printiferr (err, "while unparsing the ccache principal name"); } if (!err) { printmsg ("Kerberos 5 ticket cache: '%s:%s'\nDefault principal: %s\n\n", type, name, ccache_identity_string); printmsg ("Valid Starting"); printfiller (' ', get_timestamp_width () - sizeof ("Valid Starting") + 3); printmsg ("Expires"); printfiller (' ', get_timestamp_width () - sizeof ("Expires") + 3); printmsg ("Service Principal\n"); err = kim_credential_iterator_create (&iterator, in_ccache); } while (!err) { kim_credential credential = NULL; kim_identity client = NULL; kim_identity service = NULL; kim_string client_string = NULL; kim_string service_string = NULL; krb5_creds *creds = NULL; int extra_field = 0; err = kim_credential_iterator_next (iterator, &credential); if (!err && !credential) { break; } if (!err) { err = kim_credential_get_client_identity (credential, &client); printiferr (err, "while getting the client principal"); } if (!err) { err = kim_identity_get_display_string (client, &client_string); printiferr (err, "while unparsing the client principal name"); } if (!err) { err = kim_credential_get_service_identity (credential, &service); printiferr (err, "while getting the service principal"); } if (!err) { err = kim_identity_get_display_string (service, &service_string); printiferr (err, "while unparsing the service principal name"); } if (!err) { err = kim_credential_get_krb5_creds (credential, kcontext, &creds); printiferr (err, "while getting krb5 creds"); } if (!err && krb5_is_config_principal(kcontext, creds->server)) goto next; if (!err) { found_tickets = 1; printtime (creds->times.starttime ? creds->times.starttime : creds->times.authtime); printmsg (" "); printtime (creds->times.endtime); printmsg (" "); printmsg ("%s\n", service_string); if (strcmp (ccache_identity_string, client_string)) { if (!extra_field) { printmsg ("\t"); } printmsg ("for client %s", client_string); extra_field++; } if (creds->ticket_flags & TKT_FLG_RENEWABLE) { printmsg (extra_field ? ", " : "\t"); printmsg ("renew until "); printtime (creds->times.renew_till); extra_field += 2; } if (extra_field > 2) { printmsg ("\n"); extra_field = 0; } if (show_flags) { printmsg (extra_field ? ", " : "\t"); printflags (creds->ticket_flags); extra_field++; } if (extra_field > 2) { printmsg ("\n"); extra_field = 0; } if (show_enctypes) { krb5_ticket *ticket_rep; if (krb5_decode_ticket (&creds->ticket, &ticket_rep) == 0) { if (!extra_field) { printmsg ("\t"); } else { printmsg (", "); } printmsg ("Etype (skey, tkt): %s, ", enctype_to_string (creds->keyblock.enctype)); printmsg ("%s ", enctype_to_string (ticket_rep->enc_part.enctype)); extra_field++; krb5_free_ticket (kcontext, ticket_rep); } } if (extra_field) { printmsg ("\n"); } if (show_address_list) { printmsg ("\tAddresses: "); if (!creds->addresses || !creds->addresses[0]) { printmsg ("(none)\n"); } else { int i; for (i = 0; creds->addresses[i]; i++) { if (i > 0) { printmsg (", "); } printaddress (*creds->addresses[i]); } printmsg ("\n"); } } if (extra_field) { printmsg ("\n"); } } if (!err) { kim_boolean is_tgt = 0; kim_credential_state state; err = kim_credential_is_tgt (credential, &is_tgt); printiferr (err, "while checking if creds are valid"); if (!err) { err = kim_credential_get_state (credential, &state); } if (!err && is_tgt && state == kim_credentials_state_valid) { *out_found_valid_tgt = 1; } } next: if (creds) { krb5_free_creds (kcontext, creds); } kim_string_free (&client_string); kim_string_free (&service_string); kim_identity_free (&client); kim_identity_free (&service); kim_credential_free (&credential); } kim_string_free (&type); kim_string_free (&name); kim_string_free (&ccache_identity_string); kim_identity_free (&ccache_identity); kim_credential_iterator_free (&iterator); if (!err) { if (!found_tickets) { printerr ("No Kerberos 5 tickets in credentials cache\n"); } else { printmsg ("\n"); } } return err; }
int print_keytab (const char *in_name) { krb5_error_code err = 0; krb5_keytab kt; krb5_keytab_entry entry; krb5_kt_cursor cursor; char keytab_name[BUFSIZ]; /* hopefully large enough for any type */ if (!err) { if (!in_name) { err = krb5_kt_default (kcontext, &kt); printiferr (err, "while resolving default keytab"); } else { err = krb5_kt_resolve (kcontext, in_name, &kt); printiferr (err, "while resolving keytab %s", in_name); } } if (!err) { err = krb5_kt_get_name (kcontext, kt, keytab_name, sizeof (keytab_name)); printiferr (err, "while getting keytab name"); } if (!err) { printmsg ("Keytab name: %s\n", keytab_name); } if (!err) { err = krb5_kt_start_seq_get (kcontext, kt, &cursor); printiferr (err, "while starting scan of keytab %s", keytab_name); } if (!err) { if (show_entry_timestamps) { printmsg ("KVNO Timestamp"); printfiller (' ', get_timestamp_width () - sizeof ("Timestamp") + 2); printmsg ("Principal\n"); printmsg ("---- "); printfiller ('-', get_timestamp_width ()); printmsg (" "); printfiller ('-', 78 - get_timestamp_width () - sizeof ("KVNO")); printmsg ("\n"); } else { printmsg("KVNO Principal\n"); printmsg("---- --------------------------------------------------------------------------\n"); } } while (!err) { char *principal_name = NULL; err = krb5_kt_next_entry (kcontext, kt, &entry, &cursor); if (err == KRB5_KT_END) { err = 0; break; } if (!err) { err = krb5_unparse_name (kcontext, entry.principal, &principal_name); printiferr (err, "while unparsing principal name"); } if (!err) { printmsg ("%4d ", entry.vno); if (show_entry_timestamps) { printtime (entry.timestamp); printmsg (" "); } printmsg ("%s", principal_name); if (show_enctypes) { printmsg (" (%s) ", enctype_to_string (entry.key.enctype)); } if (show_entry_DES_keys) { unsigned int i; printmsg (" (0x"); for (i = 0; i < entry.key.length; i++) { printmsg ("%02x", entry.key.contents[i]); } printmsg (")"); } printmsg ("\n"); } printiferr (err, "while scanning keytab %s", keytab_name); if (principal_name) { krb5_free_unparsed_name (kcontext, principal_name); } } if (!err) { err = krb5_kt_end_seq_get (kcontext, kt, &cursor); printiferr (err, "while ending scan of keytab %s", keytab_name); } return err ? 1 : 0; }
static int destroy_tickets (void) { krb5_error_code err = 0; if (cache_name) { kim_ccache ccache = NULL; err = kim_ccache_create_from_display_name (&ccache, cache_name); printiferr (err, "while locating credentials cache '%s'", cache_name); if (!err) { err = kim_ccache_destroy (&ccache); printiferr (err, "while destroying credentials cache '%s'", cache_name); } } else if (all) { /* Destroy all ticket caches */ kim_ccache_iterator iterator = NULL; err = kim_ccache_iterator_create (&iterator); while (!err) { kim_ccache ccache = NULL; err = kim_ccache_iterator_next (iterator, &ccache); if (!err) { if (ccache) { err = kim_ccache_destroy (&ccache); } else { break; /* no more ccaches */ } } } kim_ccache_iterator_free (&iterator); } else { /* Destroy the tickets by the principal or the default tickets */ kim_identity identity = KIM_IDENTITY_ANY; kim_ccache ccache = NULL; if (principal_name) { err = kim_identity_create_from_string (&identity, principal_name); printiferr (err, "while creating identity for '%s'", principal_name); } if (!err) { kim_ccache_create_from_client_identity (&ccache, identity); if (identity) { printiferr (err, "while getting ccache for '%s'", principal_name); } else { printiferr (err, "while getting default ccache"); } } if (!err) { err = kim_ccache_destroy (&ccache); printiferr (err, "while destroying tickets"); } kim_identity_free (&identity); } return err ? 1 : 0; }
/* * 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; }