Skip to content

Commit

Permalink
Attempt to re-open CONIN$ if stdin has been redirected on Windows
Browse files Browse the repository at this point in the history
This should hopefully fix the problem with --passwd-on-stdin, described
in openconnect/openconnect-gui#101

It doesn't actually work for me in wine, as I get 'Access Denied' when
trying to use ReadConsoleW() on the resulting handle. But wine is strange,
and this at least shouldn't make things any *worse*.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Sep 23, 2016
1 parent 2c7a54b commit b40bb63
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions main.c
Expand Up @@ -367,17 +367,29 @@ static char *convert_arg_to_utf8(char **argv, char *arg)
static void read_stdin(char **string, int hidden, int allow_fail)
{
CONSOLE_READCONSOLE_CONTROL rcc = { sizeof(rcc), 0, 13, 0 };
HANDLE stdinh = GetStdHandle(STD_INPUT_HANDLE);
HANDLE conh, stdinh = GetStdHandle(STD_INPUT_HANDLE);
DWORD cmode, nr_read;
wchar_t wbuf[1024];
char *buf;

conh = stdinh;
if (!GetConsoleMode(conh, &cmode)) {
/* STDIN is not a console? Try opening it explicitly */
conh = CreateFile("CONIN$", GENERIC_READ, FILE_SHARE_READ,
0,OPEN_EXISTING, 0, 0);
if (conh == INVALID_HANDLE_VALUE || !GetConsoleMode(conh, &cmode)) {
char *errstr = openconnect__win32_strerror(GetLastError());
fprintf(stderr, _("Failed to open CONIN$: %s\n"), errstr);
free(errstr);
*string = NULL;
goto out;
}
}
if (hidden) {
GetConsoleMode(stdinh, &cmode);
SetConsoleMode(stdinh, cmode & (~ENABLE_ECHO_INPUT));
SetConsoleMode(conh, cmode & (~ENABLE_ECHO_INPUT));
}

if (!ReadConsoleW(stdinh, wbuf, sizeof(wbuf)/2, &nr_read, &rcc)) {
if (!ReadConsoleW(conh, wbuf, sizeof(wbuf)/2, &nr_read, &rcc)) {
char *errstr = openconnect__win32_strerror(GetLastError());
fprintf(stderr, _("ReadConsole() failed: %s\n"), errstr);
free(errstr);
Expand Down Expand Up @@ -417,9 +429,11 @@ static void read_stdin(char **string, int hidden, int allow_fail)

out:
if (hidden) {
SetConsoleMode(stdinh, cmode);
SetConsoleMode(conh, cmode);
fprintf(stderr, "\n");
}
if (conh != stdinh && conh != INVALID_HANDLE_VALUE)
CloseHandle(conh);
}

#elif defined(HAVE_ICONV)
Expand Down

0 comments on commit b40bb63

Please sign in to comment.