#include #include #include #if HAVE_SRAND48 #define RAND() lrand48() #define SRAND(a) srand48(a) #define RAND_TYPE long #elif HAVE_SRAND #define RAND() rand() #define SRAND(a) srand(a) #define RAND_TYPE int #elif HAVE_SRANDOM #define RAND() random() #define SRAND(a) srandom(a) #define RAND_TYPE long #else /* no random */ need a random number generator #endif /* no random */ krb5_keyblock test1[] = { {0, ENCTYPE_DES_CBC_CRC, 0, 0}, {-1}, }; krb5_keyblock test2[] = { {0, ENCTYPE_DES_CBC_RAW, 0, 0}, {-1}, }; krb5_keyblock test3[] = { {0, ENCTYPE_DES_CBC_MD5, 0, 0}, {-1}, }; krb5_keyblock *tests[] = { test1, test2, test3, NULL }; #if 0 int keyblocks_equal(krb5_keyblock *kb1, krb5_keyblock *kb2) { return (kb1->enctype == kb2->enctype && kb1->length == kb2->length && memcmp(kb1->contents, kb2->contents, kb1->length) == 0); } #endif krb5_data tgtname = { 0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME }; krb5_enctype ktypes[] = { 0, 0 }; extern krb5_kt_ops krb5_ktf_writable_ops; int main(int argc, char **argv) { krb5_context context; krb5_keytab kt; krb5_keytab_entry ktent; krb5_encrypt_block eblock; krb5_creds my_creds; kadm5_principal_ent_rec princ_ent; krb5_principal princ, server; char pw[16]; char *whoami, *principal, *authprinc; krb5_data pwdata; void *handle; int ret, i, test, encnum; whoami = argv[0]; if (argc != 2 && argc != 3) { fprintf(stderr, "Usage: %s principal [authuser]\n", whoami); exit(1); } principal = argv[1]; authprinc = argv[2] ? argv[2] : argv[0]; /* * Setup. Initialize data structures, open keytab, open connection * to kadm5 server. */ memset(&context, 0, sizeof(context)); kadm5_init_krb5_context(&context); ret = krb5_parse_name(context, principal, &princ); if (ret) { com_err(whoami, ret, "while parsing principal name %s", principal); exit(1); } if((ret = krb5_build_principal_ext(context, &server, krb5_princ_realm(kcontext, princ)->length, krb5_princ_realm(kcontext, princ)->data, tgtname.length, tgtname.data, krb5_princ_realm(kcontext, princ)->length, krb5_princ_realm(kcontext, princ)->data, 0))) { com_err(whoami, ret, "while building server name"); exit(1); } /* register the WRFILE keytab type */ ret = krb5_kt_register(context, &krb5_ktf_writable_ops); if (ret) { com_err(whoami, ret, "while registering writable key table functions"); exit(1); } ret = krb5_kt_default(context, &kt); if (ret) { com_err(whoami, ret, "while opening keytab"); exit(1); } ret = kadm5_init(authprinc, NULL, KADM5_ADMIN_SERVICE, NULL, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, NULL, &handle); if (ret) { com_err(whoami, ret, "while initializing connection"); exit(1); } /* these pw's don't need to be secure, just different every time */ SRAND((RAND_TYPE)time((void *) NULL)); pwdata.data = pw; pwdata.length = sizeof(pw); /* * For each test: * * For each enctype in the test, construct a random password/key. * Assign all keys to principal with kadm5_setkey_principal. Add * each key to the keytab, and acquire an initial ticket with the * keytab (XXX can I specify the enctype & kvno explicitly?). If * krb5_get_in_tkt_with_keytab succeeds, then the keys were set * successfully. */ for (test = 0; tests[test] != NULL; test++) { krb5_keyblock *testp = tests[test]; printf("+ Test %d:\n", test); for (encnum = 0; testp[encnum].magic != -1; encnum++) { for (i = 0; i < sizeof(pw); i++) pw[i] = (RAND() % 26) + '0'; /* XXX */ krb5_use_enctype(context, &eblock, testp[encnum].enctype); ret = krb5_string_to_key(context, &eblock, &testp[encnum], &pwdata, NULL); if (ret) { com_err(whoami, ret, "while converting string to key"); exit(1); } } /* now, encnum == # of keyblocks in testp */ ret = kadm5_setkey_principal(handle, princ, testp, encnum); if (ret) { com_err(whoami, ret, "while setting keys"); exit(1); } ret = kadm5_get_principal(handle, princ, &princ_ent, KADM5_KVNO); if (ret) { com_err(whoami, ret, "while retrieving principal"); exit(1); } for (encnum = 0; testp[encnum].magic != -1; encnum++) { printf("+ enctype %d\n", testp[encnum].enctype); memset(&ktent, 0, sizeof(ktent)); ktent.principal = princ; ktent.key = testp[encnum]; ktent.vno = princ_ent.kvno; ret = krb5_kt_add_entry(context, kt, &ktent); if (ret) { com_err(whoami, ret, "while adding keytab entry"); exit(1); } memset(&my_creds, 0, sizeof(my_creds)); my_creds.client = princ; my_creds.server = server; ktypes[0] = testp[encnum].enctype; ret = krb5_get_in_tkt_with_keytab(context, 0 /* options */, NULL /* addrs */, ktypes, NULL /* preauth */, kt, 0, &my_creds, 0); if (ret) { com_err(whoami, ret, "while acquiring initial ticket"); exit(1); } /* since I can't specify enctype explicitly ... */ ret = krb5_kt_remove_entry(context, kt, &ktent); if (ret) { com_err(whoami, ret, "while removing keytab entry"); exit(1); } } } ret = krb5_kt_close(context, kt); if (ret) { com_err(whoami, ret, "while closing keytab"); exit(1); } ret = kadm5_destroy(handle); if (ret) { com_err(whoami, ret, "while closing kadmin connection"); exit(1); } return 0; }