tweak changelog
[debian/sudo] / src / tgetpass.c
index f8a9d3e323b284612629f77ad81a3cdb3f8ec87a..31194b96317fcbaa1e6c123221649eca0ea958f0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998-2005, 2007-2011
+ * Copyright (c) 1996, 1998-2005, 2007-2013
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -26,7 +26,6 @@
 #include <config.h>
 
 #include <sys/types.h>
-#include <sys/param.h>
 #include <stdio.h>
 #ifdef STDC_HEADERS
 # include <stdlib.h>
 
 static volatile sig_atomic_t signo[NSIG];
 
-static void handler(int);
+static void tgetpass_handler(int);
 static char *getln(int, char *, size_t, int);
 static char *sudo_askpass(const char *, const char *);
 
-#ifdef _PATH_SUDO_ASKPASS
-const char *askpass_path = _PATH_SUDO_ASKPASS;
-#else
-const char *askpass_path;
-#endif
-
 /*
  * Like getpass(3) but with timeout and echo flags.
  */
@@ -84,15 +77,15 @@ tgetpass(const char *prompt, int timeout, int flags)
     (void) fflush(stdout);
 
     if (askpass == NULL) {
-       askpass = getenv("SUDO_ASKPASS");
+       askpass = getenv_unhooked("SUDO_ASKPASS");
        if (askpass == NULL || *askpass == '\0')
-           askpass = askpass_path;
+           askpass = sudo_conf_askpass_path();
     }
 
     /* If no tty present and we need to disable echo, try askpass. */
     if (!ISSET(flags, TGP_STDIN|TGP_ECHO|TGP_ASKPASS|TGP_NOECHO_TRY) &&
        !tty_present()) {
-       if (askpass == NULL || getenv("DISPLAY") == NULL) {
+       if (askpass == NULL || getenv_unhooked("DISPLAY") == NULL) {
            warningx(_("no tty present and no askpass program specified"));
            debug_return_str(NULL);
        }
@@ -102,7 +95,7 @@ tgetpass(const char *prompt, int timeout, int flags)
     /* If using a helper program to get the password, run it instead. */
     if (ISSET(flags, TGP_ASKPASS)) {
        if (askpass == NULL || *askpass == '\0')
-           errorx(1, _("no askpass program specified, try setting SUDO_ASKPASS"));
+           fatalx(_("no askpass program specified, try setting SUDO_ASKPASS"));
        debug_return_str_masked(sudo_askpass(askpass, prompt));
     }
 
@@ -137,7 +130,7 @@ restart:
     zero_bytes(&sa, sizeof(sa));
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_INTERRUPT;        /* don't restart system calls */
-    sa.sa_handler = handler;
+    sa.sa_handler = tgetpass_handler;
     (void) sigaction(SIGALRM, &sa, &savealrm);
     (void) sigaction(SIGINT, &sa, &saveint);
     (void) sigaction(SIGHUP, &sa, &savehup);
@@ -221,10 +214,10 @@ sudo_askpass(const char *askpass, const char *prompt)
     debug_decl(sudo_askpass, SUDO_DEBUG_CONV)
 
     if (pipe(pfd) == -1)
-       error(1, _("unable to create pipe"));
+       fatal(_("unable to create pipe"));
 
     if ((pid = fork()) == -1)
-       error(1, _("unable to fork"));
+       fatal(_("unable to fork"));
 
     if (pid == 0) {
        /* child, point stdout to output side of the pipe and exec askpass */
@@ -232,7 +225,8 @@ sudo_askpass(const char *askpass, const char *prompt)
            warning("dup2");
            _exit(255);
        }
-       (void) setuid(ROOT_UID);
+       if (setuid(ROOT_UID) == -1)
+           warning("setuid(%d)", ROOT_UID);
        if (setgid(user_details.gid)) {
            warning(_("unable to set gid to %u"), (unsigned int)user_details.gid);
            _exit(255);
@@ -260,6 +254,9 @@ sudo_askpass(const char *askpass, const char *prompt)
     (void) close(pfd[0]);
     (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
 
+    if (pass == NULL)
+       errno = EINTR;  /* make cancel button simulate ^C */
+
     debug_return_str_masked(pass);
 }
 
@@ -301,8 +298,7 @@ getln(int fd, char *buf, size_t bufsiz, int feedback)
                }
                continue;
            }
-           if (write(fd, "*", 1) == -1)
-               /* shut up glibc */;
+           ignore_result(write(fd, "*", 1));
        }
        *cp++ = c;
     }
@@ -320,7 +316,7 @@ getln(int fd, char *buf, size_t bufsiz, int feedback)
 }
 
 static void
-handler(int s)
+tgetpass_handler(int s)
 {
     if (s != SIGALRM)
        signo[s] = 1;