diff --git a/kdc/kstash.c b/kdc/kstash.c index 67ea1dfb0..d7e5f014b 100644 --- a/kdc/kstash.c +++ b/kdc/kstash.c @@ -53,7 +53,7 @@ struct getargs args[] = { { "version4-key-file", '4', arg_string, &v4_keyfile, "kerberos 4 master key file", "file" }, { "convert-file", 0, arg_flag, &convert_flag, - "convert keytype of keyfile" }, + "just convert keyfile to now format" }, { "master-key-fd", 0, arg_integer, &master_key_fd, "filedescriptor to read passphrase from", "fd" }, { "help", 'h', arg_flag, &help_flag }, @@ -62,99 +62,10 @@ struct getargs args[] = { int num_args = sizeof(args) / sizeof(args[0]); -static void -write_keyfile(EncryptionKey key) -{ - FILE *f; - char buf[1024]; - size_t len; - -#ifdef HAVE_UMASK - umask(077); -#endif - - f = fopen(keyfile, "w"); - if(f == NULL) - krb5_err(context, 1, errno, "%s", keyfile); - encode_EncryptionKey((unsigned char *)buf + sizeof(buf) - 1, - sizeof(buf), &key, &len); - fwrite(buf + sizeof(buf) - len, len, 1, f); - memset(buf, 0, sizeof(buf)); - if(ferror(f)) { - int e = errno; - unlink(keyfile); - krb5_err(context, 1, e, "%s", keyfile); - } - fclose(f); - chmod(keyfile, 0400); -} - -static int -convert_file(void) -{ - FILE *f; - unsigned char buf[1024]; - char *fn; - size_t len; - EncryptionKey key; - krb5_error_code ret; - - f = fopen(keyfile, "r"); - if(f == NULL) { - krb5_warn(context, errno, "%s", keyfile); - return 1; - } - len = fread(buf, 1, sizeof(buf), f); - if(ferror(f)) { - krb5_warn(context, errno, "fread"); - ret = 1; - goto out1; - } - fclose(f); - ret = decode_EncryptionKey(buf, len, &key, &len); - memset(buf, 0, sizeof(buf)); - if(ret) { - krb5_warn(context, ret, "decode_EncryptionKey"); - goto out2; - } - if(key.keytype == KEYTYPE_DES) - key.keytype = ETYPE_DES_CBC_MD5; - else if(key.keytype == ETYPE_DES_CBC_MD5) { - krb5_warnx(context, "keyfile already converted"); - ret = 0; - goto out2; - } else { - krb5_warnx(context, "bad encryption key type (%d)", key.keytype); - ret = 1; - goto out2; - } - asprintf(&fn, "%s.old", keyfile); - if(fn == NULL) { - krb5_warn(context, ENOMEM, "malloc"); - ret = 1; - goto out1; - } - if(rename(keyfile, fn) < 0) { - krb5_warn(context, errno, "rename"); - ret = 1; - goto out1; - } - write_keyfile(key); - krb5_free_keyblock_contents(context, &key); - return 0; -out1: - memset(buf, 0, sizeof(buf)); - return ret ? 1 : 0; -out2: - krb5_free_keyblock_contents(context, &key); - return ret ? 1 : 0; -} - int main(int argc, char **argv) { char buf[1024]; - krb5_keyblock key; krb5_error_code ret; krb5_enctype enctype; @@ -170,18 +81,16 @@ main(int argc, char **argv) exit(0); } - if(convert_flag) - exit(convert_file()); - ret = krb5_string_to_enctype(context, enctype_str, &enctype); if(ret) krb5_err(context, 1, ret, "krb5_string_to_enctype"); ret = hdb_read_master_key(context, keyfile, &mkey); - if(ret) + if(ret && ret != ENOENT) krb5_err(context, 1, ret, "reading master key"); - { + if(!convert_flag) { + krb5_keyblock key; krb5_salt salt; salt.salttype = KRB5_PW_SALT; /* XXX better value? */ @@ -199,30 +108,41 @@ main(int argc, char **argv) exit(1); } krb5_string_to_key_salt(context, enctype, buf, salt, &key); + ret = hdb_add_master_key(context, &key, &mkey); + + krb5_free_keyblock_contents(context, &key); + } - ret = hdb_add_master_key(context, &key, &mkey); - - krb5_free_keyblock_contents(context, &key); - { char *new, *old; asprintf(&old, "%s.old", keyfile); asprintf(&new, "%s.new", keyfile); + if(unlink(new) < 0 && errno != ENOENT) { + ret = errno; + goto out; + } + krb5_warnx(context, "writing key to `%s'", keyfile); ret = hdb_write_master_key(context, new, mkey); if(ret) unlink(new); else { - if(link(keyfile, old) < 0) + unlink(old); + if(link(keyfile, old) < 0 && errno != ENOENT) { ret = errno; - else if(rename(new, keyfile) < 0) + unlink(new); + } else if(rename(new, keyfile) < 0) { ret = errno; + } } + out: free(old); free(new); + if(ret) + krb5_warn(context, errno, "writing master key file"); } hdb_free_master_key(context, mkey); - exit(0); + exit(ret != 0); }