diff options
Diffstat (limited to 'crypto/heimdal/kdc/kstash.c')
-rw-r--r-- | crypto/heimdal/kdc/kstash.c | 188 |
1 files changed, 74 insertions, 114 deletions
diff --git a/crypto/heimdal/kdc/kstash.c b/crypto/heimdal/kdc/kstash.c index 5b79fd1e6553..edb00b25403b 100644 --- a/crypto/heimdal/kdc/kstash.c +++ b/crypto/heimdal/kdc/kstash.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,122 +33,41 @@ #include "headers.h" -RCSID("$Id: kstash.c,v 1.10 1999/11/13 04:14:17 assar Exp $"); +RCSID("$Id: kstash.c,v 1.14 2001/01/30 17:08:35 assar Exp $"); krb5_context context; char *keyfile = HDB_DB_DIR "/m-key"; -char *v4_keyfile; int convert_flag; int help_flag; int version_flag; +int master_key_fd = -1; + +char *enctype_str = "des3-cbc-sha1"; + struct getargs args[] = { + { "enctype", 'e', arg_string, &enctype_str, "encryption type" }, { "key-file", 'k', arg_string, &keyfile, "master key file", "file" }, - { "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 new format" }, + { "master-key-fd", 0, arg_integer, &master_key_fd, + "filedescriptor to read passphrase from", "fd" }, { "help", 'h', arg_flag, &help_flag }, { "version", 0, arg_flag, &version_flag } }; 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]; - EncryptionKey key; - FILE *f; + krb5_error_code ret; + + krb5_enctype enctype; + + hdb_master_key mkey; krb5_program_setup(&context, argc, argv, args, num_args, NULL); @@ -159,30 +78,71 @@ main(int argc, char **argv) exit(0); } - if(convert_flag) - exit(convert_file()); - - key.keytype = ETYPE_DES_CBC_MD5; /* XXX */ - if(v4_keyfile) { - f = fopen(v4_keyfile, "r"); - if(f == NULL) - krb5_err(context, 1, errno, "fopen(%s)", v4_keyfile); - key.keyvalue.length = sizeof(des_cblock); - key.keyvalue.data = malloc(key.keyvalue.length); - fread(key.keyvalue.data, 1, key.keyvalue.length, f); - fclose(f); + 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 && ret != ENOENT) + krb5_err(context, 1, ret, "reading master key from %s", keyfile); + + if (convert_flag) { + if (ret) + krb5_err(context, 1, ret, "reading master key from %s", keyfile); } else { + krb5_keyblock key; krb5_salt salt; salt.salttype = KRB5_PW_SALT; /* XXX better value? */ salt.saltvalue.data = NULL; salt.saltvalue.length = 0; - if(des_read_pw_string(buf, sizeof(buf), "Master key: ", 1)) - exit(1); - krb5_string_to_key_salt(context, key.keytype, buf, salt, &key); + if(master_key_fd != -1) { + ssize_t n; + n = read(master_key_fd, buf, sizeof(buf)); + if(n <= 0) + krb5_err(context, 1, errno, "failed to read passphrase"); + buf[n] = '\0'; + buf[strcspn(buf, "\r\n")] = '\0'; + } else { + if(des_read_pw_string(buf, sizeof(buf), "Master key: ", 1)) + 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); + } - write_keyfile(key); - krb5_free_keyblock_contents(context, &key); - exit(0); + { + 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 { + unlink(old); + if(link(keyfile, old) < 0 && errno != ENOENT) { + ret = errno; + 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(ret != 0); } |