From 56eb0c813025b8363c3a53930573deac6fddfcdc Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 14 Oct 2023 20:47:56 +0200 Subject: [PATCH] su: Read password from /dev/tty instead of stdin --- apps/su.cpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/apps/su.cpp b/apps/su.cpp index 30458101..64353719 100644 --- a/apps/su.cpp +++ b/apps/su.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -7,10 +8,11 @@ #include static struct termios orig; +static int fd = -1; void restore_terminal() { - tcsetattr(STDIN_FILENO, TCSANOW, &orig); + tcsetattr(fd, TCSANOW, &orig); } void signal_handler(int signo) @@ -21,21 +23,25 @@ void signal_handler(int signo) char* getpass() { - if (!isatty(STDIN_FILENO)) + FILE* f = fopen("/dev/tty", "r"); + if (!f) { - // FIXME: Just read from /dev/tty (the controlling terminal). Problem: that doesn't exist yet. - fprintf(stderr, "error: password must be read from a terminal!"); + perror("Failed to open /dev/tty"); return nullptr; } - tcsetpgrp(STDIN_FILENO, getpgid(0)); + fd = fileno(f); + + tcsetpgrp(fd, getpgid(0)); fputs("Password: ", stdout); fflush(stdout); - if (tcgetattr(STDIN_FILENO, &orig) < 0) + if (tcgetattr(fd, &orig) < 0) { perror("tcgetattr"); + fclose(f); + fd = -1; return nullptr; } @@ -51,18 +57,23 @@ char* getpass() struct termios tc = orig; tc.c_lflag &= ~ECHO; - if (tcsetattr(STDIN_FILENO, TCSANOW, &tc) < 0) + if (tcsetattr(fd, TCSANOW, &tc) < 0) { perror("tcsetattr"); + fclose(f); + fd = -1; return nullptr; } static char buf[BUFSIZ]; - char* rc = fgets(buf, sizeof(buf), stdin); + char* rc = fgets(buf, sizeof(buf), f); restore_terminal(); putchar('\n'); + fclose(f); + fd = -1; + if (!rc) { perror("fgets");