2
* Copyright (c) 1996, 1998-2005, 2007-2008
2
* Copyright (c) 1996, 1998-2005, 2007-2009
3
3
* Todd C. Miller <Todd.Miller@courtesan.com>
5
5
* Permission to use, copy, modify, and distribute this software for any
58
54
#include <signal.h>
67
# include <sys/ioctl.h>
68
# endif /* HAVE_TERMIO_H */
69
#endif /* HAVE_TERMIOS_H */
74
__unused static const char rcsid[] = "$Sudo: tgetpass.c,v 1.126 2008/12/09 20:55:49 millert Exp $";
60
__unused static const char rcsid[] = "$Sudo: tgetpass.c,v 1.131 2009/05/25 12:02:42 millert Exp $";
84
#ifndef _POSIX_VDISABLE
86
# define _POSIX_VDISABLE VDISABLE
88
# define _POSIX_VDISABLE 0
93
* Compat macros for non-termios systems.
95
#ifndef HAVE_TERMIOS_H
98
# define termios termio
99
# define tcgetattr(f, t) ioctl(f, TCGETA, t)
100
# define tcsetattr(f, a, t) ioctl(f, a, t)
102
# define TCSAFLUSH TCSETAF
105
# define termios sgttyb
106
# define c_lflag sg_flags
107
# define tcgetattr(f, t) ioctl(f, TIOCGETP, t)
108
# define tcsetattr(f, a, t) ioctl(f, a, t)
110
# define TCSAFLUSH TIOCSETP
111
# endif /* HAVE_TERMIO_H */
112
#endif /* HAVE_TERMIOS_H */
114
63
static volatile sig_atomic_t signo;
116
65
static void handler __P((int));
117
static char *getln __P((int, char *, size_t));
66
static char *getln __P((int, char *, size_t, int));
118
67
static char *sudo_askpass __P((const char *));
69
extern int term_restore __P((int));
70
extern int term_noecho __P((int));
71
extern int term_raw __P((int));
121
74
* Like getpass(3) but with timeout and echo flags.
129
82
sigaction_t sa, savealrm, saveint, savehup, savequit, saveterm;
130
83
sigaction_t savetstp, savettin, savettou;
131
struct termios term, oterm;
133
85
static char buf[SUDO_PASS_MAX + 1];
134
int input, output, save_errno;
86
int input, output, save_errno, neednl;;
136
88
(void) fflush(stdout);
167
119
(void) sigaction(SIGTTIN, &sa, &savettin);
168
120
(void) sigaction(SIGTTOU, &sa, &savettou);
170
/* Turn echo off/on as specified by flags. */
171
if (tcgetattr(input, &oterm) == 0) {
172
(void) memcpy(&term, &oterm, sizeof(term));
173
if (!ISSET(flags, TGP_ECHO))
174
CLR(term.c_lflag, ECHO|ECHONL);
176
term.c_cc[VSTATUS] = _POSIX_VDISABLE;
178
(void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
180
zero_bytes(&term, sizeof(term));
181
zero_bytes(&oterm, sizeof(oterm));
123
neednl = term_raw(input);
125
neednl = term_noecho(input);
184
127
/* No output if we are already backgrounded. */
185
128
if (signo != SIGTTOU && signo != SIGTTIN) {
191
pass = getln(input, buf, sizeof(buf));
134
pass = getln(input, buf, sizeof(buf), def_pwfeedback);
193
136
save_errno = errno;
195
if (!ISSET(term.c_lflag, ECHO))
196
139
(void) write(output, "\n", 1);
199
142
/* Restore old tty settings and signals. */
200
if (memcmp(&term, &oterm, sizeof(term)) != 0) {
201
while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 &&
205
144
(void) sigaction(SIGALRM, &savealrm, NULL);
206
145
(void) sigaction(SIGINT, &saveint, NULL);
207
146
(void) sigaction(SIGHUP, &savehup, NULL);
270
209
/* Get response from child (askpass) and restore SIGPIPE handler */
271
210
(void) close(pfd[1]);
272
pass = getln(pfd[0], buf, sizeof(buf));
211
pass = getln(pfd[0], buf, sizeof(buf), 0);
273
212
(void) close(pfd[0]);
274
213
(void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
218
extern int term_erase, term_kill;
280
getln(fd, buf, bufsiz)
221
getln(fd, buf, bufsiz, feedback)
227
size_t left = bufsiz;
291
234
return(NULL); /* sanity */
295
238
nr = read(fd, &c, 1);
296
239
if (nr != 1 || c == '\n' || c == '\r')
242
if (c == term_kill) {
244
(void) write(fd, "\b \b", 3);
249
} else if (c == term_erase) {
251
(void) write(fd, "\b \b", 3);
257
(void) write(fd, "*", 1);
265
(void) write(fd, "\b \b", 3);
302
270
return(nr == 1 ? buf : NULL);