diff --git a/man/systemd-cryptenroll.xml b/man/systemd-cryptenroll.xml
index dfc6d31cf4..c687ac31bb 100644
--- a/man/systemd-cryptenroll.xml
+++ b/man/systemd-cryptenroll.xml
@@ -650,6 +650,51 @@
+
+ Credentials
+
+ systemd-cryptenroll supports the service credentials logic as implemented by
+ ImportCredential=/LoadCredential=/SetCredential=
+ (see systemd.exec5 for
+ details). The following credentials are used when passed in:
+
+
+
+ cryptenroll.passphrase
+ cryptenroll.new-passphrase
+
+ May contain the passphrase to unlock the volume with/to newly enroll.
+
+
+
+
+
+ cryptenroll.tpm2-pin
+ cryptenroll.new-tpm2-pin
+
+ May contain the TPM2 PIN to unlock the volume with/to newly enroll.
+
+
+
+
+
+ cryptenroll.fido2-pin
+
+ If a FIDO2 token is enrolled this may contain the PIN of the token.
+
+
+
+
+
+ cryptenroll.pkcs11-pin
+
+ If a PKCS#11 token is enrolled this may contain the PIN of the token.
+
+
+
+
+
+
Exit status
diff --git a/man/systemd-cryptsetup.xml b/man/systemd-cryptsetup.xml
index 5f12dc4748..72dc56390f 100644
--- a/man/systemd-cryptsetup.xml
+++ b/man/systemd-cryptsetup.xml
@@ -105,7 +105,7 @@
- System Credentials
+ Credentials
systemd-cryptsetup supports the service credentials logic as implemented by
ImportCredential=/LoadCredential=/SetCredential=
@@ -122,14 +122,6 @@
-
- cryptsetup.fido2-pin
-
- This credential specifies the FIDO2 token pin.
-
-
-
-
cryptsetup.tpm2-pin
@@ -139,9 +131,9 @@
- cryptsetup.luks2-pin
+ cryptsetup.fido2-pin
- This credential specifies the LUKS2 token pin.
+ This credential specifies the FIDO2 token pin.
@@ -153,6 +145,14 @@
+
+
+ cryptsetup.luks2-pin
+
+ This credential specifies the PIN requested by generic LUKS2 token modules.
+
+
+
diff --git a/man/systemd.system-credentials.xml b/man/systemd.system-credentials.xml
index 749d3bfb15..2a345c47b4 100644
--- a/man/systemd.system-credentials.xml
+++ b/man/systemd.system-credentials.xml
@@ -353,6 +353,20 @@
+
+
+ cryptsetup.passphrase
+ cryptsetup.tpm2-pin
+ cryptsetup.fido2-pin
+ cryptsetup.pkcs11-pin
+ cryptsetup.luks2-pin
+
+ Specifies the passphrase/PINs to use for unlock encrypted storage volumes. For details see
+ systemd-cryptsetup8.
+
+
+
+
diff --git a/src/ask-password/ask-password.c b/src/ask-password/ask-password.c
index bf4c93e2dc..371d316332 100644
--- a/src/ask-password/ask-password.c
+++ b/src/ask-password/ask-password.c
@@ -239,7 +239,15 @@ static int run(int argc, char *argv[]) {
else
timeout = 0;
- r = ask_password_auto(arg_message, arg_icon, arg_id, arg_key_name, arg_credential_name ?: "password", timeout, arg_flags, &l);
+ AskPasswordRequest req = {
+ .message = arg_message,
+ .icon = arg_icon,
+ .id = arg_id,
+ .keyring = arg_key_name,
+ .credential = arg_credential_name ?: "password",
+ };
+
+ r = ask_password_auto(&req, timeout, arg_flags, &l);
if (r < 0)
return log_error_errno(r, "Failed to query password: %m");
diff --git a/src/cryptenroll/cryptenroll-fido2.c b/src/cryptenroll/cryptenroll-fido2.c
index 2baeb92e07..baa630a6b3 100644
--- a/src/cryptenroll/cryptenroll-fido2.c
+++ b/src/cryptenroll/cryptenroll-fido2.c
@@ -33,10 +33,10 @@ int load_volume_key_fido2(
cd_node,
device,
/* until= */ 0,
- /* headless= */ false,
+ "cryptenroll.fido2-pin",
+ ASK_PASSWORD_PUSH_CACHE|ASK_PASSWORD_ACCEPT_CACHED,
&decrypted_key,
- &decrypted_key_size,
- ASK_PASSWORD_PUSH_CACHE|ASK_PASSWORD_ACCEPT_CACHED);
+ &decrypted_key_size);
if (r == -EAGAIN)
return log_error_errno(r, "FIDO2 token does not exist, or UV is blocked. Please try again.");
if (r < 0)
@@ -97,6 +97,7 @@ int enroll_fido2(
/* user_display_name= */ node,
/* user_icon_name= */ NULL,
/* askpw_icon_name= */ "drive-harddisk",
+ /* askpw_credential= */ "cryptenroll.fido2-pin",
lock_with,
cred_alg,
&cid, &cid_size,
diff --git a/src/cryptenroll/cryptenroll-password.c b/src/cryptenroll/cryptenroll-password.c
index c35b6092c8..a9bd8a1dd0 100644
--- a/src/cryptenroll/cryptenroll-password.c
+++ b/src/cryptenroll/cryptenroll-password.c
@@ -38,9 +38,8 @@ int load_volume_key_password(
return log_error_errno(r, "Password from environment variable $PASSWORD did not work: %m");
} else {
AskPasswordFlags ask_password_flags = ASK_PASSWORD_PUSH_CACHE|ASK_PASSWORD_ACCEPT_CACHED;
- _cleanup_free_ char *question = NULL, *disk_path = NULL;
+ _cleanup_free_ char *question = NULL, *id = NULL, *disk_path = NULL;
unsigned i = 5;
- const char *id;
question = strjoin("Please enter current passphrase for disk ", cd_node, ":");
if (!question)
@@ -50,7 +49,17 @@ int load_volume_key_password(
if (!disk_path)
return log_oom();
- id = strjoina("cryptsetup:", disk_path);
+ id = strjoin("cryptenroll:", disk_path);
+ if (!id)
+ return log_oom();
+
+ AskPasswordRequest req = {
+ .message = question,
+ .icon = "drive-harddisk",
+ .id = id,
+ .keyring = "cryptenroll",
+ .credential = "cryptenroll.passphrase",
+ };
for (;;) {
_cleanup_strv_free_erase_ char **passwords = NULL;
@@ -59,10 +68,7 @@ int load_volume_key_password(
return log_error_errno(SYNTHETIC_ERRNO(ENOKEY),
"Too many attempts, giving up.");
- r = ask_password_auto(
- question, "drive-harddisk", id, "cryptenroll", "cryptenroll.passphrase", USEC_INFINITY,
- ask_password_flags,
- &passwords);
+ r = ask_password_auto(&req, USEC_INFINITY, ask_password_flags, &passwords);
if (r < 0)
return log_error_errno(r, "Failed to query password: %m");
@@ -105,9 +111,8 @@ int enroll_password(
if (r < 0)
return log_error_errno(r, "Failed to acquire password from environment: %m");
if (r == 0) {
- _cleanup_free_ char *disk_path = NULL;
+ _cleanup_free_ char *disk_path = NULL, *id = NULL;
unsigned i = 5;
- const char *id;
assert_se(node = crypt_get_device_name(cd));
@@ -117,7 +122,16 @@ int enroll_password(
if (!disk_path)
return log_oom();
- id = strjoina("cryptsetup:", disk_path);
+ id = strjoin("cryptenroll-new:", disk_path);
+ if (!id)
+ return log_oom();
+
+ AskPasswordRequest req = {
+ .icon = "drive-harddisk",
+ .id = id,
+ .keyring = "cryptenroll",
+ .credential = "cryptenroll.new-passphrase",
+ };
for (;;) {
_cleanup_strv_free_erase_ char **passwords = NULL, **passwords2 = NULL;
@@ -131,7 +145,9 @@ int enroll_password(
if (!question)
return log_oom();
- r = ask_password_auto(question, "drive-harddisk", id, "cryptenroll", "cryptenroll.new-passphrase", USEC_INFINITY, 0, &passwords);
+ req.message = question;
+
+ r = ask_password_auto(&req, USEC_INFINITY, /* flags= */ 0, &passwords);
if (r < 0)
return log_error_errno(r, "Failed to query password: %m");
@@ -142,7 +158,9 @@ int enroll_password(
if (!question)
return log_oom();
- r = ask_password_auto(question, "drive-harddisk", id, "cryptenroll", "cryptenroll.new-passphrase", USEC_INFINITY, 0, &passwords2);
+ req.message = question;
+
+ r = ask_password_auto(&req, USEC_INFINITY, /* flags= */ 0, &passwords2);
if (r < 0)
return log_error_errno(r, "Failed to query password: %m");
diff --git a/src/cryptenroll/cryptenroll-pkcs11.c b/src/cryptenroll/cryptenroll-pkcs11.c
index 6b70a147c3..09875c1598 100644
--- a/src/cryptenroll/cryptenroll-pkcs11.c
+++ b/src/cryptenroll/cryptenroll-pkcs11.c
@@ -55,7 +55,14 @@ int enroll_pkcs11(
assert_se(node = crypt_get_device_name(cd));
- r = pkcs11_acquire_public_key(uri, "volume enrollment operation", "drive-harddisk", &pkey, NULL);
+ r = pkcs11_acquire_public_key(
+ uri,
+ "volume enrollment operation",
+ "drive-harddisk",
+ "cryptenroll.pkcs11-pin",
+ /* askpw_flags= */ 0,
+ &pkey,
+ /* ret_pin_used= */ NULL);
if (r < 0)
return r;
diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c
index fb862a3329..3ded815fb0 100644
--- a/src/cryptenroll/cryptenroll-tpm2.c
+++ b/src/cryptenroll/cryptenroll-tpm2.c
@@ -87,28 +87,29 @@ static int get_pin(char **ret_pin_str, TPM2Flags *ret_flags) {
return log_error_errno(
SYNTHETIC_ERRNO(ENOKEY), "Too many attempts, giving up.");
+ AskPasswordRequest req = {
+ .message = "Please enter TPM2 PIN:",
+ .icon = "drive-harddisk",
+ .keyring = "tpm2-pin",
+ .credential = "cryptenroll.new-tpm2-pin",
+ };
+
pin = strv_free_erase(pin);
r = ask_password_auto(
- "Please enter TPM2 PIN:",
- "drive-harddisk",
- NULL,
- "tpm2-pin",
- "cryptenroll.tpm2-pin",
- USEC_INFINITY,
- 0,
+ &req,
+ /* until= */ USEC_INFINITY,
+ /* flags= */ 0,
&pin);
if (r < 0)
return log_error_errno(r, "Failed to ask for user pin: %m");
assert(strv_length(pin) == 1);
+ req.message = "Please enter TPM2 PIN (repeat):";
+
r = ask_password_auto(
- "Please enter TPM2 PIN (repeat):",
- "drive-harddisk",
- NULL,
- "tpm2-pin",
- "cryptenroll.tpm2-pin",
+ &req,
USEC_INFINITY,
- 0,
+ /* flags= */ 0,
&pin2);
if (r < 0)
return log_error_errno(r, "Failed to ask for user pin: %m");
@@ -209,8 +210,8 @@ int load_volume_key_tpm2(
&pcrlock_nv,
tpm2_flags,
/* until= */ 0,
- /* headless= */ false,
- /* ask_password_flags */ false,
+ "cryptenroll.tpm2-pin",
+ /* askpw_flags= */ 0,
&decrypted_key);
if (IN_SET(r, -EACCES, -ENOLCK))
return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN), "TPM2 PIN unlock failed");
diff --git a/src/cryptsetup/cryptsetup-pkcs11.c b/src/cryptsetup/cryptsetup-pkcs11.c
index 4ef249509d..4b2b5bbf00 100644
--- a/src/cryptsetup/cryptsetup-pkcs11.c
+++ b/src/cryptsetup/cryptsetup-pkcs11.c
@@ -34,14 +34,14 @@ int decrypt_pkcs11_key(
const void *key_data, /* … or key_data and key_data_size (for literal keys) */
size_t key_data_size,
usec_t until,
- bool headless,
+ AskPasswordFlags askpw_flags,
void **ret_decrypted_key,
size_t *ret_decrypted_key_size) {
_cleanup_(pkcs11_crypt_device_callback_data_release) pkcs11_crypt_device_callback_data data = {
.friendly_name = friendly_name,
+ .askpw_flags = askpw_flags,
.until = until,
- .headless = headless,
};
int r;
diff --git a/src/cryptsetup/cryptsetup-pkcs11.h b/src/cryptsetup/cryptsetup-pkcs11.h
index 256c09a9b6..22e6992582 100644
--- a/src/cryptsetup/cryptsetup-pkcs11.h
+++ b/src/cryptsetup/cryptsetup-pkcs11.h
@@ -19,7 +19,7 @@ int decrypt_pkcs11_key(
const void *key_data,
size_t key_data_size,
usec_t until,
- bool headless,
+ AskPasswordFlags askpw_flags,
void **ret_decrypted_key,
size_t *ret_decrypted_key_size);
@@ -42,7 +42,7 @@ static inline int decrypt_pkcs11_key(
const void *key_data,
size_t key_data_size,
usec_t until,
- bool headless,
+ AskPasswordFlags askpw_flags,
void **ret_decrypted_key,
size_t *ret_decrypted_key_size) {
diff --git a/src/cryptsetup/cryptsetup-tokens/luks2-pkcs11.c b/src/cryptsetup/cryptsetup-tokens/luks2-pkcs11.c
index 512a4cf18a..ac5100f688 100644
--- a/src/cryptsetup/cryptsetup-tokens/luks2-pkcs11.c
+++ b/src/cryptsetup/cryptsetup-tokens/luks2-pkcs11.c
@@ -157,7 +157,7 @@ static int acquire_luks2_key_systemd(
assert(params);
data.friendly_name = params->friendly_name;
- data.headless = params->headless;
+ data.askpw_credential = params->askpw_credential;
data.askpw_flags = params->askpw_flags;
data.until = params->until;
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 1caaa514d5..7099f68f88 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -101,7 +101,6 @@ static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
static char *arg_tpm2_signature = NULL;
static bool arg_tpm2_pin = false;
static char *arg_tpm2_pcrlock = NULL;
-static bool arg_headless = false;
static usec_t arg_token_timeout_usec = 30*USEC_PER_SEC;
static unsigned arg_tpm2_measure_pcr = UINT_MAX; /* This and the following field is about measuring the unlocked volume key to the local TPM */
static char **arg_tpm2_measure_banks = NULL;
@@ -504,9 +503,9 @@ static int parse_one_option(const char *option) {
return 0;
}
- arg_headless = r;
+ SET_FLAG(arg_ask_password_flags, ASK_PASSWORD_HEADLESS, r);
} else if (streq(option, "headless"))
- arg_headless = true;
+ arg_ask_password_flags |= ASK_PASSWORD_HEADLESS;
else if ((val = startswith(option, "token-timeout="))) {
@@ -798,17 +797,16 @@ static int get_password(
PassphraseType passphrase_type,
char ***ret) {
- _cleanup_free_ char *friendly = NULL, *text = NULL, *disk_path = NULL;
+ _cleanup_free_ char *friendly = NULL, *text = NULL, *disk_path = NULL, *id = NULL;
_cleanup_strv_free_erase_ char **passwords = NULL;
- char *id;
- int r = 0;
AskPasswordFlags flags = arg_ask_password_flags | ASK_PASSWORD_PUSH_CACHE;
+ int r;
assert(vol);
assert(src);
assert(ret);
- if (arg_headless)
+ if (FLAGS_SET(arg_ask_password_flags, ASK_PASSWORD_HEADLESS))
return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "Password querying disabled via 'headless' option.");
friendly = friendly_disk_name(src, vol);
@@ -822,11 +820,23 @@ static int get_password(
if (!disk_path)
return log_oom();
- id = strjoina("cryptsetup:", disk_path);
+ id = strjoin("cryptsetup:", disk_path);
+ if (!id)
+ return log_oom();
- r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", "cryptsetup.passphrase", until,
- flags | (accept_cached*ASK_PASSWORD_ACCEPT_CACHED),
- &passwords);
+ AskPasswordRequest req = {
+ .message = text,
+ .icon = "drive-harddisk",
+ .id = id,
+ .keyring = "cryptsetup",
+ .credential = "cryptsetup.passphrase",
+ };
+
+ r = ask_password_auto(
+ &req,
+ until,
+ flags | (accept_cached*ASK_PASSWORD_ACCEPT_CACHED),
+ &passwords);
if (r < 0)
return log_error_errno(r, "Failed to query password: %m");
@@ -835,12 +845,19 @@ static int get_password(
assert(strv_length(passwords) == 1);
+ text = mfree(text);
if (asprintf(&text, "Please enter %s for disk %s (verification):", passphrase_type_to_string(passphrase_type), friendly) < 0)
return log_oom();
- id = strjoina("cryptsetup-verification:", disk_path);
+ free(id);
+ id = strjoin("cryptsetup-verification:", disk_path);
+ if (!id)
+ return log_oom();
- r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", "cryptsetup.passphrase", until, flags, &passwords2);
+ req.message = text;
+ req.id = id;
+
+ r = ask_password_auto(&req, until, flags, &passwords2);
if (r < 0)
return log_error_errno(r, "Failed to query verification password: %m");
@@ -1248,12 +1265,11 @@ static int crypt_activate_by_token_pin_ask_password(
const char *name,
const char *type,
usec_t until,
- bool headless,
void *userdata,
uint32_t activation_flags,
const char *message,
- const char *key_name,
- const char *credential_name) {
+ const char *keyring,
+ const char *credential) {
#if HAVE_LIBCRYPTSETUP_PLUGINS
AskPasswordFlags flags = arg_ask_password_flags | ASK_PASSWORD_PUSH_CACHE | ASK_PASSWORD_ACCEPT_CACHED;
@@ -1278,12 +1294,20 @@ static int crypt_activate_by_token_pin_ask_password(
return r;
}
- if (headless)
+ if (FLAGS_SET(arg_ask_password_flags, ASK_PASSWORD_HEADLESS))
return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the '$PIN' environment variable.");
for (;;) {
pins = strv_free_erase(pins);
- r = ask_password_auto(message, "drive-harddisk", /* id= */ NULL, key_name, credential_name, until, flags, &pins);
+
+ AskPasswordRequest req = {
+ .message = message,
+ .icon = "drive-harddisk",
+ .keyring = keyring,
+ .credential = credential,
+ };
+
+ r = ask_password_auto(&req, until, flags, &pins);
if (r < 0)
return r;
@@ -1307,7 +1331,6 @@ static int attach_luks2_by_fido2_via_plugin(
struct crypt_device *cd,
const char *name,
usec_t until,
- bool headless,
void *userdata,
uint32_t activation_flags) {
@@ -1316,7 +1339,6 @@ static int attach_luks2_by_fido2_via_plugin(
name,
"systemd-fido2",
until,
- headless,
userdata,
activation_flags,
"Please enter security token PIN:",
@@ -1371,7 +1393,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
for (;;) {
if (use_libcryptsetup_plugin && !arg_fido2_cid) {
- r = attach_luks2_by_fido2_via_plugin(cd, name, until, arg_headless, arg_fido2_device, flags);
+ r = attach_luks2_by_fido2_via_plugin(cd, name, until, arg_fido2_device, flags);
if (IN_SET(r, -ENOTUNIQ, -ENXIO, -ENOENT))
return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
"Automatic FIDO2 metadata discovery was not possible because missing or not unique, falling back to traditional unlocking.");
@@ -1387,10 +1409,11 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
key_file, arg_keyfile_size, arg_keyfile_offset,
key_data, key_data_size,
until,
- arg_headless,
required,
- &decrypted_key, &decrypted_key_size,
- arg_ask_password_flags);
+ "cryptsetup.fido2-pin",
+ arg_ask_password_flags,
+ &decrypted_key,
+ &decrypted_key_size);
else
r = acquire_fido2_key_auto(
cd,
@@ -1398,9 +1421,10 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
friendly,
arg_fido2_device,
until,
- arg_headless,
- &decrypted_key, &decrypted_key_size,
- arg_ask_password_flags);
+ "cryptsetup.fido2-pin",
+ arg_ask_password_flags,
+ &decrypted_key,
+ &decrypted_key_size);
if (r >= 0)
break;
}
@@ -1461,7 +1485,7 @@ static int attach_luks2_by_pkcs11_via_plugin(
const char *name,
const char *friendly_name,
usec_t until,
- bool headless,
+ const char *askpw_credential,
uint32_t flags) {
#if HAVE_LIBCRYPTSETUP_PLUGINS
@@ -1473,7 +1497,7 @@ static int attach_luks2_by_pkcs11_via_plugin(
systemd_pkcs11_plugin_params params = {
.friendly_name = friendly_name,
.until = until,
- .headless = headless,
+ .askpw_credential = askpw_credential,
.askpw_flags = arg_ask_password_flags,
};
@@ -1537,7 +1561,13 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
for (;;) {
if (use_libcryptsetup_plugin && arg_pkcs11_uri_auto)
- r = attach_luks2_by_pkcs11_via_plugin(cd, name, friendly, until, arg_headless, flags);
+ r = attach_luks2_by_pkcs11_via_plugin(
+ cd,
+ name,
+ friendly,
+ until,
+ "cryptsetup.pkcs11-pin",
+ flags);
else {
r = decrypt_pkcs11_key(
name,
@@ -1546,7 +1576,7 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
key_file, arg_keyfile_size, arg_keyfile_offset,
key_data, key_data_size,
until,
- arg_headless,
+ arg_ask_password_flags,
&decrypted_key, &decrypted_key_size);
if (r >= 0)
break;
@@ -1671,7 +1701,6 @@ static int attach_luks2_by_tpm2_via_plugin(
struct crypt_device *cd,
const char *name,
usec_t until,
- bool headless,
uint32_t flags) {
#if HAVE_LIBCRYPTSETUP_PLUGINS
@@ -1691,7 +1720,6 @@ static int attach_luks2_by_tpm2_via_plugin(
name,
"systemd-tpm2",
until,
- headless,
¶ms,
flags,
"Please enter TPM2 PIN:",
@@ -1747,7 +1775,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
/* pcrlock_nv= */ NULL,
arg_tpm2_pin ? TPM2_FLAGS_USE_PIN : 0,
until,
- arg_headless,
+ "cryptsetup.tpm2-pin",
arg_ask_password_flags,
&decrypted_key);
if (r >= 0)
@@ -1762,7 +1790,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
return -EAGAIN; /* Mangle error code: let's make any form of TPM2 failure non-fatal. */
}
} else {
- r = attach_luks2_by_tpm2_via_plugin(cd, name, until, arg_headless, flags);
+ r = attach_luks2_by_tpm2_via_plugin(cd, name, until, flags);
if (r >= 0)
return 0;
/* EAGAIN means: no tpm2 chip found
@@ -1845,7 +1873,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
&pcrlock_nv,
tpm2_flags,
until,
- arg_headless,
+ "cryptsetup.tpm2-pin",
arg_ask_password_flags,
&decrypted_key);
if (IN_SET(r, -EACCES, -ENOLCK))
@@ -2365,7 +2393,6 @@ static int run(int argc, char *argv[]) {
volume,
/* type= */ NULL,
until,
- arg_headless,
/* userdata= */ NULL,
flags,
"Please enter LUKS2 token PIN:",
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 76af4e4ed5..d9d2e28251 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -797,7 +797,11 @@ static int prompt_root_password(int rfd) {
_cleanup_strv_free_erase_ char **a = NULL, **b = NULL;
_cleanup_free_ char *error = NULL;
- r = ask_password_tty(-1, msg1, NULL, 0, 0, NULL, &a);
+ AskPasswordRequest req = {
+ .message = msg1,
+ };
+
+ r = ask_password_tty(-EBADF, &req, /* until= */ 0, /* flags= */ 0, /* flag_file= */ NULL, &a);
if (r < 0)
return log_error_errno(r, "Failed to query root password: %m");
if (strv_length(a) != 1)
@@ -817,7 +821,9 @@ static int prompt_root_password(int rfd) {
else if (r == 0)
log_warning("Password is weak, accepting anyway: %s", error);
- r = ask_password_tty(-1, msg2, NULL, 0, 0, NULL, &b);
+ req.message = msg2;
+
+ r = ask_password_tty(-EBADF, &req, /* until= */ 0, /* flags= */ 0, /* flag_file= */ NULL, &b);
if (r < 0)
return log_error_errno(r, "Failed to query root password: %m");
if (strv_length(b) != 1)
diff --git a/src/home/homectl-fido2.c b/src/home/homectl-fido2.c
index 3cbdf912aa..384461a1ca 100644
--- a/src/home/homectl-fido2.c
+++ b/src/home/homectl-fido2.c
@@ -167,6 +167,7 @@ int identity_add_fido2_parameters(
/* user_display_name= */ rn ? json_variant_string(rn) : NULL,
/* user_icon_name= */ NULL,
/* askpw_icon_name= */ "user-home",
+ /* askpw_credential= */ "home.token-pin",
lock_with,
cred_alg,
&cid, &cid_size,
diff --git a/src/home/homectl-pkcs11.c b/src/home/homectl-pkcs11.c
index 5c54ec016e..bb582d7d47 100644
--- a/src/home/homectl-pkcs11.c
+++ b/src/home/homectl-pkcs11.c
@@ -153,7 +153,14 @@ int identity_add_pkcs11_key_data(JsonVariant **v, const char *uri) {
assert(v);
- r = pkcs11_acquire_public_key(uri, "home directory operation", "user-home", &pkey, &pin);
+ r = pkcs11_acquire_public_key(
+ uri,
+ "home directory operation",
+ "user-home",
+ "home.token-pin",
+ /* askpw_flags= */ 0,
+ &pkey,
+ &pin);
if (r < 0)
return r;
diff --git a/src/home/homectl.c b/src/home/homectl.c
index 5357e791a5..3a839c73ea 100644
--- a/src/home/homectl.c
+++ b/src/home/homectl.c
@@ -261,14 +261,14 @@ static int acquire_existing_password(
user_name) < 0)
return log_oom();
- r = ask_password_auto(question,
- /* icon= */ "user-home",
- NULL,
- /* key_name= */ "home-password",
- /* credential_name= */ "home.password",
- USEC_INFINITY,
- flags,
- &password);
+ AskPasswordRequest req = {
+ .message = question,
+ .icon = "user-home",
+ .keyring = "home-password",
+ .credential = "home.password",
+ };
+
+ r = ask_password_auto(&req, USEC_INFINITY, flags, &password);
if (r == -EUNATCH) { /* EUNATCH is returned if no password was found and asking interactively was
* disabled via the flags. Not an error for us. */
log_debug_errno(r, "No passwords acquired.");
@@ -319,14 +319,14 @@ static int acquire_recovery_key(
if (asprintf(&question, "Please enter recovery key for user %s:", user_name) < 0)
return log_oom();
- r = ask_password_auto(question,
- /* icon= */ "user-home",
- NULL,
- /* key_name= */ "home-recovery-key",
- /* credential_name= */ "home.recovery-key",
- USEC_INFINITY,
- flags,
- &recovery_key);
+ AskPasswordRequest req = {
+ .message = question,
+ .icon = "user-home",
+ .keyring = "home-recovery-key",
+ .credential = "home.recovery-key",
+ };
+
+ r = ask_password_auto(&req, USEC_INFINITY, flags, &recovery_key);
if (r == -EUNATCH) { /* EUNATCH is returned if no recovery key was found and asking interactively was
* disabled via the flags. Not an error for us. */
log_debug_errno(r, "No recovery keys acquired.");
@@ -373,15 +373,14 @@ static int acquire_token_pin(
if (asprintf(&question, "Please enter security token PIN for user %s:", user_name) < 0)
return log_oom();
- r = ask_password_auto(
- question,
- /* icon= */ "user-home",
- NULL,
- /* key_name= */ "token-pin",
- /* credential_name= */ "home.token-pin",
- USEC_INFINITY,
- flags,
- &pin);
+ AskPasswordRequest req = {
+ .message = question,
+ .icon = "user-home",
+ .keyring = "token-pin",
+ .credential = "home.token-pin",
+ };
+
+ r = ask_password_auto(&req, USEC_INFINITY, flags, &pin);
if (r == -EUNATCH) { /* EUNATCH is returned if no PIN was found and asking interactively was disabled
* via the flags. Not an error for us. */
log_debug_errno(r, "No security token PINs acquired.");
@@ -1228,14 +1227,17 @@ static int acquire_new_password(
if (asprintf(&question, "Please enter new password for user %s:", user_name) < 0)
return log_oom();
+ AskPasswordRequest req = {
+ .message = question,
+ .icon = "user-home",
+ .keyring = "home-password",
+ .credential = "home.new-password",
+ };
+
r = ask_password_auto(
- question,
- /* icon= */ "user-home",
- NULL,
- /* key_name= */ "home-password",
- /* credential_name= */ "home.new-password",
+ &req,
USEC_INFINITY,
- 0, /* no caching, we want to collect a new password here after all */
+ /* flags= */ 0, /* no caching, we want to collect a new password here after all */
&first);
if (r < 0)
return log_error_errno(r, "Failed to acquire password: %m");
@@ -1244,14 +1246,12 @@ static int acquire_new_password(
if (asprintf(&question, "Please enter new password for user %s (repeat):", user_name) < 0)
return log_oom();
+ req.message = question;
+
r = ask_password_auto(
- question,
- /* icon= */ "user-home",
- NULL,
- /* key_name= */ "home-password",
- /* credential_name= */ "home.new-password",
+ &req,
USEC_INFINITY,
- 0, /* no caching */
+ /* flags= */ 0, /* no caching */
&second);
if (r < 0)
return log_error_errno(r, "Failed to acquire password: %m");
diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c
index 1dd3d86a73..e70c44c675 100644
--- a/src/pcrlock/pcrlock.c
+++ b/src/pcrlock/pcrlock.c
@@ -4444,12 +4444,14 @@ static int make_policy(bool force, bool recovery_pin) {
if (r == 0) {
_cleanup_(strv_free_erasep) char **l = NULL;
+ AskPasswordRequest req = {
+ .message = "Recovery PIN",
+ .id = "pcrlock-recovery-pin",
+ .credential = "pcrlock.recovery-pin",
+ };
+
r = ask_password_auto(
- "Recovery PIN",
- /* icon= */ NULL,
- /* id= */ "pcrlock-recovery-pin",
- /* key_name= */ NULL,
- /* credential_name= */ "systemd-pcrlock.recovery-pin",
+ &req,
/* until= */ 0,
/* flags= */ 0,
&l);
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index 6d71245549..462b3d2e00 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -147,18 +147,17 @@ static int add_to_keyring_and_log(const char *keyname, AskPasswordFlags flags, c
return 0;
}
-static int ask_password_keyring(const char *keyname, AskPasswordFlags flags, char ***ret) {
-
+static int ask_password_keyring(const AskPasswordRequest *req, AskPasswordFlags flags, char ***ret) {
key_serial_t serial;
int r;
- assert(keyname);
+ assert(req);
assert(ret);
if (!FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED))
return -EUNATCH;
- r = lookup_key(keyname, &serial);
+ r = lookup_key(req->keyring, &serial);
if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || r == -EPERM)
/* When retrieving, the distinction between "kernel or container manager don't support or
* allow this" and "no matching key known" doesn't matter. Note that we propagate EACCESS
@@ -205,7 +204,7 @@ static int backspace_string(int ttyfd, const char *str) {
}
int ask_password_plymouth(
- const char *message,
+ const AskPasswordRequest *req,
usec_t until,
AskPasswordFlags flags,
const char *flag_file,
@@ -225,8 +224,10 @@ int ask_password_plymouth(
assert(ret);
- if (!message)
- message = "Password:";
+ if (FLAGS_SET(flags, ASK_PASSWORD_HEADLESS))
+ return -ENOEXEC;
+
+ const char *message = req && req->message ? req->message : "Password:";
if (flag_file) {
notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
@@ -357,8 +358,7 @@ int ask_password_plymouth(
int ask_password_tty(
int ttyfd,
- const char *message,
- const char *keyname,
+ const AskPasswordRequest *req,
usec_t until,
AskPasswordFlags flags,
const char *flag_file,
@@ -381,16 +381,19 @@ int ask_password_tty(
assert(ret);
+ if (FLAGS_SET(flags, ASK_PASSWORD_HEADLESS))
+ return -ENOEXEC;
+
if (FLAGS_SET(flags, ASK_PASSWORD_NO_TTY))
return -EUNATCH;
- if (!message)
- message = "Password:";
+ const char *message = req && req->message ? req->message : "Password:";
+ const char *keyring = req ? req->keyring : NULL;
if (!FLAGS_SET(flags, ASK_PASSWORD_HIDE_EMOJI) && emoji_enabled())
message = strjoina(special_glyph(SPECIAL_GLYPH_LOCK_AND_KEY), " ", message);
- if (flag_file || (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyname)) {
+ if (flag_file || (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyring)) {
notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
if (notify < 0)
return -errno;
@@ -399,8 +402,8 @@ int ask_password_tty(
if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0)
return -errno;
}
- if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyname) {
- r = ask_password_keyring(keyname, flags, ret);
+ if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && req && keyring) {
+ r = ask_password_keyring(req, flags, ret);
if (r >= 0)
return 0;
else if (r != -ENOKEY)
@@ -487,10 +490,10 @@ int ask_password_tty(
goto finish;
}
- if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0 && keyname) {
+ if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0 && keyring) {
(void) flush_fd(notify);
- r = ask_password_keyring(keyname, flags, ret);
+ r = ask_password_keyring(req, flags, ret);
if (r >= 0) {
r = 0;
goto finish;
@@ -629,8 +632,8 @@ skipped:
if (strv_isempty(l))
r = log_debug_errno(SYNTHETIC_ERRNO(ECANCELED), "Password query was cancelled.");
else {
- if (keyname)
- (void) add_to_keyring_and_log(keyname, flags, l);
+ if (keyring)
+ (void) add_to_keyring_and_log(keyring, flags, l);
*ret = TAKE_PTR(l);
r = 0;
@@ -679,10 +682,7 @@ static int create_socket(char **ret) {
}
int ask_password_agent(
- const char *message,
- const char *icon,
- const char *id,
- const char *keyname,
+ const AskPasswordRequest *req,
usec_t until,
AskPasswordFlags flags,
char ***ret) {
@@ -706,6 +706,9 @@ int ask_password_agent(
assert(ret);
+ if (FLAGS_SET(flags, ASK_PASSWORD_HEADLESS))
+ return -ENOEXEC;
+
if (FLAGS_SET(flags, ASK_PASSWORD_NO_AGENT))
return -EUNATCH;
@@ -715,8 +718,8 @@ int ask_password_agent(
(void) mkdir_p_label("/run/systemd/ask-password", 0755);
- if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyname) {
- r = ask_password_keyring(keyname, flags, ret);
+ if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && req && req->keyring) {
+ r = ask_password_keyring(req, flags, ret);
if (r >= 0) {
r = 0;
goto finish;
@@ -775,14 +778,16 @@ int ask_password_agent(
until,
FLAGS_SET(flags, ASK_PASSWORD_SILENT));
- if (message)
- fprintf(f, "Message=%s\n", message);
+ if (req) {
+ if (req->message)
+ fprintf(f, "Message=%s\n", req->message);
- if (icon)
- fprintf(f, "Icon=%s\n", icon);
+ if (req->icon)
+ fprintf(f, "Icon=%s\n", req->icon);
- if (id)
- fprintf(f, "Id=%s\n", id);
+ if (req->id)
+ fprintf(f, "Id=%s\n", req->id);
+ }
r = fflush_and_check(f);
if (r < 0)
@@ -837,12 +842,14 @@ int ask_password_agent(
if (notify >= 0 && pollfd[FD_INOTIFY].revents != 0) {
(void) flush_fd(notify);
- r = ask_password_keyring(keyname, flags, ret);
- if (r >= 0) {
- r = 0;
- goto finish;
- } else if (r != -ENOKEY)
- goto finish;
+ if (req && req->keyring) {
+ r = ask_password_keyring(req, flags, ret);
+ if (r >= 0) {
+ r = 0;
+ goto finish;
+ } else if (r != -ENOKEY)
+ goto finish;
+ }
}
if (pollfd[FD_SOCKET].revents == 0)
@@ -921,8 +928,8 @@ int ask_password_agent(
log_debug("Invalid packet");
}
- if (keyname)
- (void) add_to_keyring_and_log(keyname, flags, l);
+ if (req && req->keyring)
+ (void) add_to_keyring_and_log(req->keyring, flags, l);
*ret = TAKE_PTR(l);
r = 0;
@@ -940,16 +947,17 @@ finish:
return r;
}
-static int ask_password_credential(const char *credential_name, AskPasswordFlags flags, char ***ret) {
+static int ask_password_credential(const AskPasswordRequest *req, AskPasswordFlags flags, char ***ret) {
_cleanup_(erase_and_freep) char *buffer = NULL;
size_t size;
char **l;
int r;
- assert(credential_name);
+ assert(req);
+ assert(req->credential);
assert(ret);
- r = read_credential(credential_name, (void**) &buffer, &size);
+ r = read_credential(req->credential, (void**) &buffer, &size);
if (IN_SET(r, -ENXIO, -ENOENT)) /* No credentials passed or this credential not defined? */
return -ENOKEY;
@@ -962,11 +970,7 @@ static int ask_password_credential(const char *credential_name, AskPasswordFlags
}
int ask_password_auto(
- const char *message,
- const char *icon,
- const char *id, /* id in "ask-password" protocol */
- const char *key_name, /* name in kernel keyring */
- const char *credential_name, /* name in $CREDENTIALS_DIRECTORY directory */
+ const AskPasswordRequest *req,
usec_t until,
AskPasswordFlags flags,
char ***ret) {
@@ -975,26 +979,26 @@ int ask_password_auto(
assert(ret);
- if (!FLAGS_SET(flags, ASK_PASSWORD_NO_CREDENTIAL) && credential_name) {
- r = ask_password_credential(credential_name, flags, ret);
+ if (!FLAGS_SET(flags, ASK_PASSWORD_NO_CREDENTIAL) && req && req->credential) {
+ r = ask_password_credential(req, flags, ret);
if (r != -ENOKEY)
return r;
}
if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) &&
- key_name &&
+ req && req->keyring &&
(FLAGS_SET(flags, ASK_PASSWORD_NO_TTY) || !isatty(STDIN_FILENO)) &&
FLAGS_SET(flags, ASK_PASSWORD_NO_AGENT)) {
- r = ask_password_keyring(key_name, flags, ret);
+ r = ask_password_keyring(req, flags, ret);
if (r != -ENOKEY)
return r;
}
if (!FLAGS_SET(flags, ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO))
- return ask_password_tty(-1, message, key_name, until, flags, NULL, ret);
+ return ask_password_tty(-EBADF, req, until, flags, NULL, ret);
if (!FLAGS_SET(flags, ASK_PASSWORD_NO_AGENT))
- return ask_password_agent(message, icon, id, key_name, until, flags, ret);
+ return ask_password_agent(req, until, flags, ret);
return -EUNATCH;
}
diff --git a/src/shared/ask-password-api.h b/src/shared/ask-password-api.h
index 7464e7f6de..e851d6d087 100644
--- a/src/shared/ask-password-api.h
+++ b/src/shared/ask-password-api.h
@@ -15,9 +15,19 @@ typedef enum AskPasswordFlags {
ASK_PASSWORD_CONSOLE_COLOR = 1 << 6, /* Use color if /dev/console points to a console that supports color */
ASK_PASSWORD_NO_CREDENTIAL = 1 << 7, /* never use $CREDENTIALS_DIRECTORY data */
ASK_PASSWORD_HIDE_EMOJI = 1 << 8, /* hide the lock and key emoji */
+ ASK_PASSWORD_HEADLESS = 1 << 9, /* headless mode: never query interactively */
} AskPasswordFlags;
-int ask_password_tty(int tty_fd, const char *message, const char *key_name, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
-int ask_password_plymouth(const char *message, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
-int ask_password_agent(const char *message, const char *icon, const char *id, const char *key_name, usec_t until, AskPasswordFlags flag, char ***ret);
-int ask_password_auto(const char *message, const char *icon, const char *id, const char *key_name, const char *credential_name, usec_t until, AskPasswordFlags flag, char ***ret);
+/* Encapsulates the mostly static fields of a password query */
+typedef struct AskPasswordRequest {
+ const char *message; /* The human readable password prompt when asking interactively */
+ const char *keyring; /* kernel keyring key name (key of "user" type) */
+ const char *icon; /* freedesktop icon spec name */
+ const char *id; /* some identifier used for this prompt for the "ask-password" protocol */
+ const char *credential; /* $CREDENTIALS_DIRECTORY credential name */
+} AskPasswordRequest;
+
+int ask_password_tty(int tty_fd, const AskPasswordRequest *req, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
+int ask_password_plymouth(const AskPasswordRequest *req, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
+int ask_password_agent(const AskPasswordRequest *req, usec_t until, AskPasswordFlags flag, char ***ret);
+int ask_password_auto(const AskPasswordRequest *req, usec_t until, AskPasswordFlags flag, char ***ret);
diff --git a/src/shared/cryptsetup-fido2.c b/src/shared/cryptsetup-fido2.c
index 2d59a630a6..5ab5cefe8f 100644
--- a/src/shared/cryptsetup-fido2.c
+++ b/src/shared/cryptsetup-fido2.c
@@ -24,11 +24,11 @@ int acquire_fido2_key(
const void *key_data,
size_t key_data_size,
usec_t until,
- bool headless,
Fido2EnrollFlags required,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
void **ret_decrypted_key,
- size_t *ret_decrypted_key_size,
- AskPasswordFlags ask_password_flags) {
+ size_t *ret_decrypted_key_size) {
_cleanup_(erase_and_freep) char *envpw = NULL;
_cleanup_strv_free_erase_ char **pins = NULL;
@@ -38,11 +38,11 @@ int acquire_fido2_key(
size_t salt_size;
int r;
- if ((required & (FIDO2ENROLL_PIN | FIDO2ENROLL_UP | FIDO2ENROLL_UV)) && headless)
+ if ((required & (FIDO2ENROLL_PIN | FIDO2ENROLL_UP | FIDO2ENROLL_UV)) && FLAGS_SET(askpw_flags, ASK_PASSWORD_HEADLESS))
return log_error_errno(SYNTHETIC_ERRNO(ENOPKG),
"Local verification is required to unlock this volume, but the 'headless' parameter was set.");
- ask_password_flags |= ASK_PASSWORD_PUSH_CACHE | ASK_PASSWORD_ACCEPT_CACHED;
+ askpw_flags |= ASK_PASSWORD_PUSH_CACHE | ASK_PASSWORD_ACCEPT_CACHED;
assert(cid);
assert(key_file || key_data);
@@ -115,15 +115,22 @@ int acquire_fido2_key(
device_exists = true; /* that a PIN is needed/wasn't correct means that we managed to
* talk to a device */
- if (headless)
+ if (FLAGS_SET(askpw_flags, ASK_PASSWORD_HEADLESS))
return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the '$PIN' environment variable.");
+ static const AskPasswordRequest req = {
+ .message = "Please enter security token PIN:",
+ .icon = "drive-harddisk",
+ .keyring = "fido2-pin",
+ .credential = "cryptsetup.fido2-pin",
+ };
+
pins = strv_free_erase(pins);
- r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", "cryptsetup.fido2-pin", until, ask_password_flags, &pins);
+ r = ask_password_auto(&req, until, askpw_flags, &pins);
if (r < 0)
return log_error_errno(r, "Failed to ask for user password: %m");
- ask_password_flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
+ askpw_flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
}
}
@@ -133,10 +140,10 @@ int acquire_fido2_key_auto(
const char *friendly_name,
const char *fido2_device,
usec_t until,
- bool headless,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
void **ret_decrypted_key,
- size_t *ret_decrypted_key_size,
- AskPasswordFlags ask_password_flags) {
+ size_t *ret_decrypted_key_size) {
_cleanup_free_ void *cid = NULL;
size_t cid_size = 0;
@@ -254,10 +261,11 @@ int acquire_fido2_key_auto(
/* key_file_offset= */ 0,
salt, salt_size,
until,
- headless,
required,
- ret_decrypted_key, ret_decrypted_key_size,
- ask_password_flags);
+ "cryptsetup.fido2-pin",
+ askpw_flags,
+ ret_decrypted_key,
+ ret_decrypted_key_size);
if (ret == 0)
break;
}
diff --git a/src/shared/cryptsetup-fido2.h b/src/shared/cryptsetup-fido2.h
index d96bb403ff..bd25566806 100644
--- a/src/shared/cryptsetup-fido2.h
+++ b/src/shared/cryptsetup-fido2.h
@@ -23,11 +23,11 @@ int acquire_fido2_key(
const void *key_data,
size_t key_data_size,
usec_t until,
- bool headless,
Fido2EnrollFlags required,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
void **ret_decrypted_key,
- size_t *ret_decrypted_key_size,
- AskPasswordFlags ask_password_flags);
+ size_t *ret_decrypted_key_size);
int acquire_fido2_key_auto(
struct crypt_device *cd,
@@ -35,10 +35,10 @@ int acquire_fido2_key_auto(
const char *friendly_name,
const char *fido2_device,
usec_t until,
- bool headless,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
void **ret_decrypted_key,
- size_t *ret_decrypted_key_size,
- AskPasswordFlags ask_password_flags);
+ size_t *ret_decrypted_key_size);
#else
@@ -55,11 +55,11 @@ static inline int acquire_fido2_key(
const void *key_data,
size_t key_data_size,
usec_t until,
- bool headless,
Fido2EnrollFlags required,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
void **ret_decrypted_key,
- size_t *ret_decrypted_key_size,
- AskPasswordFlags ask_password_flags) {
+ size_t *ret_decrypted_key_size) {
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"FIDO2 token support not available.");
@@ -71,10 +71,10 @@ static inline int acquire_fido2_key_auto(
const char *friendly_name,
const char *fido2_device,
usec_t until,
- bool headless,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
void **ret_decrypted_key,
- size_t *ret_decrypted_key_size,
- AskPasswordFlags ask_password_flags) {
+ size_t *ret_decrypted_key_size) {
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"FIDO2 token support not available.");
diff --git a/src/shared/cryptsetup-tpm2.c b/src/shared/cryptsetup-tpm2.c
index 297ef6fe4a..ee664a95a1 100644
--- a/src/shared/cryptsetup-tpm2.c
+++ b/src/shared/cryptsetup-tpm2.c
@@ -12,7 +12,11 @@
#include "sha256.h"
#include "tpm2-util.h"
-static int get_pin(usec_t until, AskPasswordFlags ask_password_flags, bool headless, char **ret_pin_str) {
+static int get_pin(
+ usec_t until,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
+ char **ret_pin_str) {
_cleanup_(erase_and_freep) char *pin_str = NULL;
_cleanup_strv_free_erase_ char **pin = NULL;
int r;
@@ -23,22 +27,21 @@ static int get_pin(usec_t until, AskPasswordFlags ask_password_flags, bool headl
if (r < 0)
return log_error_errno(r, "Failed to acquire PIN from environment: %m");
if (!r) {
- if (headless)
+ if (FLAGS_SET(askpw_flags, ASK_PASSWORD_HEADLESS))
return log_error_errno(
SYNTHETIC_ERRNO(ENOPKG),
"PIN querying disabled via 'headless' option. "
"Use the '$PIN' environment variable.");
+ AskPasswordRequest req = {
+ .message = "Please enter TPM2 PIN:",
+ .icon = "drive-harddisk",
+ .keyring = "tpm2-pin",
+ .credential = askpw_credential,
+ };
+
pin = strv_free_erase(pin);
- r = ask_password_auto(
- "Please enter TPM2 PIN:",
- "drive-harddisk",
- NULL,
- "tpm2-pin",
- "cryptsetup.tpm2-pin",
- until,
- ask_password_flags,
- &pin);
+ r = ask_password_auto(&req, until, askpw_flags, &pin);
if (r < 0)
return log_error_errno(r, "Failed to ask for user pin: %m");
assert(strv_length(pin) == 1);
@@ -73,8 +76,8 @@ int acquire_tpm2_key(
const struct iovec *pcrlock_nv,
TPM2Flags flags,
usec_t until,
- bool headless,
- AskPasswordFlags ask_password_flags,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
struct iovec *ret_decrypted_key) {
_cleanup_(json_variant_unrefp) JsonVariant *signature_json = NULL;
@@ -170,7 +173,7 @@ int acquire_tpm2_key(
if (i <= 0)
return -EACCES;
- r = get_pin(until, ask_password_flags, headless, &pin_str);
+ r = get_pin(until, askpw_credential, askpw_flags, &pin_str);
if (r < 0)
return r;
diff --git a/src/shared/cryptsetup-tpm2.h b/src/shared/cryptsetup-tpm2.h
index 0eaf9280ef..b9905f4f4b 100644
--- a/src/shared/cryptsetup-tpm2.h
+++ b/src/shared/cryptsetup-tpm2.h
@@ -31,8 +31,8 @@ int acquire_tpm2_key(
const struct iovec *pcrlock_nv,
TPM2Flags flags,
usec_t until,
- bool headless,
- AskPasswordFlags ask_password_flags,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
struct iovec *ret_decrypted_key);
int find_tpm2_auto_data(
@@ -75,8 +75,8 @@ static inline int acquire_tpm2_key(
const struct iovec *pcrlock_nv,
TPM2Flags flags,
usec_t until,
- bool headless,
- AskPasswordFlags ask_password_flags,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
struct iovec *ret_decrypted_key) {
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index d7c705184a..216c036a31 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -2989,9 +2989,16 @@ int dissected_image_decrypt_interactively(
return log_error_errno(SYNTHETIC_ERRNO(EKEYREJECTED),
"Too many retries.");
- z = strv_free(z);
+ z = strv_free_erase(z);
- r = ask_password_auto("Please enter image passphrase:", NULL, "dissect", "dissect", "dissect.passphrase", USEC_INFINITY, 0, &z);
+ static const AskPasswordRequest req = {
+ .message = "Please enter image passphrase:",
+ .id = "dissect",
+ .keyring = "dissect",
+ .credential = "dissect.passphrase",
+ };
+
+ r = ask_password_auto(&req, USEC_INFINITY, /* flags= */ 0, &z);
if (r < 0)
return log_error_errno(r, "Failed to query for passphrase: %m");
diff --git a/src/shared/libfido2-util.c b/src/shared/libfido2-util.c
index 43efa3529a..f5df579369 100644
--- a/src/shared/libfido2-util.c
+++ b/src/shared/libfido2-util.c
@@ -686,7 +686,8 @@ int fido2_generate_hmac_hash(
const char *user_name,
const char *user_display_name,
const char *user_icon,
- const char *askpw_icon_name,
+ const char *askpw_icon,
+ const char *askpw_credential,
Fido2EnrollFlags lock_with,
int cred_alg,
void **ret_cid, size_t *ret_cid_size,
@@ -838,8 +839,14 @@ int fido2_generate_hmac_hash(
for (;;) {
_cleanup_strv_free_erase_ char **pin = NULL;
+ AskPasswordRequest req = {
+ .message = "Please enter security token PIN:",
+ .icon = askpw_icon,
+ .keyring = "fido2-pin",
+ .credential = askpw_credential,
+ };
- r = ask_password_auto("Please enter security token PIN:", askpw_icon_name, NULL, "fido2-pin", "fido2-pin", USEC_INFINITY, 0, &pin);
+ r = ask_password_auto(&req, USEC_INFINITY, /* flags= */ 0, &pin);
if (r < 0)
return log_error_errno(r, "Failed to acquire user PIN: %m");
diff --git a/src/shared/libfido2-util.h b/src/shared/libfido2-util.h
index 4cfc95f712..3520ab4ec3 100644
--- a/src/shared/libfido2-util.h
+++ b/src/shared/libfido2-util.h
@@ -109,7 +109,8 @@ int fido2_generate_hmac_hash(
const char *user_name,
const char *user_display_name,
const char *user_icon,
- const char *askpw_icon_name,
+ const char *askpw_icon,
+ const char *askpw_credential,
Fido2EnrollFlags lock_with,
int cred_alg,
void **ret_cid, size_t *ret_cid_size,
diff --git a/src/shared/pkcs11-util.c b/src/shared/pkcs11-util.c
index 832d8af7e4..c330d9b6e0 100644
--- a/src/shared/pkcs11-util.c
+++ b/src/shared/pkcs11-util.c
@@ -291,12 +291,11 @@ int pkcs11_token_login(
CK_SLOT_ID slotid,
const CK_TOKEN_INFO *token_info,
const char *friendly_name,
- const char *icon_name,
- const char *key_name,
- const char *credential_name,
+ const char *askpw_icon,
+ const char *askpw_keyring,
+ const char *askpw_credential,
usec_t until,
- AskPasswordFlags ask_password_flags,
- bool headless,
+ AskPasswordFlags askpw_flags,
char **ret_used_pin) {
_cleanup_free_ char *token_uri_string = NULL, *token_uri_escaped = NULL, *id = NULL, *token_label = NULL;
@@ -351,7 +350,7 @@ int pkcs11_token_login(
if (!passwords)
return log_oom();
- } else if (headless)
+ } else if (FLAGS_SET(askpw_flags, ASK_PASSWORD_HEADLESS))
return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the 'PIN' environment variable.");
else {
_cleanup_free_ char *text = NULL;
@@ -375,8 +374,16 @@ int pkcs11_token_login(
if (r < 0)
return log_oom();
+ AskPasswordRequest req = {
+ .message = text,
+ .icon = askpw_icon,
+ .id = id,
+ .keyring = askpw_keyring,
+ .credential = askpw_credential,
+ };
+
/* We never cache PINs, simply because it's fatal if we use wrong PINs, since usually there are only 3 tries */
- r = ask_password_auto(text, icon_name, id, key_name, credential_name, until, ask_password_flags, &passwords);
+ r = ask_password_auto(&req, until, askpw_flags, &passwords);
if (r < 0)
return log_error_errno(r, "Failed to query PIN for security token '%s': %m", token_label);
}
@@ -1643,9 +1650,8 @@ int pkcs11_find_token(
struct pkcs11_acquire_public_key_callback_data {
char *pin_used;
EVP_PKEY *pkey;
- const char *askpw_friendly_name, *askpw_icon_name;
+ const char *askpw_friendly_name, *askpw_icon, *askpw_credential;
AskPasswordFlags askpw_flags;
- bool headless;
};
static void pkcs11_acquire_public_key_callback_data_release(struct pkcs11_acquire_public_key_callback_data *data) {
@@ -1690,12 +1696,11 @@ static int pkcs11_acquire_public_key_callback(
slot_id,
token_info,
data->askpw_friendly_name,
- data->askpw_icon_name,
- "pkcs11-pin",
+ data->askpw_icon,
"pkcs11-pin",
+ data->askpw_credential,
UINT64_MAX,
data->askpw_flags,
- data->headless,
&pin_used);
if (r < 0)
return r;
@@ -1821,13 +1826,17 @@ success:
int pkcs11_acquire_public_key(
const char *uri,
const char *askpw_friendly_name,
- const char *askpw_icon_name,
+ const char *askpw_icon,
+ const char *askpw_credential,
+ AskPasswordFlags askpw_flags,
EVP_PKEY **ret_pkey,
char **ret_pin_used) {
_cleanup_(pkcs11_acquire_public_key_callback_data_release) struct pkcs11_acquire_public_key_callback_data data = {
.askpw_friendly_name = askpw_friendly_name,
- .askpw_icon_name = askpw_icon_name,
+ .askpw_icon = askpw_icon,
+ .askpw_credential = askpw_credential,
+ .askpw_flags = askpw_flags,
};
int r;
@@ -2032,10 +2041,9 @@ int pkcs11_crypt_device_callback(
data->friendly_name,
"drive-harddisk",
"pkcs11-pin",
- "cryptsetup.pkcs11-pin",
+ data->askpw_credential,
data->until,
data->askpw_flags,
- data->headless,
NULL);
if (r < 0)
return r;
diff --git a/src/shared/pkcs11-util.h b/src/shared/pkcs11-util.h
index 838f90b6c1..6927a37113 100644
--- a/src/shared/pkcs11-util.h
+++ b/src/shared/pkcs11-util.h
@@ -53,7 +53,7 @@ char *pkcs11_token_manufacturer_id(const CK_TOKEN_INFO *token_info);
char *pkcs11_token_model(const CK_TOKEN_INFO *token_info);
int pkcs11_token_login_by_pin(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, const CK_TOKEN_INFO *token_info, const char *token_label, const void *pin, size_t pin_size);
-int pkcs11_token_login(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, CK_SLOT_ID slotid, const CK_TOKEN_INFO *token_info, const char *friendly_name, const char *icon_name, const char *key_name, const char *credential_name, usec_t until, AskPasswordFlags ask_password_flags, bool headless, char **ret_used_pin);
+int pkcs11_token_login(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, CK_SLOT_ID slotid, const CK_TOKEN_INFO *token_info, const char *friendly_name, const char *icon_name, const char *key_name, const char *credential_name, usec_t until, AskPasswordFlags ask_password_flags, char **ret_used_pin);
int pkcs11_token_find_related_object(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE prototype, CK_OBJECT_CLASS class, CK_OBJECT_HANDLE *ret_object);
int pkcs11_token_find_x509_certificate(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, P11KitUri *search_uri, CK_OBJECT_HANDLE *ret_object);
@@ -71,7 +71,7 @@ typedef int (*pkcs11_find_token_callback_t)(CK_FUNCTION_LIST *m, CK_SESSION_HAND
int pkcs11_find_token(const char *pkcs11_uri, pkcs11_find_token_callback_t callback, void *userdata);
#if HAVE_OPENSSL
-int pkcs11_acquire_public_key(const char *uri, const char *askpw_friendly_name, const char *askpw_icon_name, EVP_PKEY **ret_pkey, char **ret_pin_used);
+int pkcs11_acquire_public_key(const char *uri, const char *askpw_friendly_name, const char *askpw_icon, const char *askpw_credential, AskPasswordFlags askpw_flags, EVP_PKEY **ret_pkey, char **ret_pin_used);
#endif
typedef struct {
@@ -82,7 +82,7 @@ typedef struct {
void *decrypted_key;
size_t decrypted_key_size;
bool free_encrypted_key;
- bool headless;
+ const char *askpw_credential;
AskPasswordFlags askpw_flags;
} pkcs11_crypt_device_callback_data;
@@ -110,7 +110,7 @@ static inline int dlopen_p11kit(void) {
typedef struct {
const char *friendly_name;
usec_t until;
- bool headless;
+ const char *askpw_credential;
AskPasswordFlags askpw_flags;
} systemd_pkcs11_plugin_params;
diff --git a/src/test/test-ask-password-api.c b/src/test/test-ask-password-api.c
index b24159e2aa..8fee07330d 100644
--- a/src/test/test-ask-password-api.c
+++ b/src/test/test-ask-password-api.c
@@ -5,10 +5,15 @@
#include "tests.h"
TEST(ask_password) {
- int r;
_cleanup_strv_free_ char **ret = NULL;
+ int r;
- r = ask_password_tty(-1, "hello?", "da key", 0, ASK_PASSWORD_CONSOLE_COLOR, NULL, &ret);
+ static const AskPasswordRequest req = {
+ .message = "hello?",
+ .keyring = "da key",
+ };
+
+ r = ask_password_tty(-EBADF, &req, /* until= */ 0, /* flags= */ ASK_PASSWORD_CONSOLE_COLOR, /* flag_file= */ NULL, &ret);
if (r == -ECANCELED)
assert_se(ret == NULL);
else {
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 3a30bfe042..df979be5cd 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -157,7 +157,11 @@ static int agent_ask_password_tty(
log_info("Starting password query on %s.", con);
}
- r = ask_password_tty(tty_fd, message, NULL, until, flags, flag_file, ret);
+ AskPasswordRequest req = {
+ .message = message,
+ };
+
+ r = ask_password_tty(tty_fd, &req, until, flags, flag_file, ret);
if (arg_console) {
tty_fd = safe_close(tty_fd);
@@ -245,9 +249,13 @@ static int process_one_password_file(const char *filename) {
SET_FLAG(flags, ASK_PASSWORD_ECHO, echo);
SET_FLAG(flags, ASK_PASSWORD_SILENT, silent);
- if (arg_plymouth)
- r = ask_password_plymouth(message, not_after, flags, filename, &passwords);
- else
+ if (arg_plymouth) {
+ AskPasswordRequest req = {
+ .message = message,
+ };
+
+ r = ask_password_plymouth(&req, not_after, flags, filename, &passwords);
+ } else
r = agent_ask_password_tty(message, not_after, flags, filename, &passwords);
if (r < 0) {
/* If the query went away, that's OK */