Merge pull request #31400 from poettering/askpw-rework

Password Asking rework
This commit is contained in:
Luca Boccassi
2024-02-20 23:45:52 +00:00
committed by GitHub
30 changed files with 459 additions and 261 deletions
+45
View File
@@ -650,6 +650,51 @@
</refsect1>
<refsect1>
<title>Credentials</title>
<para><command>systemd-cryptenroll</command> supports the service credentials logic as implemented by
<varname>ImportCredential=</varname>/<varname>LoadCredential=</varname>/<varname>SetCredential=</varname>
(see <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
details). The following credentials are used when passed in:</para>
<variablelist class='system-credentials'>
<varlistentry>
<term><varname>cryptenroll.passphrase</varname></term>
<term><varname>cryptenroll.new-passphrase</varname></term>
<listitem><para>May contain the passphrase to unlock the volume with/to newly enroll.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>cryptenroll.tpm2-pin</varname></term>
<term><varname>cryptenroll.new-tpm2-pin</varname></term>
<listitem><para>May contain the TPM2 PIN to unlock the volume with/to newly enroll.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>cryptenroll.fido2-pin</varname></term>
<listitem><para>If a FIDO2 token is enrolled this may contain the PIN of the token.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>cryptenroll.pkcs11-pin</varname></term>
<listitem><para>If a PKCS#11 token is enrolled this may contain the PIN of the token.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Exit status</title>
+11 -11
View File
@@ -105,7 +105,7 @@
</refsect1>
<refsect1>
<title>System Credentials</title>
<title>Credentials</title>
<para><command>systemd-cryptsetup</command> supports the service credentials logic as implemented by
<varname>ImportCredential=</varname>/<varname>LoadCredential=</varname>/<varname>SetCredential=</varname>
@@ -122,14 +122,6 @@
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>cryptsetup.fido2-pin</varname></term>
<listitem><para>This credential specifies the FIDO2 token pin.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>cryptsetup.tpm2-pin</varname></term>
@@ -139,9 +131,9 @@
</varlistentry>
<varlistentry>
<term><varname>cryptsetup.luks2-pin</varname></term>
<term><varname>cryptsetup.fido2-pin</varname></term>
<listitem><para>This credential specifies the LUKS2 token pin.</para>
<listitem><para>This credential specifies the FIDO2 token pin.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
@@ -153,6 +145,14 @@
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>cryptsetup.luks2-pin</varname></term>
<listitem><para>This credential specifies the PIN requested by generic LUKS2 token modules.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</varlistentry>
</variablelist>
</refsect1>
+14
View File
@@ -353,6 +353,20 @@
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>cryptsetup.passphrase</varname></term>
<term><varname>cryptsetup.tpm2-pin</varname></term>
<term><varname>cryptsetup.fido2-pin</varname></term>
<term><varname>cryptsetup.pkcs11-pin</varname></term>
<term><varname>cryptsetup.luks2-pin</varname></term>
<listitem>
<para>Specifies the passphrase/PINs to use for unlock encrypted storage volumes. For details see
<citerefentry><refentrytitle>systemd-cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
+9 -1
View File
@@ -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");
+4 -3
View File
@@ -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,
+30 -12
View File
@@ -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");
+8 -1
View File
@@ -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;
+16 -15
View File
@@ -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");
+2 -2
View File
@@ -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;
+2 -2
View File
@@ -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) {
@@ -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;
+64 -37
View File
@@ -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,
&params,
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:",
+8 -2
View File
@@ -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)
+1
View File
@@ -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,
+8 -1
View File
@@ -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;
+37 -37
View File
@@ -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");
+7 -5
View File
@@ -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);
+56 -52
View File
@@ -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;
}
+14 -4
View File
@@ -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);
+22 -14
View File
@@ -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;
}
+12 -12
View File
@@ -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.");
+17 -14
View File
@@ -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;
+4 -4
View File
@@ -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),
+9 -2
View File
@@ -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");
+9 -2
View File
@@ -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");
+2 -1
View File
@@ -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,
+24 -16
View File
@@ -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;
+4 -4
View File
@@ -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;
+7 -2
View File
@@ -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 {
@@ -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 */