One of my users found that the new ssh-add, from the portable OpenSSH CVS as of October 12, was hanging in his .profile while trying to start up CDE (Common Desktop Environment) on Solaris 2.6. The previous one, which was from OpenSSH 2.9p2, did not hang. It turns out that CDE, at least on Solaris 2.6, 7 and 8, runs the user's .profile with a special startup shell that allocates a pseudo-tty (I assume so people can use "stty" to set their preferred settings) but is not attached to anything that can actually accept user input. Those of you with Solaris can reproduce with DTSOURCEPROFILE=true /usr/dt/bin/sdt_shell -c ssh-add I discovered that the problem was that the new readpassphrase() function is flushing (that is, discarding) the terminal input but the old function cli_read_passphrase() did not. When input is not flushed, then ssh-add gets an immediate end of file and exits. When the input is flushed, a subsequent read from stdin hangs. I see by truss that sdt_shell is actually write an end-of-file character (^D) to the pseudo-tty, and apparently that results in a single zero-length read on the other side if it isn't flushed. You may wonder why the user was calling ssh-add from his .profile; it's because after CDE comes up the user runs an xterm (dtterm actually) with "-C -ls", which means a console window running as a login shell, which executes .profile again, and he goes to that console window to type in his passphrase. And actually the user was not following the documented way of using CDE, in that a comment in ~/.dtprofile says that anything which is going to result in reading from the user is supposed to be surrounded by a if [ ! "$DT" ]; then ... read data ... fi On the other hand, the old ssh-add used to work and the new one doesn't so it may cause problems for more people. A patch to go back to the old way is attached in case it is wanted. You might think that because readpassphrase() usually turns off echoing, that flushing the input is a good idea. If that's desired, I suggest either adding another flag or using the existing RPP_REQUIRE_TTY flag and using _T_FLUSH only if that is set. That flag is not set for ssh-add, but it is set for other things. - Dave Dykstra --- openbsd-compat/readpassphrase.c.O Fri Oct 12 17:12:22 2001 +++ openbsd-compat/readpassphrase.c Thu Oct 18 13:59:25 2001 @@ -36,12 +36,6 @@ #include <termios.h> #include <readpassphrase.h> -#ifdef TCSASOFT -# define _T_FLUSH (TCSAFLUSH|TCSASOFT) -#else -# define _T_FLUSH (TCSAFLUSH) -#endif - char * readpassphrase(prompt, buf, bufsiz, flags) const char *prompt; @@ -102,13 +96,13 @@ term.c_cc[VSTATUS] = _POSIX_VDISABLE; } #endif - (void)tcsetattr(input, _T_FLUSH, &term); + (void)tcsetattr(input, TCSANOW, &term); } if (!(flags & RPP_ECHO_ON)) { if (tcgetattr(input, &term) == 0 && (term.c_lflag & ECHO)) { echo = 1; term.c_lflag &= ~ECHO; - (void)tcsetattr(input, _T_FLUSH, &term); + (void)tcsetattr(input, TCSANOW, &term); } } @@ -141,7 +135,7 @@ if (status != _POSIX_VDISABLE) term.c_cc[VSTATUS] = status; #endif - (void)tcsetattr(input, _T_FLUSH, &term); + (void)tcsetattr(input, TCSANOW, &term); } (void)sigprocmask(SIG_SETMASK, &oset, NULL); if (input != STDIN_FILENO)