4 * asetkey - Manipulates an AFS KeyFile
6 * Updated for Kerberos 5
10 #include <afs/param.h>
15 #define KERBEROS_APPLE_DEPRECATED(x)
18 #ifndef HAVE_KERBEROSV_HEIM_ERR_H
19 #include <afs/com_err.h>
21 #include <afs/cellconfig.h>
23 #include <afs/dirpath.h>
25 #ifdef HAVE_KRB5_CREDS_KEYBLOCK
28 #ifdef HAVE_KRB5_CREDS_SESSION
29 #define USING_HEIMDAL 1
33 stringToType(const char *string
) {
34 if (strcmp(string
, "rxkad") == 0)
36 if (strcmp(string
, "rxkad_krb5") == 0)
37 return afsconf_rxkad_krb5
;
43 printKey(const struct rx_opaque
*key
)
47 for (i
= 0; i
< key
->len
; i
++)
48 printf("%02x", ((unsigned char *)key
->val
)[i
]);
56 if (c
>= '0' && c
<= '9')
58 if ((c
>= 'a') && (c
<= 'f'))
59 return (c
- 'a' + 10);
61 if ((c
>= 'A') && (c
<= 'F'))
62 return (c
- 'A' + 10);
67 static struct afsconf_typedKey
*
68 keyFromCommandLine(afsconf_keyType type
, int kvno
, int subType
,
69 const char *string
, size_t length
)
72 struct afsconf_typedKey
*typedKey
;
76 if (strlen(string
) != 2*length
) {
77 printf("key %s is not in right format\n", string
);
78 printf(" <key> should be an %d byte hex representation \n", (int) length
);
82 rx_opaque_alloc(&key
, length
);
84 for (i
= 0; i
< length
; i
++) {
85 ((char *)key
.val
)[i
] = char2hex(*cp
) * 16 + char2hex(*(cp
+1));
89 typedKey
= afsconf_typedKey_new(type
, kvno
, subType
, &key
);
90 rx_opaque_freeContents(&key
);
95 #define deref_key_length(key) \
98 #define deref_key_contents(key) \
101 #define deref_key_length(key) \
104 #define deref_key_contents(key) \
108 static struct afsconf_typedKey
*
109 keyFromKeytab(int kvno
, afsconf_keyType type
, int subtype
, const char *keytab
, const char *princ
)
112 krb5_principal principal
;
114 krb5_context context
;
115 struct rx_opaque buffer
;
116 struct afsconf_typedKey
*typedKey
;
118 krb5_init_context(&context
);
120 retval
= krb5_parse_name(context
, princ
, &principal
);
122 afs_com_err("asetkey", retval
, "while parsing AFS principal");
126 if (type
== afsconf_rxkad
) {
127 retval
= krb5_kt_read_service_key(context
, (char *)keytab
, principal
,
128 kvno
, ENCTYPE_DES_CBC_CRC
, &key
);
129 if (retval
== KRB5_KT_NOTFOUND
)
130 retval
= krb5_kt_read_service_key(context
, (char *)keytab
,
132 ENCTYPE_DES_CBC_MD5
, &key
);
133 if (retval
== KRB5_KT_NOTFOUND
)
134 retval
= krb5_kt_read_service_key(context
, (char *)keytab
,
136 ENCTYPE_DES_CBC_MD4
, &key
);
137 } else if (type
== afsconf_rxkad_krb5
) {
138 retval
= krb5_kt_read_service_key(context
, (char *)keytab
, principal
,
139 kvno
, subtype
, &key
);
141 retval
=AFSCONF_BADKEY
;
143 if (retval
== KRB5_KT_NOTFOUND
) {
144 char * princname
= NULL
;
146 krb5_unparse_name(context
, principal
, &princname
);
148 if (type
== afsconf_rxkad
) {
149 afs_com_err("asetkey", retval
,
150 "for keytab entry with Principal %s, kvno %u, "
151 "DES-CBC-CRC/MD5/MD4",
152 princname
? princname
: princ
, kvno
);
154 afs_com_err("asetkey", retval
,
155 "for keytab entry with Principal %s, kvno %u",
156 princname
? princname
: princ
, kvno
);
162 afs_com_err("asetkey", retval
, "while extracting AFS service key");
166 if (type
== afsconf_rxkad
&& deref_key_length(key
) != 8) {
167 fprintf(stderr
, "Key length should be 8, but is really %u!\n",
168 (unsigned int)deref_key_length(key
));
172 rx_opaque_populate(&buffer
, deref_key_contents(key
), deref_key_length(key
));
174 typedKey
= afsconf_typedKey_new(type
, kvno
, subtype
, &buffer
);
175 rx_opaque_freeContents(&buffer
);
176 krb5_free_principal(context
, principal
);
177 krb5_free_keyblock(context
, key
);
182 addKey(struct afsconf_dir
*dir
, int argc
, char **argv
) {
183 struct afsconf_typedKey
*typedKey
;
190 typedKey
= keyFromCommandLine(afsconf_rxkad
, atoi(argv
[2]), 0,
194 typedKey
= keyFromKeytab(atoi(argv
[2]), afsconf_rxkad
, 0, argv
[3], argv
[4]);
197 type
= stringToType(argv
[2]);
198 kvno
= atoi(argv
[3]);
199 if (type
== afsconf_rxkad
) {
200 typedKey
= keyFromCommandLine(afsconf_rxkad
, kvno
, 0, argv
[5], 8);
201 } else if (type
== afsconf_rxkad_krb5
){
202 fprintf(stderr
, "Raw keys for afsconf_rxkad_krb5 are unsupported");
205 fprintf(stderr
, "Unknown key type %s\n", argv
[2]);
210 type
= stringToType(argv
[2]);
211 kvno
= atoi(argv
[3]);
212 if (type
== afsconf_rxkad
|| type
== afsconf_rxkad_krb5
) {
213 typedKey
= keyFromKeytab(kvno
, type
, atoi(argv
[4]), argv
[5],
216 fprintf(stderr
, "Unknown key type %s\n", argv
[2]);
221 fprintf(stderr
, "%s add: usage is '%s add <kvno> <keyfile> "
222 "<princ>\n", argv
[0], argv
[0]);
223 fprintf(stderr
, "\tOR\n\t%s add <kvno> <key>\n", argv
[0]);
224 fprintf(stderr
, "\tOR\n\t%s add <type> <kvno> <subtype> <key>\n",
226 fprintf(stderr
, "\tOR\n\t%s add <type> <kvno> <subtype> <keyfile> <princ>\n",
228 fprintf(stderr
, "\t\tEx: %s add 0 \"80b6a7cd7a9dadb6\"\n", argv
[0]);
231 code
= afsconf_AddTypedKey(dir
, typedKey
, 1);
232 afsconf_typedKey_put(&typedKey
);
234 afs_com_err("asetkey", code
, "while adding new key");
240 deleteKey(struct afsconf_dir
*dir
, int argc
, char **argv
)
246 fprintf(stderr
, "%s delete: usage is '%s delete <kvno>\n",
250 kvno
= atoi(argv
[2]);
251 code
= afsconf_DeleteKey(dir
, kvno
);
253 afs_com_err(argv
[0], code
, "while deleting key %d", kvno
);
259 listKey(struct afsconf_dir
*dir
, int argc
, char **argv
)
261 struct afsconf_typedKeyList
*keys
;
265 code
= afsconf_GetAllKeys(dir
, &keys
);
267 afs_com_err("asetkey", code
, "while retrieving keys");
270 for (i
= 0; i
< keys
->nkeys
; i
++) {
271 afsconf_keyType type
;
274 struct rx_opaque
*keyMaterial
;
276 afsconf_typedKey_values(keys
->keys
[i
], &type
, &kvno
, &minorType
,
281 printf("rxkad\tkvno %4d: key is: ", kvno
);
282 printKey(keyMaterial
);
285 case afsconf_rxkad_krb5
:
287 printf("rxkad_krb5\tkvno %4d enctype %d; key is: ",
289 printKey(keyMaterial
);
293 printf("unknown(%d)\tkvno %4d subtype %d; key is: ", type
,
295 printKey(keyMaterial
);
299 printf("All done.\n");
303 main(int argc
, char *argv
[])
305 struct afsconf_dir
*tdir
;
309 fprintf(stderr
, "%s: usage is '%s <opcode> options, e.g.\n",
311 fprintf(stderr
, "\t%s add <kvno> <keyfile> <princ>\n", argv
[0]);
312 fprintf(stderr
, "\tOR\n\t%s add <kvno> <key>\n", argv
[0]);
313 fprintf(stderr
, "\tOR\n\t%s add <type> <kvno> <subtype> <key>\n",
315 fprintf(stderr
, "\tOR\n\t%s add <type> <kvno> <subtype> <keyfile> <princ>\n",
317 fprintf(stderr
, "\t\tEx: %s add 0 \"80b6a7cd7a9dadb6\"\n", argv
[0]);
318 fprintf(stderr
, "\t%s delete <kvno>\n", argv
[0]);
319 fprintf(stderr
, "\t%s list\n", argv
[0]);
323 confdir
= AFSDIR_SERVER_ETC_DIRPATH
;
325 tdir
= afsconf_Open(confdir
);
327 fprintf(stderr
, "%s: can't initialize conf dir '%s'\n", argv
[0],
331 if (strcmp(argv
[1], "add")==0) {
332 addKey(tdir
, argc
, argv
);
334 else if (strcmp(argv
[1], "delete")==0) {
335 deleteKey(tdir
, argc
, argv
);
337 else if (strcmp(argv
[1], "list") == 0) {
338 listKey(tdir
, argc
, argv
);
342 fprintf(stderr
, "%s: unknown operation '%s', type '%s' for "
343 "assistance\n", argv
[0], argv
[1], argv
[0]);