4 * asetkey - Manipulates an AFS KeyFile
6 * Updated for Kerberos 5
10 #include <afs/param.h>
17 #ifndef HAVE_KERBEROSV_HEIM_ERR_H
18 #include <afs/com_err.h>
20 #include <afs/cellconfig.h>
22 #include <afs/dirpath.h>
24 #ifdef HAVE_KRB5_CREDS_KEYBLOCK
27 #ifdef HAVE_KRB5_CREDS_SESSION
28 #define USING_HEIMDAL 1
32 stringToType(const char *string) {
33 if (strcmp(string, "rxkad") == 0)
35 if (strcmp(string, "rxkad_krb5") == 0)
36 return afsconf_rxkad_krb5;
42 printKey(const struct rx_opaque *key)
46 for (i = 0; i < key->len; i++)
47 printf("%02x", ((unsigned char *)key->val)[i]);
55 if (c >= '0' && c <= '9')
57 if ((c >= 'a') && (c <= 'f'))
58 return (c - 'a' + 10);
60 if ((c >= 'A') && (c <= 'F'))
61 return (c - 'A' + 10);
66 static struct afsconf_typedKey *
67 keyFromCommandLine(afsconf_keyType type, int kvno, int subType,
68 const char *string, size_t length)
71 struct afsconf_typedKey *typedKey;
75 if (strlen(string) != 2*length) {
76 printf("key %s is not in right format\n", string);
77 printf(" <key> should be an %d byte hex representation \n", (int) length);
81 rx_opaque_alloc(&key, length);
83 for (i = 0; i< length; i++) {
84 ((char *)key.val)[i] = char2hex(*cp) * 16 + char2hex(*(cp+1));
88 typedKey = afsconf_typedKey_new(type, kvno, subType, &key);
89 rx_opaque_freeContents(&key);
94 #define deref_key_length(key) \
97 #define deref_key_contents(key) \
100 #define deref_key_length(key) \
103 #define deref_key_contents(key) \
107 static struct afsconf_typedKey *
108 keyFromKeytab(int kvno, afsconf_keyType type, int subtype, const char *keytab, const char *princ)
111 krb5_principal principal;
113 krb5_context context;
114 struct rx_opaque buffer;
115 struct afsconf_typedKey *typedKey;
117 krb5_init_context(&context);
119 retval = krb5_parse_name(context, princ, &principal);
121 afs_com_err("asetkey", retval, "while parsing AFS principal");
125 if (type == afsconf_rxkad) {
126 retval = krb5_kt_read_service_key(context, (char *)keytab, principal,
127 kvno, ENCTYPE_DES_CBC_CRC, &key);
128 if (retval == KRB5_KT_NOTFOUND)
129 retval = krb5_kt_read_service_key(context, (char *)keytab,
131 ENCTYPE_DES_CBC_MD5, &key);
132 if (retval == KRB5_KT_NOTFOUND)
133 retval = krb5_kt_read_service_key(context, (char *)keytab,
135 ENCTYPE_DES_CBC_MD4, &key);
136 } else if (type == afsconf_rxkad_krb5) {
137 retval = krb5_kt_read_service_key(context, (char *)keytab, principal,
138 kvno, subtype, &key);
140 retval=AFSCONF_BADKEY;
142 if (retval == KRB5_KT_NOTFOUND) {
143 char * princname = NULL;
145 krb5_unparse_name(context, principal, &princname);
147 if (type == afsconf_rxkad) {
148 afs_com_err("asetkey", retval,
149 "for keytab entry with Principal %s, kvno %u, "
150 "DES-CBC-CRC/MD5/MD4",
151 princname ? princname : princ, kvno);
153 afs_com_err("asetkey", retval,
154 "for keytab entry with Principal %s, kvno %u",
155 princname ? princname : princ, kvno);
161 afs_com_err("asetkey", retval, "while extracting AFS service key");
165 if (type == afsconf_rxkad && deref_key_length(key) != 8) {
166 fprintf(stderr, "Key length should be 8, but is really %u!\n",
167 (unsigned int)deref_key_length(key));
171 rx_opaque_populate(&buffer, deref_key_contents(key), deref_key_length(key));
173 typedKey = afsconf_typedKey_new(type, kvno, subtype, &buffer);
174 rx_opaque_freeContents(&buffer);
175 krb5_free_principal(context, principal);
176 krb5_free_keyblock(context, key);
181 addKey(struct afsconf_dir *dir, int argc, char **argv) {
182 struct afsconf_typedKey *typedKey;
189 typedKey = keyFromCommandLine(afsconf_rxkad, atoi(argv[2]), 0,
193 typedKey = keyFromKeytab(atoi(argv[2]), afsconf_rxkad, 0, argv[3], argv[4]);
196 type = stringToType(argv[2]);
197 kvno = atoi(argv[3]);
198 if (type == afsconf_rxkad) {
199 typedKey = keyFromCommandLine(afsconf_rxkad, kvno, 0, argv[5], 8);
201 fprintf(stderr, "Unknown key type %s\n", argv[2]);
206 typedKey = keyFromKeytab(atoi(argv[3]), atoi(argv[2]), atoi(argv[4]), argv[5], argv[6]);
209 fprintf(stderr, "%s add: usage is '%s add <kvno> <keyfile> "
210 "<princ>\n", argv[0], argv[0]);
211 fprintf(stderr, "\tOR\n\t%s add <kvno> <key>\n", argv[0]);
212 fprintf(stderr, "\tOR\n\t%s add <type> <kvno> <subtype> <key>\n",
214 fprintf(stderr, "\tOR\n\t%s add <type> <kvno> <subtype> <keyfile> <princ>\n",
216 fprintf(stderr, "\t\tEx: %s add 0 \"80b6a7cd7a9dadb6\"\n", argv[0]);
219 code = afsconf_AddTypedKey(dir, typedKey, 1);
220 afsconf_typedKey_put(&typedKey);
222 afs_com_err("asetkey", code, "while adding new key");
228 deleteKey(struct afsconf_dir *dir, int argc, char **argv)
234 fprintf(stderr, "%s delete: usage is '%s delete <kvno>\n",
238 kvno = atoi(argv[2]);
239 code = afsconf_DeleteKey(dir, kvno);
241 afs_com_err(argv[0], code, "while deleting key %d", kvno);
247 listKey(struct afsconf_dir *dir, int argc, char **argv)
249 struct afsconf_typedKeyList *keys;
253 code = afsconf_GetAllKeys(dir, &keys);
255 afs_com_err("asetkey", code, "while retrieving keys");
258 for (i = 0; i < keys->nkeys; i++) {
259 afsconf_keyType type;
262 struct rx_opaque *keyMaterial;
264 afsconf_typedKey_values(keys->keys[i], &type, &kvno, &minorType,
269 printf("rxkad\tkvno %4d: key is: ", kvno);
270 printKey(keyMaterial);
273 case afsconf_rxkad_krb5:
275 printf("rxkad_krb5\tkvno %4d enctype %d; key is: ",
277 printKey(keyMaterial);
281 printf("unknown(%d)\tkvno %4d subtype %d; key is: ", type,
283 printKey(keyMaterial);
287 printf("All done.\n");
291 main(int argc, char *argv[])
293 struct afsconf_dir *tdir;
297 fprintf(stderr, "%s: usage is '%s <opcode> options, e.g.\n",
299 fprintf(stderr, "\t%s add <kvno> <keyfile> <princ>\n", argv[0]);
300 fprintf(stderr, "\tOR\n\t%s add <kvno> <key>\n", argv[0]);
301 fprintf(stderr, "\tOR\n\t%s add <type> <kvno> <subtype> <key>\n",
303 fprintf(stderr, "\tOR\n\t%s add <type> <kvno> <subtype> <keyfile> <princ>\n",
305 fprintf(stderr, "\t\tEx: %s add 0 \"80b6a7cd7a9dadb6\"\n", argv[0]);
306 fprintf(stderr, "\t%s delete <kvno>\n", argv[0]);
307 fprintf(stderr, "\t%s list\n", argv[0]);
311 confdir = AFSDIR_SERVER_ETC_DIRPATH;
313 tdir = afsconf_Open(confdir);
315 fprintf(stderr, "%s: can't initialize conf dir '%s'\n", argv[0],
319 if (strcmp(argv[1], "add")==0) {
320 addKey(tdir, argc, argv);
322 else if (strcmp(argv[1], "delete")==0) {
323 deleteKey(tdir, argc, argv);
325 else if (strcmp(argv[1], "list") == 0) {
326 listKey(tdir, argc, argv);
330 fprintf(stderr, "%s: unknown operation '%s', type '%s' for "
331 "assistance\n", argv[0], argv[1], argv[0]);