Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/kdc/kstash.c
34860 views
1
/*
2
* Copyright (c) 1997-2004 Kungliga Tekniska Högskolan
3
* (Royal Institute of Technology, Stockholm, Sweden).
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
*
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
*
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* 3. Neither the name of the Institute nor the names of its contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
* SUCH DAMAGE.
32
*/
33
34
#include "headers.h"
35
36
krb5_context context;
37
38
static char *keyfile;
39
static int convert_flag;
40
static int help_flag;
41
static int version_flag;
42
43
static int master_key_fd = -1;
44
static int random_key_flag;
45
46
static const char *enctype_str = "des3-cbc-sha1";
47
48
static struct getargs args[] = {
49
{ "enctype", 'e', arg_string, rk_UNCONST(&enctype_str), "encryption type",
50
NULL },
51
{ "key-file", 'k', arg_string, &keyfile, "master key file", "file" },
52
{ "convert-file", 0, arg_flag, &convert_flag,
53
"just convert keyfile to new format", NULL },
54
{ "master-key-fd", 0, arg_integer, &master_key_fd,
55
"filedescriptor to read passphrase from", "fd" },
56
{ "random-key", 0, arg_flag, &random_key_flag,
57
"generate a random master key", NULL },
58
{ "help", 'h', arg_flag, &help_flag, NULL, NULL },
59
{ "version", 0, arg_flag, &version_flag, NULL, NULL }
60
};
61
62
int num_args = sizeof(args) / sizeof(args[0]);
63
64
int
65
main(int argc, char **argv)
66
{
67
char buf[1024];
68
krb5_error_code ret;
69
70
krb5_enctype enctype;
71
72
hdb_master_key mkey;
73
74
krb5_program_setup(&context, argc, argv, args, num_args, NULL);
75
76
if(help_flag)
77
krb5_std_usage(0, args, num_args);
78
if(version_flag){
79
print_version(NULL);
80
exit(0);
81
}
82
83
if (master_key_fd != -1 && random_key_flag)
84
krb5_errx(context, 1, "random-key and master-key-fd "
85
"is mutual exclusive");
86
87
if (keyfile == NULL)
88
asprintf(&keyfile, "%s/m-key", hdb_db_dir(context));
89
90
ret = krb5_string_to_enctype(context, enctype_str, &enctype);
91
if(ret)
92
krb5_err(context, 1, ret, "krb5_string_to_enctype");
93
94
ret = hdb_read_master_key(context, keyfile, &mkey);
95
if(ret && ret != ENOENT)
96
krb5_err(context, 1, ret, "reading master key from %s", keyfile);
97
98
if (convert_flag) {
99
if (ret)
100
krb5_err(context, 1, ret, "reading master key from %s", keyfile);
101
} else {
102
krb5_keyblock key;
103
krb5_salt salt;
104
salt.salttype = KRB5_PW_SALT;
105
/* XXX better value? */
106
salt.saltvalue.data = NULL;
107
salt.saltvalue.length = 0;
108
if (random_key_flag) {
109
ret = krb5_generate_random_keyblock(context, enctype, &key);
110
if (ret)
111
krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
112
113
} else {
114
if(master_key_fd != -1) {
115
ssize_t n;
116
n = read(master_key_fd, buf, sizeof(buf));
117
if(n <= 0)
118
krb5_err(context, 1, errno, "failed to read passphrase");
119
buf[n] = '\0';
120
buf[strcspn(buf, "\r\n")] = '\0';
121
122
} else {
123
if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Master key: ", 1))
124
exit(1);
125
}
126
krb5_string_to_key_salt(context, enctype, buf, salt, &key);
127
}
128
ret = hdb_add_master_key(context, &key, &mkey);
129
if (ret)
130
krb5_err(context, 1, ret, "hdb_add_master_key");
131
132
krb5_free_keyblock_contents(context, &key);
133
134
}
135
136
{
137
char *new, *old;
138
asprintf(&old, "%s.old", keyfile);
139
asprintf(&new, "%s.new", keyfile);
140
if(unlink(new) < 0 && errno != ENOENT) {
141
ret = errno;
142
goto out;
143
}
144
krb5_warnx(context, "writing key to `%s'", keyfile);
145
ret = hdb_write_master_key(context, new, mkey);
146
if(ret)
147
unlink(new);
148
else {
149
#ifndef NO_POSIX_LINKS
150
unlink(old);
151
if(link(keyfile, old) < 0 && errno != ENOENT) {
152
ret = errno;
153
unlink(new);
154
} else {
155
#endif
156
if(rename(new, keyfile) < 0) {
157
ret = errno;
158
}
159
#ifndef NO_POSIX_LINKS
160
}
161
#endif
162
}
163
out:
164
free(old);
165
free(new);
166
if(ret)
167
krb5_warn(context, errno, "writing master key file");
168
}
169
170
hdb_free_master_key(context, mkey);
171
172
exit(ret != 0);
173
}
174
175