]>
Commit | Line | Data |
---|---|---|
8710a681 LP |
1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | ||
3 | #include "ask-password-api.h" | |
4 | #include "cryptenroll-password.h" | |
5 | #include "escape.h" | |
6 | #include "memory-util.h" | |
7 | #include "pwquality-util.h" | |
8 | #include "strv.h" | |
9 | ||
10 | int enroll_password( | |
11 | struct crypt_device *cd, | |
12 | const void *volume_key, | |
13 | size_t volume_key_size) { | |
14 | ||
15 | _cleanup_(erase_and_freep) char *new_password = NULL; | |
16 | _cleanup_free_ char *error = NULL; | |
17 | const char *node; | |
18 | int r, keyslot; | |
19 | char *e; | |
20 | ||
21 | assert_se(node = crypt_get_device_name(cd)); | |
22 | ||
23 | e = getenv("NEWPASSWORD"); | |
24 | if (e) { | |
25 | ||
26 | new_password = strdup(e); | |
27 | if (!new_password) | |
28 | return log_oom(); | |
29 | ||
30 | string_erase(e); | |
31 | assert_se(unsetenv("NEWPASSWORD") == 0); | |
32 | ||
33 | } else { | |
34 | _cleanup_free_ char *disk_path = NULL; | |
35 | unsigned i = 5; | |
36 | const char *id; | |
37 | ||
38 | assert_se(node = crypt_get_device_name(cd)); | |
39 | ||
40 | (void) suggest_passwords(); | |
41 | ||
42 | disk_path = cescape(node); | |
43 | if (!disk_path) | |
44 | return log_oom(); | |
45 | ||
46 | id = strjoina("cryptsetup:", disk_path); | |
47 | ||
48 | for (;;) { | |
49 | _cleanup_strv_free_erase_ char **passwords = NULL, **passwords2 = NULL; | |
50 | _cleanup_free_ char *question = NULL; | |
51 | ||
52 | if (--i == 0) | |
53 | return log_error_errno(SYNTHETIC_ERRNO(ENOKEY), | |
54 | "Too many attempts, giving up:"); | |
55 | ||
56 | question = strjoin("Please enter new passphrase for disk ", node, ":"); | |
57 | if (!question) | |
58 | return log_oom(); | |
59 | ||
8806bb4b | 60 | r = ask_password_auto(question, "drive-harddisk", id, "cryptenroll", "cryptenroll.new-passphrase", USEC_INFINITY, 0, &passwords); |
8710a681 LP |
61 | if (r < 0) |
62 | return log_error_errno(r, "Failed to query password: %m"); | |
63 | ||
64 | assert(strv_length(passwords) == 1); | |
65 | ||
66 | free(question); | |
67 | question = strjoin("Please enter new passphrase for disk ", node, " (repeat):"); | |
68 | if (!question) | |
69 | return log_oom(); | |
70 | ||
8806bb4b | 71 | r = ask_password_auto(question, "drive-harddisk", id, "cryptenroll", "cryptenroll.new-passphrase", USEC_INFINITY, 0, &passwords2); |
8710a681 LP |
72 | if (r < 0) |
73 | return log_error_errno(r, "Failed to query password: %m"); | |
74 | ||
75 | assert(strv_length(passwords2) == 1); | |
76 | ||
77 | if (strv_equal(passwords, passwords2)) { | |
78 | new_password = passwords2[0]; | |
79 | passwords2 = mfree(passwords2); | |
80 | break; | |
81 | } | |
82 | ||
83 | log_error("Password didn't match, try again."); | |
84 | } | |
85 | } | |
86 | ||
87 | r = quality_check_password(new_password, NULL, &error); | |
88 | if (r < 0) | |
89 | return log_error_errno(r, "Failed to check password for quality: %m"); | |
90 | if (r == 0) | |
91 | log_warning_errno(r, "Specified password does not pass quality checks (%s), proceeding anyway.", error); | |
92 | ||
93 | keyslot = crypt_keyslot_add_by_volume_key( | |
94 | cd, | |
95 | CRYPT_ANY_SLOT, | |
96 | volume_key, | |
97 | volume_key_size, | |
98 | new_password, | |
99 | strlen(new_password)); | |
100 | if (keyslot < 0) | |
101 | return log_error_errno(keyslot, "Failed to add new password to %s: %m", node); | |
102 | ||
103 | log_info("New password enrolled as key slot %i.", keyslot); | |
104 | return keyslot; | |
105 | } |