From: Werner Fink Date: Wed, 18 Nov 2015 11:28:30 +0000 (+0100) Subject: ask-password: ask for passphrases not only on the first console of /dev/console X-Git-Tag: v231.3~125 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=e3d4e3cc9bd2e9c9e421cdea775e35f529b46b3a ask-password: ask for passphrases not only on the first console of /dev/console but also on all other consoles. This does help on e.g. mainframes where often a serial console together with other consoles are used. Even rack based servers attachted to both a serial console as well as having a virtual console do sometimes miss a connected monitor. To be able to ask on all terminal devices of /dev/console the devices are collected. If more than one device are found, then on each of the terminals a inquiring task for passphrase is forked and do not return to the caller. Every task has its own session and its own controlling terminal. If one of the tasks does handle a password, the remaining tasks will be terminated. Also let contradictory options on the command of elogind-tty-ask-password-agent fail. Spwan for each device of the system console /dev/console a own process. Replace the system call wait() with with system call waitid(). Use SIGTERM instead of SIGHUP to get unresponsive childs down. Port the collect_consoles() function forward to a pulbic and strv based function "get_kernel_consoles()" in terminal-util.c and use this in tty-ask-password-agent.c. --- diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index cb75ad7c1..8f46c9267 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -50,6 +50,7 @@ #include "socket-util.h" #include "stat-util.h" #include "string-util.h" +#include "strv.h" #include "terminal-util.h" #include "time-util.h" #include "util.h" @@ -715,6 +716,64 @@ char *resolve_dev_console(char **active) { return tty; } +int get_kernel_consoles(char ***consoles) { + _cleanup_strv_free_ char **con = NULL; + _cleanup_free_ char *line = NULL; + const char *active; + int r; + + assert(consoles); + + r = read_one_line_file("/sys/class/tty/console/active", &line); + if (r < 0) + return r; + + active = line; + for (;;) { + _cleanup_free_ char *tty = NULL; + char *path; + + r = extract_first_word(&active, &tty, NULL, 0); + if (r < 0) + return r; + if (r == 0) + break; + + if (streq(tty, "tty0")) { + tty = mfree(tty); + r = read_one_line_file("/sys/class/tty/tty0/active", &tty); + if (r < 0) + return r; + } + + path = strappend("/dev/", tty); + if (!path) + return -ENOMEM; + + if (access(path, F_OK) < 0) { + log_debug_errno(errno, "Console device %s is not accessible, skipping: %m", path); + free(path); + continue; + } + + r = strv_consume(&con, path); + if (r < 0) + return r; + } + + if (strv_isempty(con)) { + log_debug("No devices found for system console"); + + r = strv_extend(&con, "/dev/console"); + if (r < 0) + return r; + } + + *consoles = con; + con = NULL; + return 0; +} + bool tty_is_vc_resolve(const char *tty) { _cleanup_free_ char *active = NULL;