Add new kadmin/ktutil --keep* and --enctypes opts
- Add --keepold/keepallold/pruneall options to various kadmin/ktutil commands. Default behavior to "prune old keys". - When setting keys for a service, we need to specify enctypes for it: - Always use kadm5_randkey_principal_3() instead of the older kadm5_randkey_principal(). - Add krb5_string_to_keysalts2(), like MIT's krb5_string_to_keysalts(), but with a context, and simpler. - Add --enctypes options to various kadmin/ktutil commands. - Add [libdefaults] supported_enctypes param with enctype[:salttype] list. - Add [realms] realm supported_enctypes param with enctype[:salttype] list. Default to aes128-cts-hmac-sha1-96:normal.
This commit is contained in:

committed by
Nico Williams

parent
7b76d6719f
commit
d8394c65b7
123
admin/get.c
123
admin/get.c
@@ -82,45 +82,84 @@ open_kadmin_connection(char *principal,
|
||||
return kadm_handle;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_enctypes(struct get_options *opt,
|
||||
size_t *nks,
|
||||
krb5_key_salt_tuple **ks)
|
||||
{
|
||||
const char *str;
|
||||
char *s = NULL;
|
||||
char *tmp;
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
*nks = 0;
|
||||
*ks = NULL;
|
||||
if (opt->enctypes_strings.num_strings == 0) {
|
||||
str = krb5_config_get_string(context, NULL, "libdefaults",
|
||||
"supported_enctypes", NULL);
|
||||
if (str == NULL)
|
||||
str = "aes128-cts-hmac-sha1-96";
|
||||
return krb5_string_to_keysalts2(context, str, nks, ks);
|
||||
}
|
||||
|
||||
for (i = 0; i < opt->enctypes_strings.num_strings; i++) {
|
||||
if (asprintf(&tmp, "%s%s%s", i ? s : "", i ? "," : "",
|
||||
opt->enctypes_strings.strings[i]) == -1) {
|
||||
free(s);
|
||||
return krb5_enomem(context);
|
||||
}
|
||||
s = tmp;
|
||||
}
|
||||
ret = krb5_string_to_keysalts2(context, s, nks, ks);
|
||||
free(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
kt_get(struct get_options *opt, int argc, char **argv)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
krb5_keytab keytab;
|
||||
void *kadm_handle = NULL;
|
||||
krb5_enctype *etypes = NULL;
|
||||
size_t netypes = 0;
|
||||
krb5_key_salt_tuple *ks = NULL;
|
||||
size_t nks;
|
||||
size_t i;
|
||||
int a, j;
|
||||
int a, j, keep;
|
||||
unsigned int failed = 0;
|
||||
|
||||
if((keytab = ktutil_open_keytab()) == NULL)
|
||||
i = 0;
|
||||
keep = 0;
|
||||
if (opt->keepallold_flag) {
|
||||
keep = 2;
|
||||
i++;
|
||||
}
|
||||
if (opt->keepold_flag) {
|
||||
keep = 1;
|
||||
i++;
|
||||
}
|
||||
if (opt->pruneall_flag) {
|
||||
keep = 0;
|
||||
i++;
|
||||
}
|
||||
if (i > 1) {
|
||||
fprintf(stderr, "use only one of --keepold, --keepallold, or --pruneall\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if ((ret = parse_enctypes(opt, &nks, &ks))) {
|
||||
fprintf(stderr, "invalid enctype(s)\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if((keytab = ktutil_open_keytab()) == NULL) {
|
||||
free(ks);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(opt->realm_string)
|
||||
krb5_set_default_realm(context, opt->realm_string);
|
||||
|
||||
if (opt->enctypes_strings.num_strings != 0) {
|
||||
|
||||
etypes = malloc (opt->enctypes_strings.num_strings * sizeof(*etypes));
|
||||
if (etypes == NULL) {
|
||||
krb5_warnx(context, "malloc failed");
|
||||
goto out;
|
||||
}
|
||||
netypes = opt->enctypes_strings.num_strings;
|
||||
for(i = 0; i < netypes; i++) {
|
||||
ret = krb5_string_to_enctype(context,
|
||||
opt->enctypes_strings.strings[i],
|
||||
&etypes[i]);
|
||||
if(ret) {
|
||||
krb5_warnx(context, "unrecognized enctype: %s",
|
||||
opt->enctypes_strings.strings[i]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(a = 0; a < argc; a++){
|
||||
krb5_principal princ_ent;
|
||||
kadm5_principal_ent_rec princ;
|
||||
@@ -167,7 +206,8 @@ kt_get(struct get_options *opt, int argc, char **argv)
|
||||
failed++;
|
||||
continue;
|
||||
}
|
||||
ret = kadm5_randkey_principal(kadm_handle, princ_ent, &keys, &n_keys);
|
||||
ret = kadm5_randkey_principal_3(kadm_handle, princ_ent, keep, nks, ks,
|
||||
&keys, &n_keys);
|
||||
if (ret) {
|
||||
krb5_warn(context, ret, "kadm5_randkey_principal(%s)", argv[a]);
|
||||
krb5_free_principal(context, princ_ent);
|
||||
@@ -203,37 +243,22 @@ kt_get(struct get_options *opt, int argc, char **argv)
|
||||
continue;
|
||||
}
|
||||
for(j = 0; j < n_keys; j++) {
|
||||
int do_add = TRUE;
|
||||
|
||||
if (netypes) {
|
||||
size_t k;
|
||||
|
||||
do_add = FALSE;
|
||||
for (k = 0; k < netypes; ++k)
|
||||
if (keys[j].keytype == etypes[k]) {
|
||||
do_add = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (do_add) {
|
||||
entry.principal = princ_ent;
|
||||
entry.vno = princ.kvno;
|
||||
entry.keyblock = keys[j];
|
||||
entry.timestamp = time (NULL);
|
||||
ret = krb5_kt_add_entry(context, keytab, &entry);
|
||||
if (ret)
|
||||
krb5_warn(context, ret, "krb5_kt_add_entry");
|
||||
}
|
||||
entry.principal = princ_ent;
|
||||
entry.vno = princ.kvno;
|
||||
entry.keyblock = keys[j];
|
||||
entry.timestamp = time (NULL);
|
||||
ret = krb5_kt_add_entry(context, keytab, &entry);
|
||||
if (ret)
|
||||
krb5_warn(context, ret, "krb5_kt_add_entry");
|
||||
krb5_free_keyblock_contents(context, &keys[j]);
|
||||
}
|
||||
|
||||
kadm5_free_principal_ent(kadm_handle, &princ);
|
||||
krb5_free_principal(context, princ_ent);
|
||||
}
|
||||
out:
|
||||
free(etypes);
|
||||
if (kadm_handle)
|
||||
kadm5_destroy(kadm_handle);
|
||||
krb5_kt_close(context, keytab);
|
||||
free(ks);
|
||||
return ret != 0 || failed > 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user