|
Packit |
fd8b60 |
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
Packit |
fd8b60 |
#include <k5-int.h>
|
|
Packit |
fd8b60 |
#include <kadm5/admin.h>
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#if HAVE_SRAND48
|
|
Packit |
fd8b60 |
#define RAND() lrand48()
|
|
Packit |
fd8b60 |
#define SRAND(a) srand48(a)
|
|
Packit |
fd8b60 |
#define RAND_TYPE long
|
|
Packit |
fd8b60 |
#elif HAVE_SRAND
|
|
Packit |
fd8b60 |
#define RAND() rand()
|
|
Packit |
fd8b60 |
#define SRAND(a) srand(a)
|
|
Packit |
fd8b60 |
#define RAND_TYPE int
|
|
Packit |
fd8b60 |
#elif HAVE_SRANDOM
|
|
Packit |
fd8b60 |
#define RAND() random()
|
|
Packit |
fd8b60 |
#define SRAND(a) srandom(a)
|
|
Packit |
fd8b60 |
#define RAND_TYPE long
|
|
Packit |
fd8b60 |
#else /* no random */
|
|
Packit |
fd8b60 |
need a random number generator
|
|
Packit |
fd8b60 |
#endif /* no random */
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_keyblock test1[] = {
|
|
Packit |
fd8b60 |
{0, ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0, 0},
|
|
Packit |
fd8b60 |
{-1},
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
krb5_keyblock test2[] = {
|
|
Packit |
fd8b60 |
{0, ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0, 0},
|
|
Packit |
fd8b60 |
{-1},
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
krb5_keyblock test3[] = {
|
|
Packit |
fd8b60 |
{0, ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0, 0},
|
|
Packit |
fd8b60 |
{-1},
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_keyblock *tests[] = {
|
|
Packit |
fd8b60 |
test1, test2, test3, NULL
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_data tgtname = {
|
|
Packit |
fd8b60 |
0,
|
|
Packit |
fd8b60 |
KRB5_TGS_NAME_SIZE,
|
|
Packit |
fd8b60 |
KRB5_TGS_NAME
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_enctype ktypes[] = { 0, 0 };
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
extern krb5_kt_ops krb5_ktf_writable_ops;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
int
|
|
Packit |
fd8b60 |
main(int argc, char **argv)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_context context;
|
|
Packit |
fd8b60 |
krb5_keytab kt;
|
|
Packit |
fd8b60 |
krb5_keytab_entry ktent;
|
|
Packit |
fd8b60 |
krb5_encrypt_block eblock;
|
|
Packit |
fd8b60 |
krb5_creds my_creds;
|
|
Packit |
fd8b60 |
krb5_get_init_creds_opt *opt;
|
|
Packit |
fd8b60 |
kadm5_principal_ent_rec princ_ent;
|
|
Packit |
fd8b60 |
krb5_principal princ, server;
|
|
Packit |
fd8b60 |
char pw[16];
|
|
Packit |
fd8b60 |
char *whoami, *principal, *authprinc, *authpwd;
|
|
Packit |
fd8b60 |
krb5_data pwdata;
|
|
Packit |
fd8b60 |
void *handle;
|
|
Packit |
fd8b60 |
int ret, test, encnum;
|
|
Packit |
fd8b60 |
unsigned int i;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
whoami = argv[0];
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (argc < 2 || argc > 4) {
|
|
Packit |
fd8b60 |
fprintf(stderr, "Usage: %s principal [authuser] [authpwd]\n", whoami);
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
principal = argv[1];
|
|
Packit |
fd8b60 |
authprinc = (argc > 2) ? argv[2] : argv[0];
|
|
Packit |
fd8b60 |
authpwd = (argc > 3) ? argv[3] : NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Setup. Initialize data structures, open keytab, open connection
|
|
Packit |
fd8b60 |
* to kadm5 server.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
memset(&context, 0, sizeof(context));
|
|
Packit |
fd8b60 |
kadm5_init_krb5_context(&context);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = krb5_parse_name(context, principal, &princ);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while parsing principal name %s", principal);
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if((ret = krb5_build_principal_ext(context, &server,
|
|
Packit |
fd8b60 |
krb5_princ_realm(kcontext, princ)->length,
|
|
Packit |
fd8b60 |
krb5_princ_realm(kcontext, princ)->data,
|
|
Packit |
fd8b60 |
tgtname.length, tgtname.data,
|
|
Packit |
fd8b60 |
krb5_princ_realm(kcontext, princ)->length,
|
|
Packit |
fd8b60 |
krb5_princ_realm(kcontext, princ)->data,
|
|
Packit |
fd8b60 |
0))) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while building server name");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = krb5_kt_default(context, &kt;;
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while opening keytab");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = kadm5_init(context, authprinc, authpwd, KADM5_ADMIN_SERVICE, NULL,
|
|
Packit |
fd8b60 |
KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL,
|
|
Packit |
fd8b60 |
&handle);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while initializing connection");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* these pw's don't need to be secure, just different every time */
|
|
Packit |
fd8b60 |
SRAND((RAND_TYPE)time((void *) NULL));
|
|
Packit |
fd8b60 |
pwdata.data = pw;
|
|
Packit |
fd8b60 |
pwdata.length = sizeof(pw);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* For each test:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* For each enctype in the test, construct a random password/key.
|
|
Packit |
fd8b60 |
* Assign all keys to principal with kadm5_setkey_principal. Add
|
|
Packit |
fd8b60 |
* each key to the keytab, and acquire an initial ticket with the
|
|
Packit |
fd8b60 |
* keytab (XXX can I specify the kvno explicitly?). If
|
|
Packit |
fd8b60 |
* krb5_get_init_creds_keytab succeeds, then the keys were set
|
|
Packit |
fd8b60 |
* successfully.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
for (test = 0; tests[test] != NULL; test++) {
|
|
Packit |
fd8b60 |
krb5_keyblock *testp = tests[test];
|
|
Packit |
fd8b60 |
kadm5_key_data *extracted;
|
|
Packit |
fd8b60 |
int n_extracted, match;
|
|
Packit |
fd8b60 |
printf("+ Test %d:\n", test);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for (encnum = 0; testp[encnum].magic != -1; encnum++) {
|
|
Packit |
fd8b60 |
for (i = 0; i < sizeof(pw); i++)
|
|
Packit |
fd8b60 |
pw[i] = (RAND() % 26) + '0'; /* XXX */
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_use_enctype(context, &eblock, testp[encnum].enctype);
|
|
Packit |
fd8b60 |
ret = krb5_string_to_key(context, &eblock, &testp[encnum],
|
|
Packit |
fd8b60 |
&pwdata, NULL);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while converting string to key");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* now, encnum == # of keyblocks in testp */
|
|
Packit |
fd8b60 |
ret = kadm5_setkey_principal(handle, princ, testp, encnum);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while setting keys");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = kadm5_get_principal(handle, princ, &princ_ent, KADM5_KVNO);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while retrieving principal");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = kadm5_get_principal_keys(handle, princ, 0, &extracted,
|
|
Packit |
fd8b60 |
&n_extracted);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while extracting keys");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for (encnum = 0; testp[encnum].magic != -1; encnum++) {
|
|
Packit |
fd8b60 |
printf("+ enctype %d\n", testp[encnum].enctype);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for (match = 0; match < n_extracted; match++) {
|
|
Packit |
fd8b60 |
if (extracted[match].key.enctype == testp[encnum].enctype)
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (match >= n_extracted) {
|
|
Packit |
fd8b60 |
com_err(whoami, KRB5_WRONG_ETYPE, "while matching enctypes");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (extracted[match].key.length != testp[encnum].length ||
|
|
Packit |
fd8b60 |
memcmp(extracted[match].key.contents, testp[encnum].contents,
|
|
Packit |
fd8b60 |
testp[encnum].length) != 0) {
|
|
Packit |
fd8b60 |
com_err(whoami, KRB5_KDB_NO_MATCHING_KEY, "verifying keys");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
memset(&ktent, 0, sizeof(ktent));
|
|
Packit |
fd8b60 |
ktent.principal = princ;
|
|
Packit |
fd8b60 |
ktent.key = testp[encnum];
|
|
Packit |
fd8b60 |
ktent.vno = princ_ent.kvno;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = krb5_kt_add_entry(context, kt, &ktent);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while adding keytab entry");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
memset(&my_creds, 0, sizeof(my_creds));
|
|
Packit |
fd8b60 |
my_creds.client = princ;
|
|
Packit |
fd8b60 |
my_creds.server = server;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ktypes[0] = testp[encnum].enctype;
|
|
Packit |
fd8b60 |
ret = krb5_get_init_creds_opt_alloc(context, &opt;;
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while allocating gic opts");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
krb5_get_init_creds_opt_set_etype_list(opt, ktypes, 1);
|
|
Packit |
fd8b60 |
ret = krb5_get_init_creds_keytab(context, &my_creds, princ,
|
|
Packit |
fd8b60 |
kt, 0, NULL /* in_tkt_service */,
|
|
Packit |
fd8b60 |
opt);
|
|
Packit |
fd8b60 |
krb5_get_init_creds_opt_free(context, opt);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while acquiring initial ticket");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
krb5_free_cred_contents(context, &my_creds);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* since I can't specify enctype explicitly ... */
|
|
Packit |
fd8b60 |
ret = krb5_kt_remove_entry(context, kt, &ktent);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while removing keytab entry");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)kadm5_free_kadm5_key_data(context, n_extracted, extracted);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = krb5_kt_close(context, kt);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while closing keytab");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = kadm5_destroy(handle);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
com_err(whoami, ret, "while closing kadmin connection");
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5_free_principal(context, princ);
|
|
Packit |
fd8b60 |
krb5_free_principal(context, server);
|
|
Packit |
fd8b60 |
krb5_free_context(context);
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|