2727
2828#include <sys/types.h>
2929#include <sys/param.h>
30- #ifdef HAVE_SYS_BSDTYPES_H
31- # include <sys/bsdtypes.h>
32- #endif /* HAVE_SYS_BSDTYPES_H */
33- #include <sys/time.h>
3430#include <stdio.h>
3531#ifdef STDC_HEADERS
3632# include <stdlib.h>
5753#include <errno.h>
5854#include <signal.h>
5955#include <fcntl.h>
60- #ifdef HAVE_TERMIOS_H
61- # include <termios.h>
62- #else
63- # ifdef HAVE_TERMIO_H
64- # include <termio.h>
65- # else
66- # include <sgtty.h>
67- # include <sys/ioctl.h>
68- # endif /* HAVE_TERMIO_H */
69- #endif /* HAVE_TERMIOS_H */
7056
7157#include "sudo.h"
7258
7359#ifndef lint
7460__unused static const char rcsid [] = "$Sudo$" ;
7561#endif /* lint */
7662
77- #ifndef TCSASOFT
78- # define TCSASOFT 0
79- #endif
80- #ifndef ECHONL
81- # define ECHONL 0
82- #endif
83-
84- #ifndef _POSIX_VDISABLE
85- # ifdef VDISABLE
86- # define _POSIX_VDISABLE VDISABLE
87- # else
88- # define _POSIX_VDISABLE 0
89- # endif
90- #endif
91-
92- /*
93- * Compat macros for non-termios systems.
94- */
95- #ifndef HAVE_TERMIOS_H
96- # ifdef HAVE_TERMIO_H
97- # undef termios
98- # define termios termio
99- # define tcgetattr (f , t ) ioctl(f, TCGETA, t)
100- # define tcsetattr (f , a , t ) ioctl(f, a, t)
101- # undef TCSAFLUSH
102- # define TCSAFLUSH TCSETAF
103- # else
104- # undef termios
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)
109- # undef TCSAFLUSH
110- # define TCSAFLUSH TIOCSETP
111- # endif /* HAVE_TERMIO_H */
112- #endif /* HAVE_TERMIOS_H */
113-
11463static volatile sig_atomic_t signo ;
11564
11665static void handler __P ((int ));
117- static char * getln __P ((int , char * , size_t ));
66+ static char * getln __P ((int , char * , size_t , int ));
11867static char * sudo_askpass __P ((const char * ) );
11968
12069/*
@@ -128,10 +77,9 @@ tgetpass(prompt, timeout, flags)
12877{
12978 sigaction_t sa , savealrm , saveint , savehup , savequit , saveterm ;
13079 sigaction_t savetstp , savettin , savettou ;
131- struct termios term , oterm ;
13280 char * pass ;
13381 static char buf [SUDO_PASS_MAX + 1 ];
134- int input , output , save_errno ;
82+ int input , output , save_errno , neednl ; ;
13583
13684 (void ) fflush (stdout );
13785
@@ -167,19 +115,10 @@ tgetpass(prompt, timeout, flags)
167115 (void ) sigaction (SIGTTIN , & sa , & savettin );
168116 (void ) sigaction (SIGTTOU , & sa , & savettou );
169117
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 );
175- #ifdef VSTATUS
176- term .c_cc [VSTATUS ] = _POSIX_VDISABLE ;
177- #endif
178- (void ) tcsetattr (input , TCSAFLUSH |TCSASOFT , & term );
179- } else {
180- zero_bytes (& term , sizeof (term ));
181- zero_bytes (& oterm , sizeof (oterm ));
182- }
118+ if (def_pwstars )
119+ neednl = term_raw (input );
120+ else
121+ neednl = term_noecho (input );
183122
184123 /* No output if we are already backgrounded. */
185124 if (signo != SIGTTOU && signo != SIGTTIN ) {
@@ -188,20 +127,16 @@ tgetpass(prompt, timeout, flags)
188127
189128 if (timeout > 0 )
190129 alarm (timeout );
191- pass = getln (input , buf , sizeof (buf ));
130+ pass = getln (input , buf , sizeof (buf ), def_pwstars );
192131 alarm (0 );
193132 save_errno = errno ;
194133
195- if (! ISSET ( term . c_lflag , ECHO ) )
134+ if (neednl )
196135 (void ) write (output , "\n" , 1 );
197136 }
198137
199138 /* Restore old tty settings and signals. */
200- if (memcmp (& term , & oterm , sizeof (term )) != 0 ) {
201- while (tcsetattr (input , TCSAFLUSH |TCSASOFT , & oterm ) == -1 &&
202- errno == EINTR )
203- continue ;
204- }
139+ term_restore (input );
205140 (void ) sigaction (SIGALRM , & savealrm , NULL );
206141 (void ) sigaction (SIGINT , & saveint , NULL );
207142 (void ) sigaction (SIGHUP , & savehup , NULL );
@@ -269,32 +204,54 @@ sudo_askpass(prompt)
269204
270205 /* Get response from child (askpass) and restore SIGPIPE handler */
271206 (void ) close (pfd [1 ]);
272- pass = getln (pfd [0 ], buf , sizeof (buf ));
207+ pass = getln (pfd [0 ], buf , sizeof (buf ), 0 );
273208 (void ) close (pfd [0 ]);
274209 (void ) sigaction (SIGPIPE , & saved_sa_pipe , NULL );
275210
276211 return (pass );
277212}
278213
214+ extern int term_erase , term_kill ;
215+
279216static char *
280- getln (fd , buf , bufsiz )
217+ getln (fd , buf , bufsiz , stars )
281218 int fd ;
282219 char * buf ;
283220 size_t bufsiz ;
221+ int stars ;
284222{
223+ size_t left = bufsiz ;
285224 ssize_t nr = -1 ;
286225 char * cp = buf ;
287226 char c = '\0' ;
288227
289- if (bufsiz == 0 ) {
228+ if (left == 0 ) {
290229 errno = EINVAL ;
291230 return (NULL ); /* sanity */
292231 }
293232
294- while (-- bufsiz ) {
233+ while (-- left ) {
295234 nr = read (fd , & c , 1 );
296235 if (nr != 1 || c == '\n' || c == '\r' )
297236 break ;
237+ if (stars ) {
238+ if (c == term_kill ) {
239+ while (cp > buf ) {
240+ (void ) write (fd , "\b \b" , 3 );
241+ -- cp ;
242+ }
243+ left = bufsiz ;
244+ continue ;
245+ } else if (c == term_erase ) {
246+ if (cp > buf ) {
247+ (void ) write (fd , "\b \b" , 3 );
248+ -- cp ;
249+ left ++ ;
250+ }
251+ continue ;
252+ }
253+ (void ) write (fd , "*" , 1 );
254+ }
298255 * cp ++ = c ;
299256 }
300257 * cp = '\0' ;
0 commit comments