|
|
ed9154 |
diff -up ./src/tgetpass.c.bla ./src/tgetpass.c
|
|
|
ed9154 |
--- ./src/tgetpass.c.bla 2018-08-18 16:10:15.000000000 +0200
|
|
|
ed9154 |
+++ ./src/tgetpass.c 2020-02-05 17:15:16.216904891 +0100
|
|
|
ed9154 |
@@ -44,11 +44,18 @@
|
|
|
ed9154 |
#include "sudo.h"
|
|
|
ed9154 |
#include "sudo_plugin.h"
|
|
|
ed9154 |
|
|
|
ed9154 |
+enum tgetpass_errval {
|
|
|
ed9154 |
+ TGP_ERRVAL_NOERROR,
|
|
|
ed9154 |
+ TGP_ERRVAL_TIMEOUT,
|
|
|
ed9154 |
+ TGP_ERRVAL_NOPASSWORD,
|
|
|
ed9154 |
+ TGP_ERRVAL_READERROR
|
|
|
ed9154 |
+};
|
|
|
ed9154 |
+
|
|
|
ed9154 |
static volatile sig_atomic_t signo[NSIG];
|
|
|
ed9154 |
|
|
|
ed9154 |
static bool tty_present(void);
|
|
|
ed9154 |
static void tgetpass_handler(int);
|
|
|
ed9154 |
-static char *getln(int, char *, size_t, int);
|
|
|
ed9154 |
+static char *getln(int, char *, size_t, int, enum tgetpass_errval *);
|
|
|
ed9154 |
static char *sudo_askpass(const char *, const char *);
|
|
|
ed9154 |
|
|
|
ed9154 |
static int
|
|
|
ed9154 |
@@ -77,6 +84,27 @@ suspend(int signo, struct sudo_conv_call
|
|
|
ed9154 |
debug_return_int(ret);
|
|
|
ed9154 |
}
|
|
|
ed9154 |
|
|
|
ed9154 |
+static void
|
|
|
ed9154 |
+tgetpass_display_error(enum tgetpass_errval errval)
|
|
|
ed9154 |
+{
|
|
|
ed9154 |
+ debug_decl(tgetpass_display_error, SUDO_DEBUG_CONV)
|
|
|
ed9154 |
+
|
|
|
ed9154 |
+ switch (errval) {
|
|
|
ed9154 |
+ case TGP_ERRVAL_NOERROR:
|
|
|
ed9154 |
+ break;
|
|
|
ed9154 |
+ case TGP_ERRVAL_TIMEOUT:
|
|
|
ed9154 |
+ sudo_warnx(U_("timed out reading password"));
|
|
|
ed9154 |
+ break;
|
|
|
ed9154 |
+ case TGP_ERRVAL_NOPASSWORD:
|
|
|
ed9154 |
+ sudo_warnx(U_("no password was provided"));
|
|
|
ed9154 |
+ break;
|
|
|
ed9154 |
+ case TGP_ERRVAL_READERROR:
|
|
|
ed9154 |
+ sudo_warn(U_("unable to read password"));
|
|
|
ed9154 |
+ break;
|
|
|
ed9154 |
+ }
|
|
|
ed9154 |
+ debug_return;
|
|
|
ed9154 |
+}
|
|
|
ed9154 |
+
|
|
|
ed9154 |
/*
|
|
|
ed9154 |
* Like getpass(3) but with timeout and echo flags.
|
|
|
ed9154 |
*/
|
|
|
ed9154 |
@@ -90,6 +118,7 @@ tgetpass(const char *prompt, int timeout
|
|
|
ed9154 |
static const char *askpass;
|
|
|
ed9154 |
static char buf[SUDO_CONV_REPL_MAX + 1];
|
|
|
ed9154 |
int i, input, output, save_errno, neednl = 0, need_restart;
|
|
|
ed9154 |
+ enum tgetpass_errval errval;
|
|
|
ed9154 |
debug_decl(tgetpass, SUDO_DEBUG_CONV)
|
|
|
ed9154 |
|
|
|
ed9154 |
(void) fflush(stdout);
|
|
|
ed9154 |
@@ -175,7 +204,7 @@ restart:
|
|
|
ed9154 |
|
|
|
ed9154 |
if (timeout > 0)
|
|
|
ed9154 |
alarm(timeout);
|
|
|
ed9154 |
- pass = getln(input, buf, sizeof(buf), ISSET(flags, TGP_MASK));
|
|
|
ed9154 |
+ pass = getln(input, buf, sizeof(buf), ISSET(flags, TGP_MASK), &errval);
|
|
|
ed9154 |
alarm(0);
|
|
|
ed9154 |
save_errno = errno;
|
|
|
ed9154 |
|
|
|
ed9154 |
@@ -183,6 +212,7 @@ restart:
|
|
|
ed9154 |
if (write(output, "\n", 1) == -1)
|
|
|
ed9154 |
goto restore;
|
|
|
ed9154 |
}
|
|
|
ed9154 |
+ tgetpass_display_error(errval);
|
|
|
ed9154 |
|
|
|
ed9154 |
restore:
|
|
|
ed9154 |
/* Restore old signal handlers. */
|
|
|
ed9154 |
@@ -210,6 +240,8 @@ restore:
|
|
|
ed9154 |
for (i = 0; i < NSIG; i++) {
|
|
|
ed9154 |
if (signo[i]) {
|
|
|
ed9154 |
switch (i) {
|
|
|
ed9154 |
+ case SIGALRM:
|
|
|
ed9154 |
+ break;
|
|
|
ed9154 |
case SIGTSTP:
|
|
|
ed9154 |
case SIGTTIN:
|
|
|
ed9154 |
case SIGTTOU:
|
|
|
ed9154 |
@@ -239,6 +271,7 @@ sudo_askpass(const char *askpass, const
|
|
|
ed9154 |
{
|
|
|
ed9154 |
static char buf[SUDO_CONV_REPL_MAX + 1], *pass;
|
|
|
ed9154 |
struct sigaction sa, savechld;
|
|
|
ed9154 |
+ enum tgetpass_errval errval;
|
|
|
ed9154 |
int pfd[2], status;
|
|
|
ed9154 |
pid_t child;
|
|
|
ed9154 |
debug_decl(sudo_askpass, SUDO_DEBUG_CONV)
|
|
|
ed9154 |
@@ -281,9 +314,11 @@ sudo_askpass(const char *askpass, const
|
|
|
ed9154 |
|
|
|
ed9154 |
/* Get response from child (askpass). */
|
|
|
ed9154 |
(void) close(pfd[1]);
|
|
|
ed9154 |
- pass = getln(pfd[0], buf, sizeof(buf), 0);
|
|
|
ed9154 |
+ pass = getln(pfd[0], buf, sizeof(buf), 0, &errval);
|
|
|
ed9154 |
(void) close(pfd[0]);
|
|
|
ed9154 |
|
|
|
ed9154 |
+ tgetpass_display_error(errval);
|
|
|
ed9154 |
+
|
|
|
ed9154 |
/* Wait for child to exit. */
|
|
|
ed9154 |
for (;;) {
|
|
|
ed9154 |
pid_t rv = waitpid(child, &status, 0);
|
|
|
ed9154 |
@@ -305,7 +340,8 @@ sudo_askpass(const char *askpass, const
|
|
|
ed9154 |
extern int sudo_term_erase, sudo_term_kill;
|
|
|
ed9154 |
|
|
|
ed9154 |
static char *
|
|
|
ed9154 |
-getln(int fd, char *buf, size_t bufsiz, int feedback)
|
|
|
ed9154 |
+getln(int fd, char *buf, size_t bufsiz, int feedback,
|
|
|
ed9154 |
+ enum tgetpass_errval *errval)
|
|
|
ed9154 |
{
|
|
|
ed9154 |
size_t left = bufsiz;
|
|
|
ed9154 |
ssize_t nr = -1;
|
|
|
ed9154 |
@@ -313,7 +349,10 @@ getln(int fd, char *buf, size_t bufsiz,
|
|
|
ed9154 |
char c = '\0';
|
|
|
ed9154 |
debug_decl(getln, SUDO_DEBUG_CONV)
|
|
|
ed9154 |
|
|
|
ed9154 |
+ *errval = TGP_ERRVAL_NOERROR;
|
|
|
ed9154 |
+
|
|
|
ed9154 |
if (left == 0) {
|
|
|
ed9154 |
+ *errval = TGP_ERRVAL_READERROR;
|
|
|
ed9154 |
errno = EINVAL;
|
|
|
ed9154 |
debug_return_str(NULL); /* sanity */
|
|
|
ed9154 |
}
|
|
|
ed9154 |
@@ -354,14 +393,27 @@ getln(int fd, char *buf, size_t bufsiz,
|
|
|
ed9154 |
}
|
|
|
ed9154 |
}
|
|
|
ed9154 |
|
|
|
ed9154 |
- debug_return_str_masked(nr == 1 ? buf : NULL);
|
|
|
ed9154 |
+ if (nr != 1) {
|
|
|
ed9154 |
+ if (nr == 0) {
|
|
|
ed9154 |
+ *errval = TGP_ERRVAL_NOPASSWORD;
|
|
|
ed9154 |
+ } else if (nr == -1) {
|
|
|
ed9154 |
+ if (errno == EINTR) {
|
|
|
ed9154 |
+ if (signo[SIGALRM] == 1)
|
|
|
ed9154 |
+ *errval = TGP_ERRVAL_TIMEOUT;
|
|
|
ed9154 |
+ } else {
|
|
|
ed9154 |
+ *errval = TGP_ERRVAL_READERROR;
|
|
|
ed9154 |
+ }
|
|
|
ed9154 |
+ }
|
|
|
ed9154 |
+ debug_return_str(NULL);
|
|
|
ed9154 |
+ }
|
|
|
ed9154 |
+
|
|
|
ed9154 |
+ debug_return_str_masked(buf);
|
|
|
ed9154 |
}
|
|
|
ed9154 |
|
|
|
ed9154 |
static void
|
|
|
ed9154 |
tgetpass_handler(int s)
|
|
|
ed9154 |
{
|
|
|
ed9154 |
- if (s != SIGALRM)
|
|
|
ed9154 |
- signo[s] = 1;
|
|
|
ed9154 |
+ signo[s] = 1;
|
|
|
ed9154 |
}
|
|
|
ed9154 |
|
|
|
ed9154 |
static bool
|