fido2: hook up with plymouth for notifications (#37089)
Show notifications for fido2 messages in plymouth, so that they show up in the initrd like the passphrase prompt already does.
This commit is contained in:
@@ -140,6 +140,8 @@ Credentials=
|
||||
tty.serial.hvc0.login.noauth=yes
|
||||
tty.console.agetty.autologin=root
|
||||
tty.console.login.noauth=yes
|
||||
tty.virtual.tty1.agetty.autologin=root
|
||||
tty.virtual.tty1.login.noauth=yes
|
||||
RuntimeBuildSources=yes
|
||||
RuntimeScratch=no
|
||||
CPUs=2
|
||||
|
||||
@@ -9,5 +9,5 @@ Environment=
|
||||
GIT_URL=https://salsa.debian.org/systemd-team/systemd.git
|
||||
GIT_SUBDIR=debian
|
||||
GIT_BRANCH=debian/master
|
||||
GIT_COMMIT=11efce9445f987f1e588719c182a93794eba2565
|
||||
GIT_COMMIT=91a4d114e0b5a01385477f8862caedc1056fa68b
|
||||
PKG_SUBDIR=debian
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "glyph-util.h"
|
||||
#include "log.h"
|
||||
#include "memory-util.h"
|
||||
#include "plymouth-util.h"
|
||||
#include "strv.h"
|
||||
#include "unistd.h"
|
||||
|
||||
@@ -362,6 +363,26 @@ static int fido2_is_cred_in_specific_token(
|
||||
}
|
||||
}
|
||||
|
||||
static void plymouth_start_interaction(const char *text, bool *ret_displayed) {
|
||||
assert(ret_displayed);
|
||||
|
||||
if (plymouth_send_msg(text, /* pause_spinner= */ true) < 0)
|
||||
return;
|
||||
|
||||
*ret_displayed = true;
|
||||
}
|
||||
|
||||
static void plymouth_end_interaction(bool *displayed) {
|
||||
assert(displayed);
|
||||
|
||||
if (!*displayed)
|
||||
return;
|
||||
|
||||
/* In theory 'm' should hide a message, but it doesn't work (long standing issue).
|
||||
* As a workaround, sending a single NUL byte hides the previous messages. */
|
||||
(void) plymouth_send_msg("", /* pause_spinner= */ false);
|
||||
}
|
||||
|
||||
static int fido2_use_hmac_hash_specific_token(
|
||||
const char *path,
|
||||
const char *rp_id,
|
||||
@@ -374,6 +395,7 @@ static int fido2_use_hmac_hash_specific_token(
|
||||
void **ret_hmac,
|
||||
size_t *ret_hmac_size) {
|
||||
|
||||
_cleanup_(plymouth_end_interaction) bool plymouth_displayed = false;
|
||||
_cleanup_(fido_assert_free_wrapper) fido_assert_t *a = NULL;
|
||||
_cleanup_(fido_dev_free_wrapper) fido_dev_t *d = NULL;
|
||||
_cleanup_(erase_and_freep) void *hmac_copy = NULL;
|
||||
@@ -445,10 +467,12 @@ static int fido2_use_hmac_hash_specific_token(
|
||||
enable_disable(FLAGS_SET(required, FIDO2ENROLL_UP)),
|
||||
sym_fido_strerr(r));
|
||||
|
||||
if (FLAGS_SET(required, FIDO2ENROLL_UP))
|
||||
if (FLAGS_SET(required, FIDO2ENROLL_UP)) {
|
||||
log_notice("%s%sPlease confirm presence on security token to unlock.",
|
||||
emoji_enabled() ? glyph(GLYPH_TOUCH) : "",
|
||||
emoji_enabled() ? " " : "");
|
||||
plymouth_start_interaction("Please confirm presence on security token to unlock.", &plymouth_displayed);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_uv && !FLAGS_SET(required, FIDO2ENROLL_UV_OMIT)) {
|
||||
@@ -459,10 +483,12 @@ static int fido2_use_hmac_hash_specific_token(
|
||||
enable_disable(FLAGS_SET(required, FIDO2ENROLL_UV)),
|
||||
sym_fido_strerr(r));
|
||||
|
||||
if (FLAGS_SET(required, FIDO2ENROLL_UV))
|
||||
if (FLAGS_SET(required, FIDO2ENROLL_UV)) {
|
||||
log_notice("%s%sPlease verify user on security token to unlock.",
|
||||
emoji_enabled() ? glyph(GLYPH_TOUCH) : "",
|
||||
emoji_enabled() ? " " : "");
|
||||
plymouth_start_interaction("Please verify user on security token to unlock.", &plymouth_displayed);
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
@@ -502,6 +528,7 @@ static int fido2_use_hmac_hash_specific_token(
|
||||
log_notice("%s%sPlease confirm presence on security to unlock.",
|
||||
emoji_enabled() ? glyph(GLYPH_TOUCH) : "",
|
||||
emoji_enabled() ? " " : "");
|
||||
plymouth_start_interaction("Please confirm presence on security token to unlock.", &plymouth_displayed);
|
||||
retry_with_up = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,3 +31,26 @@ int plymouth_send_raw(const void *raw, size_t size, int flags) {
|
||||
|
||||
return loop_write(fd, raw, size);
|
||||
}
|
||||
|
||||
int plymouth_send_msg(const char *text, bool pause_spinner) {
|
||||
_cleanup_free_ char *plymouth_message = NULL;
|
||||
int c, r;
|
||||
|
||||
assert(text);
|
||||
assert(strlen(text) < UCHAR_MAX);
|
||||
|
||||
c = asprintf(&plymouth_message,
|
||||
"M\x02%c%s%c"
|
||||
"%c%c", /* pause/resume spinner */
|
||||
(int) strlen(text) + 1, text, '\x00',
|
||||
pause_spinner ? 'A' : 'a', '\x00');
|
||||
if (c < 0)
|
||||
return log_oom();
|
||||
|
||||
r = plymouth_send_raw(plymouth_message, c, SOCK_NONBLOCK);
|
||||
if (r < 0)
|
||||
return log_full_errno(ERRNO_IS_NO_PLYMOUTH(r) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to communicate with plymouth, ignoring: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
int plymouth_connect(int flags);
|
||||
int plymouth_send_raw(const void *raw, size_t size, int flags);
|
||||
int plymouth_send_msg(const char *text, bool pause_spinner);
|
||||
|
||||
static inline bool ERRNO_IS_NO_PLYMOUTH(int r) {
|
||||
return IN_SET(abs(r), EAGAIN, ENOENT) || ERRNO_IS_DISCONNECT(r);
|
||||
|
||||
@@ -726,28 +726,6 @@ static int nvme_subsystem_report(NvmeSubsystem *subsystem, NvmePort *ipv4, NvmeP
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int plymouth_send_text(const char *text) {
|
||||
_cleanup_free_ char *plymouth_message = NULL;
|
||||
int c, r;
|
||||
|
||||
assert(text);
|
||||
|
||||
c = asprintf(&plymouth_message,
|
||||
"M\x02%c%s%c"
|
||||
"A%c", /* pause spinner */
|
||||
(int) strlen(text) + 1, text, '\x00',
|
||||
'\x00');
|
||||
if (c < 0)
|
||||
return log_oom();
|
||||
|
||||
r = plymouth_send_raw(plymouth_message, c, SOCK_NONBLOCK);
|
||||
if (r < 0)
|
||||
return log_full_errno(ERRNO_IS_NO_PLYMOUTH(r) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to communicate with plymouth, ignoring: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int plymouth_notify_port(NvmePort *port, struct local_address *a) {
|
||||
_cleanup_free_ char *m = NULL;
|
||||
|
||||
@@ -757,7 +735,7 @@ static int plymouth_notify_port(NvmePort *port, struct local_address *a) {
|
||||
if (asprintf(&m, "nvme connect-all -t tcp -a %s -s %" PRIu16, IN_ADDR_TO_STRING(a->family, &a->address), port->portnr) < 0)
|
||||
return log_oom();
|
||||
|
||||
return plymouth_send_text(m);
|
||||
return plymouth_send_msg(m, /* pause_spinner= */ true);
|
||||
}
|
||||
|
||||
static int nvme_port_report(NvmePort *port, bool *plymouth_done) {
|
||||
@@ -1077,7 +1055,7 @@ static int on_display_refresh(sd_event_source *s, uint64_t usec, void *userdata)
|
||||
(void) nvme_port_report(c->ipv6_port, &plymouth_done);
|
||||
|
||||
if (!plymouth_done)
|
||||
(void) plymouth_send_text("Network disconnected.");
|
||||
(void) plymouth_send_msg("Network disconnected.", /* pause_spinner= */ true);
|
||||
|
||||
NvmeSubsystem *i;
|
||||
HASHMAP_FOREACH(i, c->subsystems)
|
||||
@@ -1179,7 +1157,7 @@ static int run(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
if (!plymouth_done)
|
||||
(void) plymouth_send_text("Network disconnected.");
|
||||
(void) plymouth_send_msg("Network disconnected.", /* pause_spinner= */ true);
|
||||
|
||||
NvmeSubsystem *i;
|
||||
HASHMAP_FOREACH(i, context.subsystems) {
|
||||
|
||||
Reference in New Issue
Block a user