su: Read password from /dev/tty instead of stdin
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
c323a812a5
commit
56eb0c8130
27
apps/su.cpp
27
apps/su.cpp
@ -1,3 +1,4 @@
|
|||||||
|
#include <fcntl.h>
|
||||||
#include <os/ArgumentParser.h>
|
#include <os/ArgumentParser.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -7,10 +8,11 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
static struct termios orig;
|
static struct termios orig;
|
||||||
|
static int fd = -1;
|
||||||
|
|
||||||
void restore_terminal()
|
void restore_terminal()
|
||||||
{
|
{
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &orig);
|
tcsetattr(fd, TCSANOW, &orig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void signal_handler(int signo)
|
void signal_handler(int signo)
|
||||||
@ -21,21 +23,25 @@ void signal_handler(int signo)
|
|||||||
|
|
||||||
char* getpass()
|
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.
|
perror("Failed to open /dev/tty");
|
||||||
fprintf(stderr, "error: password must be read from a terminal!");
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
tcsetpgrp(STDIN_FILENO, getpgid(0));
|
fd = fileno(f);
|
||||||
|
|
||||||
|
tcsetpgrp(fd, getpgid(0));
|
||||||
|
|
||||||
fputs("Password: ", stdout);
|
fputs("Password: ", stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
if (tcgetattr(STDIN_FILENO, &orig) < 0)
|
if (tcgetattr(fd, &orig) < 0)
|
||||||
{
|
{
|
||||||
perror("tcgetattr");
|
perror("tcgetattr");
|
||||||
|
fclose(f);
|
||||||
|
fd = -1;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,18 +57,23 @@ char* getpass()
|
|||||||
|
|
||||||
struct termios tc = orig;
|
struct termios tc = orig;
|
||||||
tc.c_lflag &= ~ECHO;
|
tc.c_lflag &= ~ECHO;
|
||||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &tc) < 0)
|
if (tcsetattr(fd, TCSANOW, &tc) < 0)
|
||||||
{
|
{
|
||||||
perror("tcsetattr");
|
perror("tcsetattr");
|
||||||
|
fclose(f);
|
||||||
|
fd = -1;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char buf[BUFSIZ];
|
static char buf[BUFSIZ];
|
||||||
char* rc = fgets(buf, sizeof(buf), stdin);
|
char* rc = fgets(buf, sizeof(buf), f);
|
||||||
|
|
||||||
restore_terminal();
|
restore_terminal();
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
fd = -1;
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
perror("fgets");
|
perror("fgets");
|
||||||
|
Loading…
Reference in New Issue
Block a user