mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-29 01:31:41 +00:00
Fix password reader for Windows using msvcrt.getwch()
The existing password prompt uses /dev/tty and termios to read input with echo disabled. Neither exists on Windows. On Windows, msvcrt.getwch() reads a single character from the console without echoing it. This adds a Windows code path that uses getwch() in a loop, collecting characters until Enter is pressed. The Unix path using termios and /dev/tty is unchanged.
This commit is contained in:
parent
4de5e017f1
commit
4bc32dc0f1
1 changed files with 37 additions and 27 deletions
|
|
@ -29,6 +29,7 @@ Usage:
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
@ -192,39 +193,48 @@ def _prompt_for_sudo_password(timeout_seconds: int = 45) -> str:
|
||||||
result = {"password": None, "done": False}
|
result = {"password": None, "done": False}
|
||||||
|
|
||||||
def read_password_thread():
|
def read_password_thread():
|
||||||
"""Read password from /dev/tty with echo disabled."""
|
"""Read password with echo disabled. Uses msvcrt on Windows, /dev/tty on Unix."""
|
||||||
tty_fd = None
|
|
||||||
old_attrs = None
|
|
||||||
try:
|
try:
|
||||||
import termios
|
if platform.system() == "Windows":
|
||||||
tty_fd = os.open("/dev/tty", os.O_RDONLY)
|
import msvcrt
|
||||||
old_attrs = termios.tcgetattr(tty_fd)
|
chars = []
|
||||||
new_attrs = termios.tcgetattr(tty_fd)
|
while True:
|
||||||
new_attrs[3] = new_attrs[3] & ~termios.ECHO
|
c = msvcrt.getwch()
|
||||||
termios.tcsetattr(tty_fd, termios.TCSAFLUSH, new_attrs)
|
if c in ("\r", "\n"):
|
||||||
chars = []
|
break
|
||||||
while True:
|
if c == "\x03":
|
||||||
b = os.read(tty_fd, 1)
|
raise KeyboardInterrupt
|
||||||
if not b or b in (b"\n", b"\r"):
|
chars.append(c)
|
||||||
break
|
result["password"] = "".join(chars)
|
||||||
chars.append(b)
|
else:
|
||||||
result["password"] = b"".join(chars).decode("utf-8", errors="replace")
|
import termios
|
||||||
|
tty_fd = os.open("/dev/tty", os.O_RDONLY)
|
||||||
|
old_attrs = termios.tcgetattr(tty_fd)
|
||||||
|
new_attrs = termios.tcgetattr(tty_fd)
|
||||||
|
new_attrs[3] = new_attrs[3] & ~termios.ECHO
|
||||||
|
termios.tcsetattr(tty_fd, termios.TCSAFLUSH, new_attrs)
|
||||||
|
try:
|
||||||
|
chars = []
|
||||||
|
while True:
|
||||||
|
b = os.read(tty_fd, 1)
|
||||||
|
if not b or b in (b"\n", b"\r"):
|
||||||
|
break
|
||||||
|
chars.append(b)
|
||||||
|
result["password"] = b"".join(chars).decode("utf-8", errors="replace")
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
termios.tcsetattr(tty_fd, termios.TCSAFLUSH, old_attrs)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
os.close(tty_fd)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
except (EOFError, KeyboardInterrupt, OSError):
|
except (EOFError, KeyboardInterrupt, OSError):
|
||||||
result["password"] = ""
|
result["password"] = ""
|
||||||
except Exception:
|
except Exception:
|
||||||
result["password"] = ""
|
result["password"] = ""
|
||||||
finally:
|
finally:
|
||||||
if tty_fd is not None and old_attrs is not None:
|
|
||||||
try:
|
|
||||||
import termios as _termios
|
|
||||||
_termios.tcsetattr(tty_fd, _termios.TCSAFLUSH, old_attrs)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
if tty_fd is not None:
|
|
||||||
try:
|
|
||||||
os.close(tty_fd)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
result["done"] = True
|
result["done"] = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue