summaryrefslogtreecommitdiffstats
path: root/src/lib/kadm/t_ktentry.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/kadm/t_ktentry.c')
-rw-r--r--src/lib/kadm/t_ktentry.c402
1 files changed, 402 insertions, 0 deletions
diff --git a/src/lib/kadm/t_ktentry.c b/src/lib/kadm/t_ktentry.c
new file mode 100644
index 000000000..0367947f2
--- /dev/null
+++ b/src/lib/kadm/t_ktentry.c
@@ -0,0 +1,402 @@
+/*
+ * lib/kadm/t_ktentry.c
+ *
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+/*
+ * t_ktentry.c - Test function of krb5_adm_{proto_to_ktent,ktent_to_proto}.
+ */
+
+#include "k5-int.h"
+#include "adm.h"
+#include "adm_proto.h"
+
+#if HAVE_SRAND48
+#define SRAND srand48
+#define RAND lrand48
+#define RAND_TYPE long
+#endif /* HAVE_SRAND48 */
+
+#if !defined(RAND_TYPE) && defined(HAVE_SRAND)
+#define SRAND srand
+#define RAND rand
+#define RAND_TYPE int
+#endif /* !defined(RAND_TYPE) && defined(HAVE_SRAND) */
+
+#if !defined(RAND_TYPE) && defined(HAVE_SRANDOM)
+#define SRAND srandom
+#define RAND random
+#define RAND_TYPE long
+#endif /* !defined(RAND_TYPE) && defined(HAVE_SRANDOM) */
+
+#if !defined(RAND_TYPE)
+There is no random number generator.
+#endif /* !defined(RAND_TYPE) */
+
+/*
+ * Generate a principal name.
+ */
+static char *
+gen_princname(isrand)
+ krb5_boolean isrand;
+{
+ static char *defprinc = "testprinc/instance@realm";
+ char *pptr;
+
+ if (isrand) {
+ int i, j;
+ int ncomps;
+ size_t compsize[9];
+ char * complist[9];
+ size_t totsize;
+
+ for (i=0; i<9; i++) {
+ compsize[i] = 0;
+ complist[i] = (char *) NULL;
+ }
+ ncomps = 2 + (RAND() % 7);
+ totsize = 0;
+ for (i=0; i<ncomps; i++) {
+ compsize[i] = 1 + (RAND() % 32);
+ complist[i] = (char *) malloc(compsize[i]+1);
+ if (complist[i]) {
+ for (j=0; j<compsize[i]; j++) {
+ (complist[i])[j] = RAND() % 128;
+ while (!isalnum((int) (complist[i])[j]))
+ (complist[i])[j] = RAND() % 128;
+ }
+ (complist[i])[compsize[i]] = '\0';
+ totsize += (compsize[i] + 1);
+ }
+ else
+ break;
+ }
+ pptr = (char *) malloc(totsize+1);
+ if (pptr) {
+ pptr[0] = '\0';
+ for (i=1; i<ncomps; i++) {
+ if (complist[i]) {
+ strcat(pptr, complist[i]);
+ strcat(pptr, "/");
+ free(complist[i]);
+ }
+ else
+ break;
+ }
+ pptr[strlen(pptr)-1] = '\0';
+ strcat(pptr, "@");
+ strcat(pptr, complist[0]);
+ free(complist[0]);
+ }
+ }
+ else {
+ pptr = (char *) malloc(strlen(defprinc)+1);
+ if (pptr)
+ strcpy(pptr, defprinc);
+ }
+ return(pptr);
+}
+
+static void
+gen_key(ktentp, isrand)
+ krb5_keytab_entry *ktentp;
+ krb5_boolean isrand;
+{
+ static unsigned char defkey[8] = { 0x01, 0xfe, 0xab, 0xc3,
+ 0x23, 0x16, 0x84, 0x23 };
+
+ if (isrand) {
+ size_t keylen;
+ int i;
+
+ keylen = 4 + (RAND() % 64);
+ ktentp->key.contents = (krb5_octet *) malloc(keylen);
+ if (ktentp->key.contents) {
+ ktentp->key.length = keylen;
+ for (i=0; i<keylen; i++)
+ ktentp->key.contents[i] = RAND() & 255;
+ }
+ }
+ else {
+ ktentp->key.contents = (krb5_octet *) malloc(sizeof(defkey));
+ if (ktentp->key.contents) {
+ ktentp->key.length = 8;
+ memcpy(ktentp->key.contents, defkey, sizeof(defkey));
+ }
+ }
+}
+
+/*
+ * Generate a keytab entry.
+ */
+static void
+gen_ktent(kcontext, ktentp, isrand)
+ krb5_context kcontext;
+ krb5_keytab_entry *ktentp;
+ krb5_boolean isrand;
+{
+ char *princname;
+
+ princname = gen_princname(isrand);
+ if (princname && !krb5_parse_name(kcontext,
+ princname,
+ &ktentp->principal)
+ ) {
+ ktentp->vno = (isrand) ? RAND() : 1;
+ gen_key(ktentp, isrand);
+ free(princname);
+ }
+}
+
+/*
+ * Compare two entries.
+ */
+static krb5_boolean
+compare_entries(kcontext, ientp, oentp)
+ krb5_context kcontext;
+ krb5_keytab_entry *ientp;
+ krb5_keytab_entry *oentp;
+{
+ if (ientp->vno != oentp->vno)
+ return(0);
+
+ if ((ientp->key.length != oentp->key.length) ||
+ memcmp(ientp->key.contents, oentp->key.contents, ientp->key.length))
+ return(0);
+
+ if (!krb5_principal_compare(kcontext, ientp->principal, oentp->principal))
+ return(0);
+ return(1);
+}
+
+/*
+ * Print out an entry.
+ */
+static void
+print_ktent(kcontext, ientp)
+ krb5_context kcontext;
+ krb5_keytab_entry *ientp;
+{
+ char *princname;
+ int i;
+
+ if (!krb5_unparse_name(kcontext, ientp->principal, &princname)) {
+ printf("Principal: %s (version %d[%x])\n", princname, ientp->vno);
+ printf("Key:");
+ for (i=0; i<ientp->key.length; i++)
+ printf(" %02x", ientp->key.contents[i]);
+ printf("\n");
+ krb5_xfree(princname);
+ }
+}
+
+/*
+ * Do a test case.
+ *
+ * Strategy: Generate the desired keytab entry type, then convert it using
+ * krb5_adm_ktent_to_proto, then convert it back to a keytab entry
+ * using krb5_adm_proto_to_ktent. Then verify the match.
+ */
+static krb5_int32
+do_test(pname, verbose, isrand, title, passno)
+ char *pname;
+ krb5_boolean verbose;
+ krb5_boolean isrand;
+ char *title;
+ krb5_int32 passno;
+{
+ krb5_context kcontext;
+ krb5_keytab_entry *in_ktent;
+ krb5_keytab_entry *out_ktent;
+ krb5_error_code kret;
+ krb5_int32 ncomps;
+ krb5_data *complist;
+
+ if (verbose) {
+ printf("* Begin %s", title);
+ if (isrand)
+ printf(" pass %d", passno);
+ printf("\n");
+ }
+
+ kret = 0;
+ krb5_init_context(&kcontext);
+ krb5_init_ets(kcontext);
+ in_ktent = (krb5_keytab_entry *) malloc(sizeof(krb5_keytab_entry));
+ out_ktent = (krb5_keytab_entry *) malloc(sizeof(krb5_keytab_entry));
+ if (in_ktent && out_ktent) {
+ /* Initialize our data */
+ memset((char *) in_ktent, 0, sizeof(krb5_keytab_entry));
+ memset((char *) out_ktent, 0, sizeof(krb5_keytab_entry));
+ ncomps = 0;
+ complist = (krb5_data *) NULL;
+
+ /* Generate the keytab entry. */
+ gen_ktent(kcontext, in_ktent, isrand);
+
+ /* Convert it to the o-t-w protocol */
+ if (!(kret = krb5_adm_ktent_to_proto(kcontext,
+ in_ktent,
+ &ncomps,
+ &complist))) {
+ /* Otherwise, convert it back to a keytab entry */
+ if (!(kret = krb5_adm_proto_to_ktent(kcontext,
+ ncomps,
+ complist,
+ out_ktent))) {
+ /* Compare the entries */
+ if (compare_entries(kcontext,
+ in_ktent,
+ out_ktent)) {
+ /* Success */
+ if (verbose) {
+ printf("Successful translation");
+ printf(" during %s", title);
+ if (isrand)
+ printf(" pass %d", passno);
+ printf(" of:\n");
+ print_ktent(kcontext, in_ktent);
+ }
+ }
+ else {
+ /* Failed */
+ fprintf(stderr, "%s: comparison mismatch", pname);
+ fprintf(stderr, " during %s", title);
+ if (isrand)
+ fprintf(stderr, " pass %d", passno);
+ fprintf(stderr, "\n");
+ if (verbose) {
+ printf("Input entry is as follows:\n");
+ print_ktent(kcontext, in_ktent);
+ printf("Output entry is as follows:\n");
+ print_ktent(kcontext, out_ktent);
+ }
+ kret = KRB5KRB_ERR_GENERIC;
+ }
+ }
+ else {
+ /* Conversion to keytab entry failed */
+ fprintf(stderr, "%s: protocol decode failed with %d",
+ pname, kret);
+ fprintf(stderr, " during %s", title);
+ if (isrand)
+ fprintf(stderr, " pass %d", passno);
+ fprintf(stderr, "\n");
+ }
+ krb5_free_adm_data(kcontext, ncomps, complist);
+ }
+ else {
+ /* Convert to protocol failed */
+ fprintf(stderr, "%s: protocol encode failed with %d",
+ pname, kret);
+ fprintf(stderr, " during %s", title);
+ if (isrand)
+ fprintf(stderr, " pass %d", passno);
+ fprintf(stderr, "\n");
+ }
+ /* Cleanup */
+ if (in_ktent->principal)
+ krb5_free_principal(kcontext, in_ktent->principal);
+ if (in_ktent->key.contents)
+ free(in_ktent->key.contents);
+ free(in_ktent);
+ if (out_ktent->principal)
+ krb5_free_principal(kcontext, out_ktent->principal);
+ if (out_ktent->key.contents)
+ free(out_ktent->key.contents);
+ free(out_ktent);
+ }
+ else {
+ fprintf(stderr, "%s: no memory\n", pname);
+ kret = ENOMEM;
+ }
+
+ krb5_free_context(kcontext);
+ if (verbose) {
+ printf("* End %s ", title);
+ if (isrand)
+ printf(" pass %d ", passno);
+ printf("%s", (kret) ? "FAILURE" : "SUCCESS");
+ if (kret)
+ printf("%d - %s", kret, error_message(kret));
+ printf("\n");
+ }
+ return((kret) ? 1 : 0);
+}
+
+/*
+ * usage is: t_ktentry [-r <nnn>] [-v]
+ */
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ krb5_boolean verbose;
+ krb5_int32 randompasses;
+ krb5_int32 error;
+ int option;
+ extern char *optarg;
+ char *programname;
+ int i;
+ time_t now;
+
+ randompasses = 0;
+ verbose = 0;
+ error = 0;
+ programname = argv[0];
+
+ now = time((time_t *) NULL);
+ SRAND((RAND_TYPE) now);
+ while ((option = getopt(argc, argv, "r:v")) != EOF) {
+ switch (option) {
+ case 'r':
+ if (sscanf(optarg, "%d", &randompasses) != 1) {
+ fprintf(stderr, "%s: %s is not a number\n", argv[0], optarg);
+ error++;
+ }
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ fprintf(stderr, "%s: usage is %s [-r number] [-v]\n",
+ argv[0], argv[0]);
+ error++;
+ break;
+ }
+ }
+ if (error)
+ return(error);
+
+ error += do_test(programname, verbose, 0, "Standard test", 0);
+ for (i=0; i<randompasses; i++)
+ error += do_test(programname, verbose, 1, 0, "Random test", i+1);
+ if (verbose) {
+ if (error)
+ printf("%s: %d errors in %d tests (%5.2f%%)\n", argv[0], error,
+ randompasses+2,
+ (float) (error*100) / (float) (randompasses+2));
+ }
+ return(error);
+}
+