ask-password: when querying for a password, try to read from credential store first

This adds generic support for the SetCredential=/LoadCredential= logic
to our password querying infrastructure: if a password is requested by a
program that has a credential store configured via
$CREDENTIALS_DIRECTORY we'll look in it for a password.

The "systemd-ask-password" tool is updated with an option to specify the
credential to look for.
This commit is contained in:
Lennart Poettering
2021-03-26 12:21:56 +01:00
parent f6ab6199a2
commit 8806bb4bc7
14 changed files with 93 additions and 37 deletions
+35 -6
View File
@@ -20,6 +20,7 @@
#include "alloc-util.h"
#include "ask-password-api.h"
#include "creds-util.h"
#include "def.h"
#include "fd-util.h"
#include "fileio.h"
@@ -971,11 +972,33 @@ finish:
return r;
}
static int ask_password_credential(const char *credential_name, AskPasswordFlags flags, char ***ret) {
_cleanup_(erase_and_freep) char *buffer = NULL;
size_t size;
char **l;
int r;
assert(credential_name);
assert(ret);
r = read_credential(credential_name, (void**) &buffer, &size);
if (IN_SET(r, -ENXIO, -ENOENT)) /* No credentials passed or this credential not defined? */
return -ENOKEY;
l = strv_parse_nulstr(buffer, size);
if (!l)
return -ENOMEM;
*ret = l;
return 0;
}
int ask_password_auto(
const char *message,
const char *icon,
const char *id,
const char *keyname,
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 */
usec_t until,
AskPasswordFlags flags,
char ***ret) {
@@ -984,20 +1007,26 @@ int ask_password_auto(
assert(ret);
if (!(flags & ASK_PASSWORD_NO_CREDENTIAL) && credential_name) {
r = ask_password_credential(credential_name, flags, ret);
if (r != -ENOKEY)
return r;
}
if ((flags & ASK_PASSWORD_ACCEPT_CACHED) &&
keyname &&
key_name &&
((flags & ASK_PASSWORD_NO_TTY) || !isatty(STDIN_FILENO)) &&
(flags & ASK_PASSWORD_NO_AGENT)) {
r = ask_password_keyring(keyname, flags, ret);
r = ask_password_keyring(key_name, flags, ret);
if (r != -ENOKEY)
return r;
}
if (!(flags & ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO))
return ask_password_tty(-1, message, keyname, until, flags, NULL, ret);
return ask_password_tty(-1, message, key_name, until, flags, NULL, ret);
if (!(flags & ASK_PASSWORD_NO_AGENT))
return ask_password_agent(message, icon, id, keyname, until, flags, ret);
return ask_password_agent(message, icon, id, key_name, until, flags, ret);
return -EUNATCH;
}
+8 -7
View File
@@ -6,16 +6,17 @@
#include "time-util.h"
typedef enum AskPasswordFlags {
ASK_PASSWORD_ACCEPT_CACHED = 1 << 0,
ASK_PASSWORD_PUSH_CACHE = 1 << 1,
ASK_PASSWORD_ACCEPT_CACHED = 1 << 0, /* read from kernel keyring */
ASK_PASSWORD_PUSH_CACHE = 1 << 1, /* write to kernel keyring after getting password from elsewhere */
ASK_PASSWORD_ECHO = 1 << 2, /* show the password literally while reading, instead of "*" */
ASK_PASSWORD_SILENT = 1 << 3, /* do no show any password at all while reading */
ASK_PASSWORD_NO_TTY = 1 << 4,
ASK_PASSWORD_NO_AGENT = 1 << 5,
ASK_PASSWORD_NO_TTY = 1 << 4, /* never ask for password on tty */
ASK_PASSWORD_NO_AGENT = 1 << 5, /* never ask for password via agent */
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 */
} AskPasswordFlags;
int ask_password_tty(int tty_fd, const char *message, const char *keyname, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
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 *keyname, usec_t until, AskPasswordFlags flag, char ***ret);
int ask_password_auto(const char *message, const char *icon, const char *id, const char *keyname, usec_t until, AskPasswordFlags flag, 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);
+1 -1
View File
@@ -1993,7 +1993,7 @@ int dissected_image_decrypt_interactively(
z = strv_free(z);
r = ask_password_auto("Please enter image passphrase:", NULL, "dissect", "dissect", USEC_INFINITY, 0, &z);
r = ask_password_auto("Please enter image passphrase:", NULL, "dissect", "dissect", "dissect.passphrase", USEC_INFINITY, 0, &z);
if (r < 0)
return log_error_errno(r, "Failed to query for passphrase: %m");
+1 -1
View File
@@ -566,7 +566,7 @@ int fido2_generate_hmac_hash(
if (!has_client_pin)
log_warning("Weird, device asked for client PIN, but does not advertise it as feature. Ignoring.");
r = ask_password_auto("Please enter security token PIN:", askpw_icon_name, NULL, "fido2-pin", USEC_INFINITY, 0, &pin);
r = ask_password_auto("Please enter security token PIN:", askpw_icon_name, NULL, "fido2-pin", "fido2-pin", USEC_INFINITY, 0, &pin);
if (r < 0)
return log_error_errno(r, "Failed to acquire user PIN: %m");
+4 -3
View File
@@ -181,7 +181,8 @@ int pkcs11_token_login(
const CK_TOKEN_INFO *token_info,
const char *friendly_name,
const char *icon_name,
const char *keyname,
const char *key_name,
const char *credential_name,
usec_t until,
char **ret_used_pin) {
@@ -269,7 +270,7 @@ int pkcs11_token_login(
return log_oom();
/* 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, keyname, until, 0, &passwords);
r = ask_password_auto(text, icon_name, id, key_name, credential_name, until, 0, &passwords);
if (r < 0)
return log_error_errno(r, "Failed to query PIN for security token '%s': %m", token_label);
}
@@ -959,7 +960,7 @@ static int pkcs11_acquire_certificate_callback(
/* Called for every token matching our URI */
r = pkcs11_token_login(m, session, slot_id, token_info, data->askpw_friendly_name, data->askpw_icon_name, "pkcs11-pin", UINT64_MAX, &pin_used);
r = pkcs11_token_login(m, session, slot_id, token_info, data->askpw_friendly_name, data->askpw_icon_name, "pkcs11-pin", "pkcs11-pin", UINT64_MAX, &pin_used);
if (r < 0)
return r;
+1 -1
View File
@@ -30,7 +30,7 @@ char *pkcs11_token_label(const CK_TOKEN_INFO *token_info);
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(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 *keyname, usec_t until, 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, char **ret_used_pin);
int pkcs11_token_find_x509_certificate(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, P11KitUri *search_uri, CK_OBJECT_HANDLE *ret_object);
#if HAVE_OPENSSL