From 184dab1c74db05d59d63bfaabedf0ef4e6bf61c9 Mon Sep 17 00:00:00 2001 From: Trumeet Date: Fri, 23 Dec 2022 22:33:19 -0800 Subject: Various improvements --- common.h | 3 +++ consent.c | 24 ++++++++++++------------ log.h | 10 ++++++++++ main.c | 34 ++++++++++++++++++++++++++++++---- sd.c | 16 +++++++--------- 5 files changed, 62 insertions(+), 25 deletions(-) diff --git a/common.h b/common.h index 0bf7c6d..d18efcd 100644 --- a/common.h +++ b/common.h @@ -6,6 +6,7 @@ #define SECDESK_COMMON_H #include +#include enum modes { /* Yes / No on action . */ @@ -24,12 +25,14 @@ struct auth_env { uid_t usr; pid_t pid; const char *prompt; + char exe[PATH_MAX + 1]; }; struct proc_env { int in; int out; int err; + int vt; }; extern struct proc_env p_env; diff --git a/consent.c b/consent.c index c2ab677..61710b0 100644 --- a/consent.c +++ b/consent.c @@ -14,21 +14,22 @@ int main_consent(int secure) { } else { printf("\033[r\033[H\033[J"); } - printf("Program %s (process %d: '%s'), is requesting your authorization.\n", - "/TODO", + printf("Program %s from user %d (process %d: '%s'), is asking for authorization.\n", + a_env.exe, + a_env.usr, a_env.pid, "todo"); switch (a_env.mode) { case mode_consent: { - printf("Do you consent '%s'? (Y / N) ", a_env.prompt); + printf("Consent '%s'? (Y / N) ", a_env.prompt); char buf[5]; if (read(STDIN_FILENO, buf, sizeof(buf) - 1) < 0) { int r = errno; LOGFV("read: %m", r); - printf("Cannot read your response: %m. Press any key to return.\n", - errno); - fgetc(stdin); if (secure) { + printf("Cannot read response: %m. Press any key to return.\n", + errno); + fgetc(stdin); printf("\033[r\033[H\033[J"); } return r; @@ -41,22 +42,21 @@ int main_consent(int secure) { break; } case mode_password: { - printf("Enter your password for '%s'. " + printf("Enter password for '%s'. " "The program will know your password.\n" "Password: ", a_env.prompt); char buf[10]; - if (read(STDIN_FILENO, buf, sizeof(buf) - 1) < 0) { + if (!fgets(buf, sizeof(buf) - 1, stdin)) { int r = errno; LOGFV("read: %m", r); - printf("Cannot read your response: %m. Press any key to return.\n", - errno); - fgetc(stdin); if (secure) { + printf("Cannot read your response: %m. Press any key to return.\n", + errno); + fgetc(stdin); printf("\033[r\033[H\033[J"); } return r; } - buf[sizeof(buf) - 1] = '\0'; dprintf(p_env.out, "%s", buf); break; } diff --git a/log.h b/log.h index 7d41fbc..a0c5beb 100644 --- a/log.h +++ b/log.h @@ -35,8 +35,18 @@ void g_log(enum log_level level, #define LOGIV(X, ...) g_log(log_info, __FUNCTION__, __LINE__, X, __VA_ARGS__) +#ifdef DEBUG_LOGS + #define LOGD(X) g_log(log_debug, __FUNCTION__, __LINE__, X) #define LOGDV(X, ...) g_log(log_debug, __FUNCTION__, __LINE__, X, __VA_ARGS__) +#else + +#define LOGD(X) (1) + +#define LOGDV(X, ...) (1) + +#endif + #endif /* LOG_H */ diff --git a/main.c b/main.c index a5f091b..0865bb4 100644 --- a/main.c +++ b/main.c @@ -4,14 +4,19 @@ #include #include #include +#include struct auth_env a_env; struct proc_env p_env = { .in = STDIN_FILENO, .out = STDOUT_FILENO, - .err = STDERR_FILENO + .err = STDERR_FILENO, + .vt = -1 }; +static void interrupt_int(int signum) { +} + int main(int argc, char **argv) { if (argc != 2 && argc != 3) { fprintf(stderr, "Usage: %s consent|password|auth [prompt]\n", @@ -38,11 +43,29 @@ int main(int argc, char **argv) { } } while (*(++ p)); } + a_env.pid = getppid(); + a_env.usr = getuid(); + + ssize_t len; + snprintf(a_env.exe, sizeof(a_env.exe) - 1, "/proc/%d/exe", a_env.pid); + if ((len = readlink(a_env.exe, a_env.exe, sizeof(a_env.exe) - 1)) == -1) { + LOGFV("Read caller binary: %m.", errno); + return errno; + } + a_env.exe[len] = '\0'; /* Because we need to frequently dup(2). */ setbuf(stdout, NULL); - a_env.pid = getppid(); signal(SIGHUP, SIG_IGN); + struct sigaction sa = { + .sa_flags = 0, + .sa_handler = interrupt_int + }; + sigemptyset(&sa.sa_mask); + /* Return EINTR on these signals to exit safely. */ + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + int r = sd_setup(); if (r == -1) { sd_cleanup(); @@ -50,10 +73,13 @@ int main(int argc, char **argv) { } if (r) { sd_cleanup(); - return main_consent(0); + r = main_consent(0); } else { + dprintf(p_env.err, "Complete authorization on TTY %d by running `chvt %d`.\n", + p_env.vt, + p_env.vt); r = main_consent(1); sd_cleanup(); - return r; } + return r; } diff --git a/sd.c b/sd.c index 88a4d9a..d1e6730 100644 --- a/sd.c +++ b/sd.c @@ -33,15 +33,14 @@ static const char *conspath[] = { static int fd_con = -1; static struct vt_stat vts; -static int vt_num = -1; static char vt_dev[PATH_MAX + 1]; static int vt_fd = -1; static pid_t chld = -1; static int vt_switch(int to) { if (to) { - IOCTL(fd_con, VT_ACTIVATE, vt_num) - IOCTL(fd_con, VT_WAITACTIVE, vt_num) + IOCTL(fd_con, VT_ACTIVATE, p_env.vt) + IOCTL(fd_con, VT_WAITACTIVE, p_env.vt) } else { IOCTL(fd_con, VT_ACTIVATE, vts.v_active) IOCTL(fd_con, VT_WAITACTIVE, vts.v_active) @@ -99,9 +98,8 @@ static int main_sak(void) { dprintf(fd, "\033[r\033[H\033[J" "Press SysRq + K to continue.\n"); /* Wait for signal. */ - while (1) { - pause(); - } + pause(); + return 0; } int sd_setup(void) { @@ -109,8 +107,8 @@ int sd_setup(void) { return 1; } IOCTL(fd_con, VT_GETSTATE, &vts) - IOCTL(fd_con, VT_OPENQRY, &vt_num) - snprintf(vt_dev, PATH_MAX, "/dev/tty%d", vt_num); + IOCTL(fd_con, VT_OPENQRY, &p_env.vt) + snprintf(vt_dev, PATH_MAX, "/dev/tty%d", p_env.vt); if (!(chld = fork())) { exit(main_sak()); @@ -194,7 +192,7 @@ void sd_cleanup(void) { if (vt_switch(0)) { LOGEV("Cannot return to the previous console: %m", errno); } - if (ioctl(fd_con, VT_DISALLOCATE, vt_num) < 0) { + if (ioctl(fd_con, VT_DISALLOCATE, p_env.vt) < 0) { LOGEV("Cannot deallocate console: %m", errno); } close(fd_con); -- cgit v1.2.3