]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/cryptenroll/cryptenroll-password.c
Merge pull request #18990 from yuwata/network-dhcpv6-use-domains
[thirdparty/systemd.git] / src / cryptenroll / cryptenroll-password.c
CommitLineData
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
10int 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}