SHA256
1
0
forked from pool/systemd
Dr. Werner Fink 2015-09-25 14:21:57 +00:00 committed by Git OBS Bridge
parent 6bda2878e3
commit a4039e218f
3 changed files with 102 additions and 65 deletions

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Fri Sep 25 14:20:41 UTC 2015 - werner@suse.de
- Fix patch tty-ask-password-agent-on-console.patch not to crash
away but enable it to ask on all devices of /dev/console
------------------------------------------------------------------- -------------------------------------------------------------------
Wed Sep 23 14:19:32 UTC 2015 - jengelh@inai.de Wed Sep 23 14:19:32 UTC 2015 - jengelh@inai.de

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Fri Sep 25 14:20:41 UTC 2015 - werner@suse.de
- Fix patch tty-ask-password-agent-on-console.patch not to crash
away but enable it to ask on all devices of /dev/console
------------------------------------------------------------------- -------------------------------------------------------------------
Wed Sep 23 14:19:32 UTC 2015 - jengelh@inai.de Wed Sep 23 14:19:32 UTC 2015 - jengelh@inai.de

View File

@ -1,11 +1,22 @@
--- From 633a5904c1c4e363a7147f47e2d9fdb1925f7b9f Mon Sep 17 00:00:00 2001
src/tty-ask-password-agent/tty-ask-password-agent.c | 171 +++++++++++++++++++- From: Werner Fink <werner@suse.de>
1 file changed, 166 insertions(+), 5 deletions(-) Date: Fri, 25 Sep 2015 14:28:58 +0200
Subject: [PATCH] Ask for passphrases not only on the first console of
/dev/console
Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c but also on all other consoles. This does help on e.g. mainframes
=================================================================== where often a serial console together with other consoles are
--- systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c used. Even rack based servers attachted to both a serial console
+++ systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c as well as having a virtual console do sometimes miss a connected
monitor.
---
src/tty-ask-password-agent/tty-ask-password-agent.c | 191 ++++++++++++++++++++-
1 file changed, 186 insertions(+), 5 deletions(-)
diff --git src/tty-ask-password-agent/tty-ask-password-agent.c src/tty-ask-password-agent/tty-ask-password-agent.c
index 82cbf95..928a5e8 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -31,6 +31,10 @@ @@ -31,6 +31,10 @@
#include <getopt.h> #include <getopt.h>
#include <sys/signalfd.h> #include <sys/signalfd.h>
@ -26,14 +37,13 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
static enum { static enum {
ACTION_LIST, ACTION_LIST,
@@ -53,6 +59,20 @@ static enum { @@ -53,6 +59,19 @@ static enum {
ACTION_WALL ACTION_WALL
} arg_action = ACTION_QUERY; } arg_action = ACTION_QUERY;
+struct console { +struct console {
+ char *tty;
+ pid_t pid; + pid_t pid;
+ int id; + char *tty;
+}; +};
+ +
+static volatile unsigned long *usemask; +static volatile unsigned long *usemask;
@ -47,18 +57,29 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
static bool arg_plymouth = false; static bool arg_plymouth = false;
static bool arg_console = false; static bool arg_console = false;
@@ -211,6 +231,60 @@ static int ask_password_plymouth( @@ -210,6 +229,69 @@ static int ask_password_plymouth(
return 0; return 0;
} }
+static void free_consoles(struct console *con, const unsigned int num) {
+ unsigned int n;
+ if (!con || !num)
+ return;
+ for (n = 0; n < num; n++)
+ free(con[n].tty);
+ free(con);
+}
+
+static const char *current_dev = "/dev/console"; +static const char *current_dev = "/dev/console";
+static struct console* collect_consoles(int * num) { +static struct console* collect_consoles(unsigned int * num) {
+ _cleanup_free_ char *active = NULL; + _cleanup_free_ char *active = NULL;
+ const char *word, *state; + const char *word, *state;
+ struct console *con = NULL; + struct console *con = NULL;
+ size_t con_len; + size_t con_len = 0, len;
+ size_t len; + int ret;
+ int ret, id = 0; +
+ assert(num);
+ assert(*num == 0);
+ +
+ ret = read_one_line_file("/sys/class/tty/console/active", &active); + ret = read_one_line_file("/sys/class/tty/console/active", &active);
+ if (ret < 0) + if (ret < 0)
@ -71,44 +92,42 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
+ word = tty; + word = tty;
+ len = strlen(tty); + len = strlen(tty);
+ } + }
+ con = greedy_realloc((void**)&con, &con_len, ++id, sizeof(struct console) + 5 + len + 1); + con = greedy_realloc((void**)&con, &con_len, 1+(*num), sizeof(struct console));
+ if (con == NULL) { + if (con == NULL) {
+ log_oom(); + log_oom();
+ return con; + return NULL;
+ } + }
+ con->tty = ((char*)con)+sizeof(struct console); + if (asprintf(&con[*num].tty, "/dev/%.*s", (int)len, word) < 0) {
+ sprintf(con->tty, "/dev/%.*s", (int)len, word); + free_consoles(con, *num);
+ con->id = id; + log_oom();
+ *num = 0;
+ return NULL;
+ }
+ con[*num].pid = 0;
+ (*num)++;
+ } + }
+ if (con == NULL) { + if (con == NULL) {
+ con = greedy_realloc((void**)&con, &con_len, 1, sizeof(struct console)); + con = greedy_realloc((void**)&con, &con_len, 1, sizeof(struct console));
+ if (con == NULL) { + if (con == NULL) {
+ log_oom(); + log_oom();
+ return con; + return NULL;
+ } + }
+ con->tty = (char*)current_dev; + con[0].tty = strdup(current_dev);
+ con->id = id = 1; + if (con[0].tty == NULL) {
+ free_consoles(con, 1);
+ log_oom();
+ return NULL;
+ }
+ con[0].pid = 0;
+ (*num)++;
+ } + }
+
+ if (num)
+ *num = id;
+ return con; + return con;
+} +}
+
+static void free_consoles(struct console *con, int num) {
+ int n;
+
+ if (!con)
+ return;
+ for (n = 0; n < num; n++)
+ free(&con[n]);
+ free(con);
+}
+ +
static int parse_password(const char *filename, char **wall) { static int parse_password(const char *filename, char **wall) {
_cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL; _cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL;
uint64_t not_after = 0; uint64_t not_after = 0;
@@ -311,7 +385,7 @@ static int parse_password(const char *filename, char **wall) { @@ -310,7 +392,7 @@ static int parse_password(const char *filename, char **wall) {
_cleanup_free_ char *password = NULL; _cleanup_free_ char *password = NULL;
if (arg_console) { if (arg_console) {
@ -117,11 +136,20 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
if (tty_fd < 0) if (tty_fd < 0)
return tty_fd; return tty_fd;
} }
@@ -615,8 +689,87 @@ static int parse_argv(int argc, char *argv[]) { @@ -614,8 +696,90 @@ static int parse_argv(int argc, char *argv[]) {
return 1; return 1;
} }
+static int wait_for_answer(void) +static unsigned int wfa_child(const struct console * con, const unsigned int id)
+{
+ setsid();
+ release_terminal();
+ *usemask |= 1 << id; /* shared memory area */
+ current_dev = con[id].tty;
+ return id;
+}
+
+static unsigned int wait_for_answer(void)
+{ +{
+ struct console *consoles; + struct console *consoles;
+ struct sigaction sig = { + struct sigaction sig = {
@ -130,7 +158,8 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
+ }; + };
+ struct sigaction oldsig; + struct sigaction oldsig;
+ sigset_t set, oldset; + sigset_t set, oldset;
+ int status = 0, num = 0, n, ret; + unsigned int num = 0, id;
+ int status = 0, ret;
+ pid_t job; + pid_t job;
+ +
+ consoles = collect_consoles(&num); + consoles = collect_consoles(&num);
@ -138,10 +167,8 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
+ log_error("Failed to query password: %m"); + log_error("Failed to query password: %m");
+ exit(EXIT_FAILURE); + exit(EXIT_FAILURE);
+ } + }
+ if (num == 1) { + if (num < 2)
+ n = 1; + return wfa_child(consoles, 0);
+ goto nofork;
+ }
+ +
+ assert_se(sigemptyset(&set) == 0); + assert_se(sigemptyset(&set) == 0);
+ assert_se(sigaddset(&set, SIGHUP) == 0); + assert_se(sigaddset(&set, SIGHUP) == 0);
@ -152,26 +179,21 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
+ sig.sa_handler = SIG_DFL; + sig.sa_handler = SIG_DFL;
+ assert_se(sigaction(SIGHUP, &sig, NULL) == 0); + assert_se(sigaction(SIGHUP, &sig, NULL) == 0);
+ +
+ for (n = 0; n < num; n++) { + for (id = 0; id < num; id++) {
+ consoles[n].pid = fork(); + consoles[id].pid = fork();
+ +
+ if (consoles[n].pid < 0) { + if (consoles[id].pid < 0) {
+ log_error("Failed to query password: %m"); + log_error("Failed to query password: %m");
+ exit(EXIT_FAILURE); + exit(EXIT_FAILURE);
+ } + }
+ +
+ if (consoles[n].pid == 0) { + if (consoles[id].pid == 0) {
+ if (prctl(PR_SET_PDEATHSIG, SIGHUP) < 0) + if (prctl(PR_SET_PDEATHSIG, SIGHUP) < 0)
+ _exit(EXIT_FAILURE); + _exit(EXIT_FAILURE);
+ zero(sig); + zero(sig);
+ assert_se(sigprocmask(SIG_UNBLOCK, &oldset, NULL) == 0); + assert_se(sigprocmask(SIG_UNBLOCK, &oldset, NULL) == 0);
+ assert_se(sigaction(SIGCHLD, &oldsig, NULL) == 0); + assert_se(sigaction(SIGCHLD, &oldsig, NULL) == 0);
+ nofork: + return wfa_child(consoles, id);
+ setsid();
+ release_terminal();
+ *usemask |= 1 << consoles[n].id;
+ current_dev = consoles[n].tty;
+ return consoles[n].id; /* child */
+ } + }
+ } + }
+ +
@ -182,16 +204,16 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
+ break; + break;
+ continue; + continue;
+ } + }
+ for (n = 0; n < num; n++) { + for (id = 0; id < num; id++) {
+ if (consoles[n].pid == job || kill(consoles[n].pid, 0) < 0) { + if (consoles[id].pid == job || kill(consoles[id].pid, 0) < 0) {
+ *usemask &= ~(1 << consoles[n].id); + *usemask &= ~(1 << id); /* shared memory area */
+ continue; + continue;
+ } + }
+ if (*usemask & (1 << consoles[n].id)) + if (*usemask & (1 << id)) /* shared memory area */
+ continue; + continue;
+ kill(consoles[n].pid, SIGHUP); + kill(consoles[id].pid, SIGHUP);
+ usleep(50000); + usleep(50000);
+ kill(consoles[n].pid, SIGKILL); + kill(consoles[id].pid, SIGKILL);
+ } + }
+ if (WIFEXITED(status) && ret == 0) + if (WIFEXITED(status) && ret == 0)
+ ret = WEXITSTATUS(status); + ret = WEXITSTATUS(status);
@ -206,7 +228,7 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
log_set_target(LOG_TARGET_AUTO); log_set_target(LOG_TARGET_AUTO);
log_parse_environment(); log_parse_environment();
@@ -628,11 +781,27 @@ int main(int argc, char *argv[]) { @@ -627,11 +791,27 @@ int main(int argc, char *argv[]) {
if (r <= 0) if (r <= 0)
goto finish; goto finish;
@ -225,8 +247,8 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
if (arg_console) { if (arg_console) {
- setsid(); - setsid();
- release_terminal(); - release_terminal();
+ if (!arg_plymouth && arg_action != ACTION_WALL && + if (!arg_plymouth &&
+ arg_action != ACTION_LIST) { + !IN_SET(arg_action, ACTION_WALL, ACTION_LIST)) {
+ id = wait_for_answer(); + id = wait_for_answer();
+ } else { + } else {
+ setsid(); + setsid();
@ -237,11 +259,14 @@ Index: systemd-221/src/tty-ask-password-agent/tty-ask-password-agent.c
if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL)) if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL))
r = watch_passwords(); r = watch_passwords();
else else
@@ -641,6 +810,7 @@ int main(int argc, char *argv[]) { @@ -640,6 +820,7 @@ int main(int argc, char *argv[]) {
if (r < 0) if (r < 0)
log_error_errno(r, "Error: %m"); log_error_errno(r, "Error: %m");
+ *usemask &= ~(1 << id); + *usemask &= ~(1 << id); /* shared memory area */
finish: finish:
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
} }
--
2.2.0