2
* Copyright (c) 1996, 1998-2005 Todd C. Miller <Todd.Miller@courtesan.com>
2
* Copyright (c) 1996, 1998-2005, 2007-2008
3
* Todd C. Miller <Todd.Miller@courtesan.com>
4
5
* Permission to use, copy, modify, and distribute this software for any
5
6
* purpose with or without fee is hereby granted, provided that the above
115
116
static void handler __P((int));
116
117
static char *getln __P((int, char *, size_t));
118
static char *sudo_askpass __P((const char *));
119
121
* Like getpass(3) but with timeout and echo flags.
132
134
int input, output, save_errno;
134
136
(void) fflush(stdout);
138
/* If using a helper program to get the password, run it instead. */
139
if (ISSET(flags, TGP_ASKPASS) && user_askpass)
140
return(sudo_askpass(prompt));
147
154
* Catch signals that would otherwise cause the user to end
148
155
* up with echo turned off in the shell.
157
zero_bytes(&sa, sizeof(sa));
150
158
sigemptyset(&sa.sa_mask);
151
159
sa.sa_flags = SA_INTERRUPT; /* don't restart system calls */
152
160
sa.sa_handler = handler;
170
178
(void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
172
memset(&term, 0, sizeof(term));
173
memset(&oterm, 0, sizeof(oterm));
180
zero_bytes(&term, sizeof(term));
181
zero_bytes(&oterm, sizeof(oterm));
176
184
/* No output if we are already backgrounded. */
236
* Fork a child and exec sudo-askpass to get the password from the user.
242
static char buf[SUDO_PASS_MAX + 1], *pass;
243
sigaction_t sa, saved_sa_pipe;
248
error(1, "unable to create pipe");
250
if ((pid = fork()) == -1)
251
error(1, "unable to fork");
254
/* child, point stdout to output side of the pipe and exec askpass */
255
(void) dup2(pfd[1], STDOUT_FILENO);
256
set_perms(PERM_FULL_USER);
257
closefrom(STDERR_FILENO + 1);
258
execl(user_askpass, user_askpass, prompt, (char *)NULL);
259
warning("unable to run %s", user_askpass);
263
/* Ignore SIGPIPE in case child exits prematurely */
264
zero_bytes(&sa, sizeof(sa));
265
sigemptyset(&sa.sa_mask);
267
sa.sa_handler = SIG_IGN;
268
(void) sigaction(SIGPIPE, &sa, &saved_sa_pipe);
270
/* Get response from child (askpass) and restore SIGPIPE handler */
271
(void) close(pfd[1]);
272
pass = getln(pfd[0], buf, sizeof(buf));
273
(void) close(pfd[0]);
274
(void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
228
280
getln(fd, buf, bufsiz)
236
289
if (bufsiz == 0) {
238
291
return(NULL); /* sanity */
243
while (--bufsiz && (nr = read(fd, &c, 1)) == 1 && c != '\n' && c != '\r')
295
nr = read(fd, &c, 1);
296
if (nr != 1 || c == '\n' || c == '\r')
246
return(nr == -1 ? NULL : buf);
302
return(nr == 1 ? buf : NULL);