* 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:
		| @@ -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; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user