Repository navigation
Hardened the -C / --CredMgr credential-miss path so an unattended run can no longer silently prompt or hang
Latest- The STDIN fallback on a credential miss now happens ONLY when a human could actually answer. If not, we print a clear error and exit with a distinct reserved code, ERROR_NOT_FOUND (1168), so a calling CMD wrapper can tell "credential missing" apart from "wrong password" (rejected) and "ssh failed".
- New --CredMgrStrict boolean flag (Args.credMgrStrict): automation passes this to force fail-fast; it NEVER touches STDIN on a miss.
- Guardrail regardless of the flag: StdinIsInteractive() treats stdin as interactive ONLY if GetFileType()==FILE_TYPE_CHAR AND GetConsoleMode() succeeds. A redirected/piped/closed/detached stdin (scheduled task, service) is refused a prompt even without --CredMgrStrict.
- Integration is flag-and-signal, NOT ExitProcess(): WritePass() runs on the PipeListener worker thread AFTER the child launches, so a hard exit there would skip main()'s console-restore and handle cleanup. Instead WritePass() sets ctx->credMgrFailed, signals ctx->events[0], and ProcessOutput() ENDs the listener loop; main()'s normal exit path restores the console and returns ERROR_NOT_FOUND.
Usage / operational notes for -C (also see help text):
- Passwords stored in the credential MUST be ASCII-only. get_vault_pass() converts UTF-16 -> ANSI via CP_ACP; non-ASCII characters corrupt silently. (This is alongside the existing "no double-quote (") in passwords" rule.)
- Leading/trailing spaces in a stored credential are written to the child verbatim and WILL break auth. Trim them when saving the credential.
- Use the ATTACHED form -CTag (e.g. -CmyServer). The separated form "-C Tag" can swallow the next token. As with all sshpass options, every -option must precede the command: parsing stops at the first non-option token (ARGPARSE_STOP_AT_NON_OPTION).