mirror of
https://github.com/tw93/Mole.git
synced 2026-03-22 18:30:08 +00:00
fix: pass through sudo's native prompt instead of hardcoding 'Password:' (#599)
* pass through sudo prompt instead of hardcoding Password: * simplify: remove redundant retry loop, sudo handles retries internally * keep stty safety net and styled prefix * fix: clear clamshell sudo prompt lines correctly --------- Co-authored-by: Tw93 <hitw93@gmail.com>
This commit is contained in:
@@ -44,58 +44,24 @@ is_clamshell_mode() {
|
|||||||
|
|
||||||
_request_password() {
|
_request_password() {
|
||||||
local tty_path="$1"
|
local tty_path="$1"
|
||||||
local attempts=0
|
|
||||||
local show_hint=true
|
|
||||||
|
|
||||||
# Extra safety: ensure sudo cache is cleared before password input
|
|
||||||
sudo -k 2> /dev/null
|
sudo -k 2> /dev/null
|
||||||
|
|
||||||
# Save original terminal settings and ensure they're restored on exit
|
|
||||||
local stty_orig
|
local stty_orig
|
||||||
stty_orig=$(stty -g < "$tty_path" 2> /dev/null || echo "")
|
stty_orig=$(stty -g < "$tty_path" 2> /dev/null || echo "")
|
||||||
trap '[[ -n "${stty_orig:-}" ]] && stty "${stty_orig:-}" < "$tty_path" 2> /dev/null || true' RETURN
|
trap '[[ -n "${stty_orig:-}" ]] && stty "${stty_orig:-}" < "$tty_path" 2> /dev/null || true' RETURN
|
||||||
|
|
||||||
while ((attempts < 3)); do
|
if check_touchid_support; then
|
||||||
local password=""
|
echo -e "${GRAY}Note: Touch ID dialog may appear once more, just cancel it${NC}" > "$tty_path"
|
||||||
|
fi
|
||||||
|
|
||||||
# Show hint on first attempt about Touch ID appearing again
|
echo -e "${PURPLE}${ICON_ARROW}${NC} Enter your credentials:" > "$tty_path"
|
||||||
if [[ $show_hint == true ]] && check_touchid_support; then
|
|
||||||
echo -e "${GRAY}Note: Touch ID dialog may appear once more, just cancel it${NC}" > "$tty_path"
|
|
||||||
show_hint=false
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "${PURPLE}${ICON_ARROW}${NC} Password: " > "$tty_path"
|
# shellcheck disable=SC2024,SC2094
|
||||||
|
# Intentionally route sudo's native prompt to the same TTY device it reads from.
|
||||||
# Disable terminal echo to hide password input (keep canonical mode for reliable input)
|
if sudo -v < "$tty_path" > /dev/null 2> "$tty_path"; then
|
||||||
stty -echo < "$tty_path" 2> /dev/null || true
|
return 0
|
||||||
IFS= read -r password < "$tty_path" || password=""
|
fi
|
||||||
# Restore terminal echo immediately
|
|
||||||
stty echo < "$tty_path" 2> /dev/null || true
|
|
||||||
|
|
||||||
printf "\n" > "$tty_path"
|
|
||||||
|
|
||||||
if [[ -z "$password" ]]; then
|
|
||||||
unset password
|
|
||||||
attempts=$((attempts + 1))
|
|
||||||
if [[ $attempts -lt 3 ]]; then
|
|
||||||
echo -e "${GRAY}${ICON_WARNING}${NC} Password cannot be empty" > "$tty_path"
|
|
||||||
fi
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Verify password with sudo
|
|
||||||
# NOTE: macOS PAM will trigger Touch ID before password auth - this is system behavior
|
|
||||||
if printf '%s\n' "$password" | sudo -S -p "" -v > /dev/null 2>&1; then
|
|
||||||
unset password
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
unset password
|
|
||||||
attempts=$((attempts + 1))
|
|
||||||
if [[ $attempts -lt 3 ]]; then
|
|
||||||
echo -e "${GRAY}${ICON_WARNING}${NC} Incorrect password, try again" > "$tty_path"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@@ -154,10 +120,14 @@ request_sudo_access() {
|
|||||||
|
|
||||||
# Check if in clamshell mode - if yes, skip Touch ID entirely
|
# Check if in clamshell mode - if yes, skip Touch ID entirely
|
||||||
if is_clamshell_mode; then
|
if is_clamshell_mode; then
|
||||||
|
local clear_lines=3
|
||||||
|
if check_touchid_support; then
|
||||||
|
clear_lines=4
|
||||||
|
fi
|
||||||
echo -e "${PURPLE}${ICON_ARROW}${NC} ${prompt_msg}"
|
echo -e "${PURPLE}${ICON_ARROW}${NC} ${prompt_msg}"
|
||||||
if _request_password "$tty_path"; then
|
if _request_password "$tty_path"; then
|
||||||
# Clear all prompt lines (use safe clearing method)
|
# Clear all prompt lines (use safe clearing method)
|
||||||
safe_clear_lines 3 "$tty_path"
|
safe_clear_lines "$clear_lines" "$tty_path"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -70,3 +70,59 @@ setup() {
|
|||||||
result=$(bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; source '$PROJECT_ROOT/lib/core/sudo.sh'; echo \$MOLE_SUDO_ESTABLISHED")
|
result=$(bash -c "source '$PROJECT_ROOT/lib/core/common.sh'; source '$PROJECT_ROOT/lib/core/sudo.sh'; echo \$MOLE_SUDO_ESTABLISHED")
|
||||||
[[ "$result" == "false" ]] || [[ -z "$result" ]]
|
[[ "$result" == "false" ]] || [[ -z "$result" ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "request_sudo_access clears four lines in clamshell mode when Touch ID hint is shown" {
|
||||||
|
run bash -c '
|
||||||
|
source "'"$PROJECT_ROOT"'/lib/core/common.sh"
|
||||||
|
source "'"$PROJECT_ROOT"'/lib/core/sudo.sh"
|
||||||
|
|
||||||
|
tty_file="$(mktemp)"
|
||||||
|
chmod 600 "$tty_file"
|
||||||
|
|
||||||
|
sudo() {
|
||||||
|
case "$1" in
|
||||||
|
-n) return 1 ;;
|
||||||
|
-k) return 0 ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
tty() { printf "%s\n" "$tty_file"; }
|
||||||
|
is_clamshell_mode() { return 0; }
|
||||||
|
check_touchid_support() { return 0; }
|
||||||
|
_request_password() { return 0; }
|
||||||
|
safe_clear_lines() { printf "CLEAR:%s\n" "$1"; }
|
||||||
|
|
||||||
|
request_sudo_access "Admin access required"
|
||||||
|
'
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[[ "$output" == *"CLEAR:4"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "request_sudo_access keeps three-line cleanup in clamshell mode without Touch ID" {
|
||||||
|
run bash -c '
|
||||||
|
source "'"$PROJECT_ROOT"'/lib/core/common.sh"
|
||||||
|
source "'"$PROJECT_ROOT"'/lib/core/sudo.sh"
|
||||||
|
|
||||||
|
tty_file="$(mktemp)"
|
||||||
|
chmod 600 "$tty_file"
|
||||||
|
|
||||||
|
sudo() {
|
||||||
|
case "$1" in
|
||||||
|
-n) return 1 ;;
|
||||||
|
-k) return 0 ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
tty() { printf "%s\n" "$tty_file"; }
|
||||||
|
is_clamshell_mode() { return 0; }
|
||||||
|
check_touchid_support() { return 1; }
|
||||||
|
_request_password() { return 0; }
|
||||||
|
safe_clear_lines() { printf "CLEAR:%s\n" "$1"; }
|
||||||
|
|
||||||
|
request_sudo_access "Admin access required"
|
||||||
|
'
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[[ "$output" == *"CLEAR:3"* ]]
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user