* passwd.cc (_getpass_close_fd): New static pthread cleanup handler.
(getpass): Rework to use /dev/tty in the first place. Install _getpass_close_fd as pthread cleanup handler. Flush prompt explicitely. Lock input and switch off signal input handling when reading password.
This commit is contained in:
parent
ecdcf15712
commit
7c1d11f7e8
|
@ -1,3 +1,10 @@
|
||||||
|
2012-04-04 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* passwd.cc (_getpass_close_fd): New static pthread cleanup handler.
|
||||||
|
(getpass): Rework to use /dev/tty in the first place. Install
|
||||||
|
_getpass_close_fd as pthread cleanup handler. Flush prompt explicitely.
|
||||||
|
Lock input and switch off signal input handling when reading password.
|
||||||
|
|
||||||
2012-04-03 Corinna Vinschen <corinna@vinschen.de>
|
2012-04-03 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 13.
|
* include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 13.
|
||||||
|
|
|
@ -269,29 +269,50 @@ setpassent ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_getpass_close_fd (void *arg)
|
||||||
|
{
|
||||||
|
if (arg)
|
||||||
|
fclose ((FILE *) arg);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" char *
|
extern "C" char *
|
||||||
getpass (const char * prompt)
|
getpass (const char * prompt)
|
||||||
{
|
{
|
||||||
char *pass = _my_tls.locals.pass;
|
char *pass = _my_tls.locals.pass;
|
||||||
struct termios ti, newti;
|
struct termios ti, newti;
|
||||||
|
|
||||||
cygheap_fdget fhstdin (0);
|
/* Try to use controlling tty in the first place. Use stdin and stderr
|
||||||
|
only as fallback. */
|
||||||
|
FILE *in = stdin, *err = stderr;
|
||||||
|
FILE *tty = fopen ("/dev/tty", "w+b");
|
||||||
|
pthread_cleanup_push (_getpass_close_fd, tty);
|
||||||
|
if (tty)
|
||||||
|
{
|
||||||
|
/* Set close-on-exec for obvious reasons. */
|
||||||
|
fcntl (fileno (tty), F_SETFD, fcntl (fileno (tty), F_GETFD) | FD_CLOEXEC);
|
||||||
|
in = err = tty;
|
||||||
|
}
|
||||||
|
|
||||||
if (fhstdin < 0)
|
/* Make sure to notice if stdin is closed. */
|
||||||
|
if (tcgetattr (fileno (in), &ti) == -1)
|
||||||
pass[0] = '\0';
|
pass[0] = '\0';
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fhstdin->tcgetattr (&ti);
|
flockfile (in);
|
||||||
newti = ti;
|
newti = ti;
|
||||||
newti.c_lflag &= ~ECHO;
|
newti.c_lflag &= ~(ECHO | ISIG); /* No echo, no signal handling. */
|
||||||
fhstdin->tcsetattr (TCSANOW, &newti);
|
tcsetattr (fileno (in), TCSANOW, &newti);
|
||||||
fputs (prompt, stderr);
|
fputs (prompt, err);
|
||||||
fgets (pass, _PASSWORD_LEN, stdin);
|
fflush (err);
|
||||||
fprintf (stderr, "\n");
|
fgets (pass, _PASSWORD_LEN, in);
|
||||||
for (int i=0; pass[i]; i++)
|
fprintf (err, "\n");
|
||||||
if (pass[i] == '\r' || pass[i] == '\n')
|
tcsetattr (fileno (in), TCSANOW, &ti);
|
||||||
pass[i] = '\0';
|
funlockfile (in);
|
||||||
fhstdin->tcsetattr (TCSANOW, &ti);
|
char *crlf = strpbrk (pass, "\r\n");
|
||||||
|
if (crlf)
|
||||||
|
*crlf = '\0';
|
||||||
}
|
}
|
||||||
|
pthread_cleanup_pop (1);
|
||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue