Skip to content

Commit 6d167ae

Browse files
committed
fix sftp.exe client to work using password authentication
ssh.exe client invoked underneath was not able to send password prompt and read password from user as stdin and stdout handles were redirected to sockets by sftp.exe ; stderr which is not redirected is used to show prompt to users and data is read from console
1 parent 0d3a933 commit 6d167ae

File tree

2 files changed

+29
-97
lines changed

2 files changed

+29
-97
lines changed

contrib/win32/win32compat/socket.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ static fd_set write_sfd_set;
7272

7373
int PassInputFd = STDIN_FILENO;
7474
int PassOutputFd = STDOUT_FILENO;
75+
int PassErrorFd = STDERR_FILENO;
7576

7677
/*
7778
* We store cookies for authorize

readpass.c

Lines changed: 28 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454

5555
extern int PassInputFd;
5656
extern int PassOutputFd;
57+
extern int PassErrorFd;
5758

5859
#endif
5960

@@ -334,110 +335,40 @@ read_passphrase(const char *prompt, int flags)
334335
* Show prompt for user.
335336
*/
336337

337-
_write(PassOutputFd, prompt, strlen(prompt));
338-
339-
/*
340-
* Disable stdin echo.
341-
*/
342-
343-
GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode);
344-
345-
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode & (~ENABLE_ECHO_INPUT));
346-
347-
/*
348-
* Read pass from stdin socket.
349-
*/
338+
_write(PassErrorFd, prompt, strlen(prompt));
350339

351340
len = retr = 0;
352-
353-
do
354-
{
355-
retr = _read(PassInputFd, buf + len, sizeof(buf) - 1 - len);
356-
357-
/*
358-
* If read error.
359-
*/
360-
361-
if (retr == -1)
362-
{
363-
int winerr = GetLastError();
364-
365-
/*
366-
* Non fatal. Only write message and try again.
367-
*/
368-
369-
if (errno == EINTR || errno == EAGAIN ||
370-
winerr == WSAENOTSOCK || winerr == WSAEWOULDBLOCK)
371-
{
372-
debug("ERROR. read_passphrase() : [errno = %d, winerr = %d], "
373-
"trying again...\n", errno, winerr);
374-
375-
fflush(stderr);
376-
}
377-
378-
/*
379-
* Fatal error. Break loop with empty string.
380-
*/
341+
int bufsize = sizeof(buf);
381342

382-
else
383-
{
384-
error("ERROR. read_passphrase() : fatal error"
385-
" [errno = %d, winerr = %d]...\n", errno, winerr);
386-
387-
fflush(stderr);
388-
389-
buf[0] = 0;
390-
391-
len = 1;
392-
393-
break;
394-
}
395-
}
343+
while (_kbhit())
344+
_getch();
396345

397-
/*
398-
* No error.
399-
*/
400-
401-
else
402-
{
403-
len += retr;
404-
}
405-
} while (len < sizeof(buf) - 1 && buf[len] == '\r');
346+
while ( len < bufsize ) {
406347

407-
/*
408-
* Put zero at string end.
409-
*/
348+
buf[len] = (unsigned char) _getch() ;
410349

411-
if (len > 0)
412-
{
413-
buf[len - 1] = '\0';
414-
}
415-
else
416-
{
417-
buf[0] = '\0';
418-
}
419-
420-
_write(PassOutputFd, "\n", strlen("\n"));
421350

422-
len = strlen(buf);
423-
424-
while (len > 0 && buf[len - 1] == 0xa || buf[len - 1] == 0xd)
425-
{
426-
buf[len - 1] = 0;
427-
428-
len --;
429-
}
430-
431-
/*
432-
* Set stdin echo back.
433-
*/
434-
435-
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode | ENABLE_ECHO_INPUT);
436-
437-
/*
438-
* Return copy of pass readed from stdin.
439-
*/
440-
351+
if ( buf[len] == '\r' ) {
352+
if (_kbhit() )
353+
_getch(); // read linefeed if its there
354+
break;
355+
}
356+
else if ( buf[len] == '\n' ) {
357+
break;
358+
}
359+
else if ( buf[len] == '\b' ) { // backspace
360+
if (len > 0 )
361+
len--; // overwrite last character
362+
}
363+
else {
364+
365+
_putch( (int) '*' ); // show a star in place of what is typed
366+
len++; // keep reading in the loop
367+
}
368+
}
369+
370+
buf[len] = '\0' ; // get rid of the cr/lf
371+
441372
ret = xstrdup(buf);
442373

443374
memset(buf, 'x', sizeof(buf));

0 commit comments

Comments
 (0)