Added "addent" command to allow creation of new keytab entries by
authorGeoffrey King <gjking@mit.edu>
Mon, 16 Aug 1999 11:50:19 +0000 (11:50 +0000)
committerGeoffrey King <gjking@mit.edu>
Mon, 16 Aug 1999 11:50:19 +0000 (11:50 +0000)
specifying a key or password, a principal, a kvno, and an enctype.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11664 dc483132-0cff-0310-8789-dd5450dbe970

src/kadmin/ktutil/ChangeLog
src/kadmin/ktutil/ktutil.c
src/kadmin/ktutil/ktutil.h
src/kadmin/ktutil/ktutil_ct.ct
src/kadmin/ktutil/ktutil_funcs.c

index 87f8244b3908cc0a7d33a7303833c540d5f95ac6..f9aa8c0223608b55072ed9ce6264768c55b7dd33 100644 (file)
@@ -1,3 +1,9 @@
+1999-08-16  Geoffrey King  <gjking@mit.edu>
+
+       * ktutil.c (ktutil_add_entry):
+       * ktutil_funcs.c (ktutil_add): Implement addent command to allow
+       creation of new keytab entries by specifying a key or password.
+
 1998-11-13  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * Makefile.in: Set the myfulldir and mydir variables (which are
index 0106ed758240c15e19e8d69867fe0ae578de1dc9..5ba668e2fe8fba1b3f43b733fd63182421b92240 100644 (file)
@@ -151,6 +151,50 @@ void ktutil_write_v4(argc, argv)
 #endif
 }
 
+void ktutil_add_entry(argc, argv)
+    int argc;
+    char *argv[];
+{
+    krb5_error_code retval;
+    char *princ = NULL;
+    char *enctype = NULL;
+    krb5_kvno kvno = 0;
+    int use_pass = 0, use_key = 0, i;    
+
+    for (i = 1; i < argc; i++) {
+       if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) {
+           princ = argv[++i];
+           continue;
+       }
+       if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) {
+           kvno = (krb5_kvno) atoi(argv[++i]);
+           continue;
+       }
+       if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) {
+           enctype = argv[++i];
+           continue;
+       }
+       if ((strlen(argv[i]) == 9) && !strncmp(argv[i], "-password", 9)) {
+           use_pass++;
+           continue;
+       }
+       if ((strlen(argv[i]) == 4) && !strncmp(argv[i], "-key", 4)) {
+           use_key++;
+           continue;
+       }
+    }
+
+    if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) {
+        fprintf(stderr, "usage: %s (-key | -password) -p principal "
+               "-k kvno -e enctype\n", argv[0]);
+       return;
+    }
+
+    retval = ktutil_add(kcontext, &ktlist, princ, kvno, enctype, use_pass);
+    if (retval)
+        com_err(argv[0], retval, "while adding new entry");
+}
+
 void ktutil_delete_entry(argc, argv)
     int argc;
     char *argv[];
@@ -186,21 +230,20 @@ void ktutil_list(argc, argv)
            show_keys++;
            continue;
        }
-if ( (strlen(argv[i]) == 2)&&
-     (!strncmp(argv[i],"-e",2))) {
-    show_enctype = 1;
-    continue;
-}
+       if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) {
+           show_enctype++;
+           continue;
+       }
        
        fprintf(stderr, "%s: illegal arguments\n", argv[0]);
        return;
     }
     if (show_time) {
-       printf("slot KVNO Timestamp          Principal\n");
-       printf("---- ---- ------------------ -------------------------------------------------------\n");
+       printf("slot KVNO Timestamp         Principal\n");
+       printf("---- ---- ----------------- ---------------------------------------------------\n");
     } else {
        printf("slot KVNO Principal\n");
-       printf("---- ---- --------------------------------------------------------------------------\n");
+       printf("---- ---- ---------------------------------------------------------------------\n");
     }
     for (i = 1, lp = ktlist; lp; i++, lp = lp->next) {
        retval = krb5_unparse_name(kcontext, lp->entry->principal, &pname);
@@ -220,7 +263,7 @@ if ( (strlen(argv[i]) == 2)&&
                                            fmtbuf,
                                            sizeof(fmtbuf),
                                            &fill))
-               printf(fmtbuf);
+               printf("%s ", fmtbuf);
        }
        printf("%40s", pname);
        if (show_enctype) {
@@ -243,3 +286,13 @@ if ( (strlen(argv[i]) == 2)&&
        krb5_xfree(pname);
     }
 }
+
+
+
+
+
+
+
+
+
+
index 0f14defb7a007e31dd8f939c5095e5a1ed5cc68d..6b3e7a0c516e2c8df9c6b782cd25643b15e27fbc 100644 (file)
@@ -36,6 +36,14 @@ krb5_error_code ktutil_delete
                        krb5_kt_list *,
                        int));
 
