1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "ask-password-api.h"
4 #include "cryptenroll-password.h"
6 #include "errno-util.h"
8 #include "memory-util.h"
9 #include "password-quality-util.h"
12 int load_volume_key_password(
13 struct crypt_device
*cd
,
18 _cleanup_(erase_and_freep
) char *envpw
= NULL
;
26 r
= getenv_steal_erase("PASSWORD", &envpw
);
28 return log_error_errno(r
, "Failed to acquire password from environment: %m");
30 r
= crypt_volume_key_get(
38 return log_error_errno(r
, "Password from environment variable $PASSWORD did not work: %m");
40 AskPasswordFlags ask_password_flags
= ASK_PASSWORD_PUSH_CACHE
|ASK_PASSWORD_ACCEPT_CACHED
;
41 _cleanup_free_
char *question
= NULL
, *disk_path
= NULL
;
45 question
= strjoin("Please enter current passphrase for disk ", cd_node
, ":");
49 disk_path
= cescape(cd_node
);
53 id
= strjoina("cryptsetup:", disk_path
);
56 _cleanup_strv_free_erase_
char **passwords
= NULL
;
59 return log_error_errno(SYNTHETIC_ERRNO(ENOKEY
),
60 "Too many attempts, giving up.");
62 r
= ask_password_auto(
63 question
, "drive-harddisk", id
, "cryptenroll", "cryptenroll.passphrase", USEC_INFINITY
,
67 return log_error_errno(r
, "Failed to query password: %m");
70 STRV_FOREACH(p
, passwords
) {
71 r
= crypt_volume_key_get(
84 log_error_errno(r
, "Password not correct, please try again: %m");
85 ask_password_flags
&= ~ASK_PASSWORD_ACCEPT_CACHED
;
93 struct crypt_device
*cd
,
94 const void *volume_key
,
95 size_t volume_key_size
) {
97 _cleanup_(erase_and_freep
) char *new_password
= NULL
;
98 _cleanup_free_
char *error
= NULL
;
102 assert_se(node
= crypt_get_device_name(cd
));
104 r
= getenv_steal_erase("NEWPASSWORD", &new_password
);
106 return log_error_errno(r
, "Failed to acquire password from environment: %m");
108 _cleanup_free_
char *disk_path
= NULL
;
112 assert_se(node
= crypt_get_device_name(cd
));
114 (void) suggest_passwords();
116 disk_path
= cescape(node
);
120 id
= strjoina("cryptsetup:", disk_path
);
123 _cleanup_strv_free_erase_
char **passwords
= NULL
, **passwords2
= NULL
;
124 _cleanup_free_
char *question
= NULL
;
127 return log_error_errno(SYNTHETIC_ERRNO(ENOKEY
),
128 "Too many attempts, giving up.");
130 question
= strjoin("Please enter new passphrase for disk ", node
, ":");
134 r
= ask_password_auto(question
, "drive-harddisk", id
, "cryptenroll", "cryptenroll.new-passphrase", USEC_INFINITY
, 0, &passwords
);
136 return log_error_errno(r
, "Failed to query password: %m");
138 assert(strv_length(passwords
) == 1);
141 question
= strjoin("Please enter new passphrase for disk ", node
, " (repeat):");
145 r
= ask_password_auto(question
, "drive-harddisk", id
, "cryptenroll", "cryptenroll.new-passphrase", USEC_INFINITY
, 0, &passwords2
);
147 return log_error_errno(r
, "Failed to query password: %m");
149 assert(strv_length(passwords2
) == 1);
151 if (strv_equal(passwords
, passwords2
)) {
152 new_password
= passwords2
[0];
153 passwords2
= mfree(passwords2
);
157 log_error("Password didn't match, try again.");
161 r
= check_password_quality(new_password
, /* old */ NULL
, /* user */ NULL
, &error
);
163 if (ERRNO_IS_NOT_SUPPORTED(r
))
164 log_warning("Password quality check is not supported, proceeding anyway.");
166 return log_error_errno(r
, "Failed to check password quality: %m");
169 log_warning("Specified password does not pass quality checks (%s), proceeding anyway.", error
);
171 keyslot
= crypt_keyslot_add_by_volume_key(
177 strlen(new_password
));
179 return log_error_errno(keyslot
, "Failed to add new password to %s: %m", node
);
181 log_info("New password enrolled as key slot %i.", keyslot
);