From be1debcf5180fceb683a6b436e01bb43495e8442 Mon Sep 17 00:00:00 2001 From: Bryan Berns Date: Tue, 5 Jun 2018 22:32:10 -0400 Subject: [PATCH 1/2] Allow Use Of Non-ASCII Character In SSH Client Passwords - Modified readpassphrase() to read unicode characters and return utf8-encoded password strings to allow use of non-ascii characters. --- contrib/win32/win32compat/misc.c | 47 ++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c index 556448ec373..fe52b3e7141 100644 --- a/contrib/win32/win32compat/misc.c +++ b/contrib/win32/win32compat/misc.c @@ -1147,7 +1147,9 @@ char * readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags) { int current_index = 0; - char ch; + int utf8_read = 0; + char utf8_char[4]; + wchar_t ch; wchar_t* wtmp = NULL; if (outBufLen == 0) { @@ -1155,7 +1157,7 @@ readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags) return NULL; } - while (_kbhit()) _getch(); + while (_kbhit()) _getwch(); wtmp = utf8_to_utf16(prompt); if (wtmp == NULL) @@ -1165,36 +1167,51 @@ readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags) free(wtmp); while (current_index < outBufLen - 1) { - ch = _getch(); + ch = _getwch(); - if (ch == '\r') { - if (_kbhit()) _getch(); /* read linefeed if its there */ + if (ch == L'\r') { + if (_kbhit()) _getwch(); /* read linefeed if its there */ break; - } else if (ch == '\n') { + } else if (ch == L'\n') { break; - } else if (ch == '\b') { /* backspace */ + } else if (ch == L'\b') { /* backspace */ if (current_index > 0) { if (flags & RPP_ECHO_ON) - printf_s("%c \b", ch); + wprintf_s(L"%c \b", ch); - current_index--; /* overwrite last character */ + /* overwrite last character - remove any utf8 extended chars */ + while (current_index > 0 && (outBuf[current_index - 1] & 0xC0) == 0x80) + current_index--; + + /* overwrite last character - remove first utf8 byte */ + if (current_index > 0) + current_index--; } - } else if (ch == '\003') { /* exit on Ctrl+C */ + } else if (ch == L'\003') { /* exit on Ctrl+C */ fatal(""); } else { if (flags & RPP_SEVENBIT) ch &= 0x7f; - if (isalpha((unsigned char)ch)) { + if (iswalpha(ch)) { if(flags & RPP_FORCELOWER) - ch = tolower((unsigned char)ch); + ch = towlower(ch); if(flags & RPP_FORCEUPPER) - ch = toupper((unsigned char)ch); + ch = towupper(ch); } - outBuf[current_index++] = ch; + /* convert unicode to utf8 characters */ + int utf8_char_size = sizeof(utf8_char); + if ((utf8_read = WideCharToMultiByte(CP_UTF8, 0, &ch, 1, utf8_char, sizeof(utf8_char), NULL, NULL)) == 0) + fatal("character conversion failed"); + + /* append to output buffer if the characters fit */ + if (current_index + utf8_read >= outBufLen - 1) break; + memcpy(&outBuf[current_index], utf8_char, utf8_read); + current_index += utf8_read; + if(flags & RPP_ECHO_ON) - printf_s("%c", ch); + wprintf_s("%c", ch); } } From 7235de1c354a26416ffc4c602fa42ff432c9c9a4 Mon Sep 17 00:00:00 2001 From: Bryan Berns Date: Thu, 19 Jul 2018 19:59:40 -0400 Subject: [PATCH 2/2] Fixed Character Echo --- contrib/win32/win32compat/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c index fe52b3e7141..88efe734e09 100644 --- a/contrib/win32/win32compat/misc.c +++ b/contrib/win32/win32compat/misc.c @@ -1211,7 +1211,7 @@ readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags) current_index += utf8_read; if(flags & RPP_ECHO_ON) - wprintf_s("%c", ch); + wprintf_s(L"%c", ch); } }