+krb5_error_code ktutil_add
+       KRB5_PROTOTYPE((krb5_context,
+                       krb5_kt_list *,
+                       char *,
+                       krb5_kvno,
+                       char *,
+                       int));
+
 krb5_error_code ktutil_read_keytab
        KRB5_PROTOTYPE((krb5_context,
                        char *,
index 1f0269f6d6054c0702144090ef147be57ec01a34..86e3d5bf22427ffb2d1700fb69243ee22d4de277 100644 (file)
@@ -38,6 +38,9 @@ request ktutil_write_v5, "Write the current keylist to a krb5 keytab.",
 request ktutil_write_v4, "Write the current keylist to a krb4 srvtab.",
        write_st, wst;
 
+request ktutil_add_entry, "Add an entry to the current keylist.",
+       add_entry, addent;
+
 request ktutil_delete_entry, "Delete an entry from the current keylist.",
        delete_entry, delent;
 
@@ -49,3 +52,4 @@ request ss_list_requests, "List available requests.",
 
 request ss_quit, "Exit program.",
        quit, exit, q;
+
index 8429169f3737f79e87582c618c8b5b2dc4582354..bacb0065c2fa6455cd80e389e1ff789a8f0b4ca3 100644 (file)
@@ -30,6 +30,7 @@
 #include <stdio.h>
 #endif
 #include <string.h>
+#include <ctype.h>
 
 /*
  * Free a kt_list
@@ -78,6 +79,137 @@ krb5_error_code ktutil_delete(context, list, index)
     return EINVAL;
 }
 
+/*
+ * Create a new keytab entry and add it to the keytab list.
+ * Based on the value of use_pass, either prompt the user for a
+ * password or key.  If the keytab list is NULL, allocate a new
+ * one first.
+ */
+krb5_error_code ktutil_add(context, list, princ_str, kvno,
+                          enctype_str, use_pass)
+    krb5_context context;
+    krb5_kt_list *list;
+    char *princ_str;
+    krb5_kvno kvno;
+    char *enctype_str;
+    int use_pass;
+{
+    krb5_keytab_entry *entry;
+    krb5_kt_list lp = NULL, tail = NULL, back = NULL;
+    krb5_principal princ;
+    krb5_enctype enctype;
+    krb5_timestamp now;
+    krb5_error_code retval;
+    krb5_data password, salt;
+    krb5_keyblock key;
+    char buf[BUFSIZ];
+    char promptstr[1024];
+
+    char *cp;
+    int i, tmp, pwsize = BUFSIZ;
+
+    retval = krb5_timeofday(context, &now);
+    if (retval)
+        return retval;
+    retval = krb5_parse_name(context, princ_str, &princ);
+    if (retval)
+        return retval;
+    /* now unparse in order to get the default realm appended
+       to princ_str, if no realm was specified */
+    retval = krb5_unparse_name(context, princ, &princ_str);
+    if (retval)
+        return retval;
+    retval = krb5_string_to_enctype(enctype_str, &enctype);
+    if (retval) 
+        return KRB5_BAD_ENCTYPE;
+
+    if (*list) {
+        /* point lp at the tail of the list */
+        for (lp = *list; lp->next; lp = lp->next);
+       back = lp;
+    }
+
+    entry = (krb5_keytab_entry *) malloc(sizeof(krb5_keytab_entry));
+    if (!entry) {
+        return ENOMEM;
+    }
+    memset((char *) entry, 0, sizeof(*entry));
+
+    if (!lp) {         /* if list is empty, start one */
+        lp = (krb5_kt_list) malloc(sizeof(krb5_kt_list));
+       if (!lp) {
+           return ENOMEM;
+       }
+    } else {
+        lp->next = (krb5_kt_list) malloc(sizeof(krb5_kt_list));
+       if (!lp->next) {
+           return ENOMEM;
+       }
+       lp = lp->next;
+    }          
+
+    if (!tail)
+        tail = lp;
+    lp->next = NULL;
+    lp->entry = entry;
+
+    if (use_pass) {
+        password.length = pwsize;
+       password.data = (char *) malloc(pwsize);
+       if (!password.data)
+           return ENOMEM;
+
+       sprintf(promptstr, "Password for %.1000s: ", princ_str);
+        krb5_read_password(context, promptstr, NULL, password.data,
+                          &password.length);
+       krb5_principal2salt(context, princ, &salt);
+       krb5_c_string_to_key(context, enctype, &password, &salt, &key);
+       memset(password.data, 0, password.length);
+       password.length = 0;
+       memcpy(&lp->entry->key, &key, sizeof(krb5_keyblock));
+    } else {
+        printf("Key for %s (hex): ", princ_str);
+       fgets(buf, BUFSIZ, stdin);
+       /*
+        * We need to get rid of the trailing '\n' from fgets.
+        * If we have an even number of hex digits (as we should),
+        * write a '\0' over the '\n'.  If for some reason we have
+        * an odd number of hex digits, force an even number of hex
+        * digits by writing a '0' into the last position (the string
+        * will still be null-terminated).
+        */
+       buf[strlen(buf) - 1] = strlen(buf) % 2 ? '\0' : '0';
+       if (strlen(buf) == 0) {
+           fprintf(stderr, "addent: Error reading key.\n");
+           return 0;
+       }
+       
+        lp->entry->key.enctype = enctype;
+       lp->entry->key.contents = (krb5_octet *) malloc((strlen(buf) + 1) / 2);
+       if (!lp->entry->key.contents)
+           return ENOMEM;
+
+       i = 0;
+       for (cp = buf; *cp; cp += 2) {
+           if (!isxdigit(cp[0]) || !isxdigit(cp[1])) {
+               fprintf(stderr, "addent: Illegal character in key.\n");
+               return 0;
+           }
+           sscanf(cp, "%02x", &tmp);
+           lp->entry->key.contents[i++] = (krb5_octet) tmp;
+       }
+       lp->entry->key.length = i;
+    }
+    lp->entry->principal = princ;
+    lp->entry->vno = kvno;
+    lp->entry->timestamp = now;
+
+    if (!*list)
+       *list = tail;
+
+    return 0;
+}
+
 /*
  * Read in a keytab and append it to list.  If list starts as NULL,
  * allocate a new one if necessary.