mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
fido2: hook up with plymouth for notifications
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:
@@ -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