=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/sudo/Attic/tgetpass.c,v retrieving revision 1.15 retrieving revision 1.16 diff -c -r1.15 -r1.16 *** src/usr.bin/sudo/Attic/tgetpass.c 2008/07/31 16:44:04 1.15 --- src/usr.bin/sudo/Attic/tgetpass.c 2008/11/14 11:58:08 1.16 *************** *** 1,5 **** /* ! * Copyright (c) 1996, 1998-2005 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above --- 1,6 ---- /* ! * Copyright (c) 1996, 1998-2005, 2007-2008 ! * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above *************** *** 70,76 **** #include "sudo.h" #ifndef lint ! __unused static const char rcsid[] = "$Sudo: tgetpass.c,v 1.111.2.7 2008/06/21 00:27:01 millert Exp $"; #endif /* lint */ #ifndef TCSASOFT --- 71,77 ---- #include "sudo.h" #ifndef lint ! __unused static const char rcsid[] = "$Sudo: tgetpass.c,v 1.124 2008/11/08 15:30:42 millert Exp $"; #endif /* lint */ #ifndef TCSASOFT *************** *** 114,119 **** --- 115,121 ---- static void handler __P((int)); static char *getln __P((int, char *, size_t)); + static char *sudo_askpass(const char *); /* * Like getpass(3) but with timeout and echo flags. *************** *** 132,137 **** --- 134,144 ---- int input, output, save_errno; (void) fflush(stdout); + + /* If using a helper program to get the password, run it instead. */ + if (ISSET(flags, TGP_ASKPASS) && user_askpass) + return(sudo_askpass(prompt)); + restart: signo = 0; pass = NULL; *************** *** 147,152 **** --- 154,160 ---- * Catch signals that would otherwise cause the user to end * up with echo turned off in the shell. */ + zero_bytes(&sa, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_flags = SA_INTERRUPT; /* don't restart system calls */ sa.sa_handler = handler; *************** *** 169,176 **** #endif (void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); } else { ! memset(&term, 0, sizeof(term)); ! memset(&oterm, 0, sizeof(oterm)); } /* No output if we are already backgrounded. */ --- 177,184 ---- #endif (void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); } else { ! zero_bytes(&term, sizeof(term)); ! zero_bytes(&oterm, sizeof(oterm)); } /* No output if we are already backgrounded. */ *************** *** 224,249 **** return(pass); } static char * getln(fd, buf, bufsiz) int fd; char *buf; size_t bufsiz; { ! char c, *cp; ! ssize_t nr; if (bufsiz == 0) { errno = EINVAL; return(NULL); /* sanity */ } ! cp = buf; ! nr = -1; ! while (--bufsiz && (nr = read(fd, &c, 1)) == 1 && c != '\n' && c != '\r') *cp++ = c; *cp = '\0'; ! return(nr == -1 ? NULL : buf); } static void --- 232,305 ---- return(pass); } + /* + * Fork a child and exec sudo-askpass to get the password from the user. + */ static char * + sudo_askpass(prompt) + const char *prompt; + { + static char buf[SUDO_PASS_MAX + 1], *pass; + sigaction_t sa, saved_sa_pipe; + int pfd[2]; + pid_t pid; + + if (pipe(pfd) == -1) + error(1, "unable to create pipe"); + + if ((pid = fork()) == -1) + error(1, "unable to fork"); + + if (pid == 0) { + /* child, point stdout to output side of the pipe and exec askpass */ + (void) dup2(pfd[1], STDOUT_FILENO); + set_perms(PERM_FULL_USER); + closefrom(STDERR_FILENO + 1); + execl(user_askpass, user_askpass, prompt, (char *)NULL); + warning("unable to run %s", user_askpass); + _exit(255); + } + + /* Ignore SIGPIPE in case child exits prematurely */ + zero_bytes(&sa, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SIG_IGN; + (void) sigaction(SIGPIPE, &sa, &saved_sa_pipe); + + /* Get response from child (askpass) and restore SIGPIPE handler */ + (void) close(pfd[1]); + pass = getln(pfd[0], buf, sizeof(buf)); + (void) close(pfd[0]); + (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL); + + return(pass); + } + + static char * getln(fd, buf, bufsiz) int fd; char *buf; size_t bufsiz; { ! ssize_t nr = -1; ! char *cp = buf; ! char c = '\0'; if (bufsiz == 0) { errno = EINVAL; return(NULL); /* sanity */ } ! while (--bufsiz) { ! nr = read(fd, &c, 1); ! if (nr != 1 || c == '\n' || c == '\r') ! break; *cp++ = c; + } *cp = '\0'; ! ! return(nr == 1 ? buf : NULL); } static void