commit bfb722bbe5a503095cc7e860f282b142f5aa75f1 Author: Jan Rybar Date: Fri Mar 15 16:07:53 2019 +0000 pkttyagent: PolkitAgentTextListener leaves echo tty disabled if SIGINT/SIGTERM If no password is typed into terminal during authentication raised by PolkitAgentTextListener, pkttyagent sends kill (it receives from systemctl/hostnamectl e.g.) without chance to restore echoing back on. This cannot be done in on_request() since it's run in a thread without guarantee the signal is distributed there. diff --git a/src/programs/pkttyagent.c b/src/programs/pkttyagent.c index 3f324b8..3c8d502 100644 --- a/src/programs/pkttyagent.c +++ b/src/programs/pkttyagent.c @@ -25,11 +25,44 @@ #include #include +#include +#include #include #include #define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE #include + +static volatile sig_atomic_t tty_flags_saved; +struct termios ts; +FILE *tty = NULL; +struct sigaction savesigterm, savesigint, savesigtstp; + + +static void tty_handler(int signal) +{ + switch (signal) + { + case SIGTERM: + sigaction (SIGTERM, &savesigterm, NULL); + break; + case SIGINT: + sigaction (SIGINT, &savesigint, NULL); + break; + case SIGTSTP: + sigaction (SIGTSTP, &savesigtstp, NULL); + break; + } + + if (tty_flags_saved) + { + tcsetattr (fileno (tty), TCSAFLUSH, &ts); + } + + kill(getpid(), signal); +} + + int main (int argc, char *argv[]) { @@ -74,6 +107,8 @@ main (int argc, char *argv[]) GMainLoop *loop = NULL; guint ret = 126; GVariantBuilder builder; + struct sigaction sa; + const char *tty_name = NULL; /* Disable remote file access from GIO. */ setenv ("GIO_USE_VFS", "local", 1); @@ -212,6 +247,27 @@ main (int argc, char *argv[]) } } +/* Bash leaves tty echo disabled if SIGINT/SIGTERM comes to polkitagenttextlistener.c::on_request(), + but due to threading the handlers cannot take care of the signal there. + Though if controlling terminal cannot be found, the world won't stop spinning. +*/ + tty_name = ctermid(NULL); + if (tty_name != NULL) + { + tty = fopen(tty_name, "r+"); + } + + if (tty != NULL && !tcgetattr (fileno (tty), &ts)) + { + tty_flags_saved = TRUE; + } + + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = &tty_handler; + sigaction (SIGTERM, &sa, &savesigterm); + sigaction (SIGINT, &sa, &savesigint); + sigaction (SIGTSTP, &sa, &savesigtstp); + loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop);