X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/a9422f39e34f55d1925d1ebef35ace1a0f1c2f6a..fe50e8140a2dbb3ba357a0ab777f34e07d568c23:/plink.c diff --git a/plink.c b/plink.c index 1d68e978..26a17292 100644 --- a/plink.c +++ b/plink.c @@ -11,6 +11,7 @@ #define PUTTY_DO_GLOBALS /* actually _define_ globals */ #include "putty.h" +#include "winstuff.h" #include "storage.h" void fatalbox (char *p, ...) { @@ -41,6 +42,8 @@ void logevent(char *string) { } void verify_ssh_host_key(char *host, int port, char *keytype, char *keystr, char *fingerprint) { int ret; + HANDLE hin; + DWORD savemode, i; static const char absentmsg[] = "The server's host key is not cached in the registry. You\n" @@ -83,10 +86,21 @@ void verify_ssh_host_key(char *host, int port, char *keytype, if (ret == 0) /* success - key matched OK */ return; - if (ret == 2) { /* key was different */ + + if (ret == 2) /* key was different */ fprintf(stderr, wrongmsg, fingerprint); - if (fgets(line, sizeof(line), stdin) && - line[0] != '\0' && line[0] != '\n') { + if (ret == 1) /* key was absent */ + fprintf(stderr, absentmsg, fingerprint); + + hin = GetStdHandle(STD_INPUT_HANDLE); + GetConsoleMode(hin, &savemode); + SetConsoleMode(hin, (savemode | ENABLE_ECHO_INPUT | + ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)); + ReadFile(hin, line, sizeof(line)-1, &i, NULL); + SetConsoleMode(hin, savemode); + + if (ret == 2) { /* key was different */ + if (line[0] != '\0' && line[0] != '\r' && line[0] != '\n') { if (line[0] == 'y' || line[0] == 'Y') store_host_key(host, port, keytype, keystr); } else { @@ -95,9 +109,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype, } } if (ret == 1) { /* key was absent */ - fprintf(stderr, absentmsg, fingerprint); - if (fgets(line, sizeof(line), stdin) && - (line[0] == 'y' || line[0] == 'Y')) + if (line[0] == 'y' || line[0] == 'Y') store_host_key(host, port, keytype, keystr); else { fprintf(stderr, abandoned); @@ -106,7 +118,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype, } } -HANDLE outhandle; +HANDLE outhandle, errhandle; DWORD orig_console_mode; void begin_session(void) { @@ -116,17 +128,17 @@ void begin_session(void) { SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), orig_console_mode); } -void term_out(void) -{ - int reap; +void from_backend(int is_stderr, char *data, int len) { + int pos; DWORD ret; - reap = 0; - while (reap < inbuf_head) { - if (!WriteFile(outhandle, inbuf+reap, inbuf_head-reap, &ret, NULL)) + HANDLE h = (is_stderr ? errhandle : outhandle); + + pos = 0; + while (pos < len) { + if (!WriteFile(h, data+pos, len-pos, &ret, NULL)) return; /* give up in panic */ - reap += ret; + pos += ret; } - inbuf_head = 0; } struct input_data { @@ -177,7 +189,7 @@ static int get_password(const char *prompt, char *str, int maxlen) return 1; } -static int WINAPI stdin_read_thread(void *param) { +static DWORD WINAPI stdin_read_thread(void *param) { struct input_data *idata = (struct input_data *)param; HANDLE inhandle; @@ -438,6 +450,7 @@ int main(int argc, char **argv) { GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &orig_console_mode); SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT); outhandle = GetStdHandle(STD_OUTPUT_HANDLE); + errhandle = GetStdHandle(STD_ERROR_HANDLE); /* * Now we must send the back end oodles of stuff. @@ -492,7 +505,6 @@ int main(int argc, char **argv) { break; } } - term_out(); } else if (n == 1) { if (idata.len > 0) { back->send(idata.buffer, idata.len); @@ -500,6 +512,8 @@ int main(int argc, char **argv) { back->special(TS_EOF); } } + if (back->socket() == INVALID_SOCKET) + break; /* we closed the connection */ } WSACleanup(); return 0;