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