summaryrefslogtreecommitdiff
path: root/src/lib/kadm5/unit-test/setkey-test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/kadm5/unit-test/setkey-test.c')
-rw-r--r--src/lib/kadm5/unit-test/setkey-test.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/lib/kadm5/unit-test/setkey-test.c b/src/lib/kadm5/unit-test/setkey-test.c
new file mode 100644
index 0000000000000..60be9e85d5d32
--- /dev/null
+++ b/src/lib/kadm5/unit-test/setkey-test.c
@@ -0,0 +1,254 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+#include <k5-int.h>
+#include <kadm5/admin.h>
+
+#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_CRC, 0, 0},
+ {-1},
+};
+krb5_keyblock test3[] = {
+ {0, ENCTYPE_DES_CBC_CRC, 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;
+ krb5_get_init_creds_opt *opt;
+ kadm5_principal_ent_rec princ_ent;
+ krb5_principal princ, server;
+ char pw[16];
+ char *whoami, *principal, *authprinc, *authpwd;
+ krb5_data pwdata;
+ void *handle;
+ int ret, i, test, encnum;
+
+ whoami = argv[0];
+
+ if (argc < 2 || argc > 4) {
+ fprintf(stderr, "Usage: %s principal [authuser] [authpwd]\n", whoami);
+ exit(1);
+ }
+ principal = argv[1];
+ authprinc = (argc > 2) ? argv[2] : argv[0];
+ authpwd = (argc > 3) ? argv[3] : NULL;
+
+ /*
+ * 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);
+ }
+
+ ret = krb5_kt_default(context, &kt);
+ if (ret) {
+ com_err(whoami, ret, "while opening keytab");
+ exit(1);
+ }
+
+ ret = kadm5_init(context, authprinc, authpwd, KADM5_ADMIN_SERVICE, NULL,
+ KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, 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 kvno explicitly?). If
+ * krb5_get_init_creds_keytab succeeds, then the keys were set
+ * successfully.
+ */
+ for (test = 0; tests[test] != NULL; test++) {
+ krb5_keyblock *testp = tests[test];
+ kadm5_key_data *extracted;
+ int n_extracted, match;
+ 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);
+ }
+
+ ret = kadm5_get_principal_keys(handle, princ, 0, &extracted,
+ &n_extracted);
+ if (ret) {
+ com_err(whoami, ret, "while extracting keys");
+ exit(1);
+ }
+
+ for (encnum = 0; testp[encnum].magic != -1; encnum++) {
+ printf("+ enctype %d\n", testp[encnum].enctype);
+
+ for (match = 0; match < n_extracted; match++) {
+ if (extracted[match].key.enctype == testp[encnum].enctype)
+ break;
+ }
+ if (match >= n_extracted) {
+ com_err(whoami, KRB5_WRONG_ETYPE, "while matching enctypes");
+ exit(1);
+ }
+ if (extracted[match].key.length != testp[encnum].length ||
+ memcmp(extracted[match].key.contents, testp[encnum].contents,
+ testp[encnum].length) != 0) {
+ com_err(whoami, KRB5_KDB_NO_MATCHING_KEY, "verifying keys");
+ exit(1);
+ }
+
+ 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_init_creds_opt_alloc(context, &opt);
+ if (ret) {
+ com_err(whoami, ret, "while allocating gic opts");
+ exit(1);
+ }
+ krb5_get_init_creds_opt_set_etype_list(opt, ktypes, 1);
+ ret = krb5_get_init_creds_keytab(context, &my_creds, princ,
+ kt, 0, NULL /* in_tkt_service */,
+ opt);
+ krb5_get_init_creds_opt_free(context, opt);
+ if (ret) {
+ com_err(whoami, ret, "while acquiring initial ticket");
+ exit(1);
+ }
+ krb5_free_cred_contents(context, &my_creds);
+
+ /* 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);
+ }
+ }
+
+ (void)kadm5_free_kadm5_key_data(context, n_extracted, extracted);
+ }
+
+ 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);
+ }
+
+ krb5_free_principal(context, princ);
+ krb5_free_principal(context, server);
+ krb5_free_context(context);
+ return 0;
+}