mirror of
https://github.com/tw93/Mole.git
synced 2026-02-04 20:54:50 +00:00
129 lines
3.1 KiB
Bash
129 lines
3.1 KiB
Bash
#!/bin/bash
|
|
# Sudo Session Manager
|
|
# Unified sudo authentication and keepalive management
|
|
|
|
set -euo pipefail
|
|
|
|
# Global state
|
|
MOLE_SUDO_KEEPALIVE_PID=""
|
|
MOLE_SUDO_ESTABLISHED="false"
|
|
|
|
# Start sudo keepalive background process
|
|
# Returns: PID of keepalive process
|
|
_start_sudo_keepalive() {
|
|
# Start background keepalive process with all outputs redirected
|
|
# This is critical: command substitution waits for all file descriptors to close
|
|
(
|
|
# Initial delay to let sudo cache stabilize after password entry
|
|
# This prevents immediately triggering Touch ID again
|
|
sleep 2
|
|
|
|
local retry_count=0
|
|
while true; do
|
|
if ! sudo -n -v 2> /dev/null; then
|
|
((retry_count++))
|
|
if [[ $retry_count -ge 3 ]]; then
|
|
exit 1
|
|
fi
|
|
sleep 5
|
|
continue
|
|
fi
|
|
retry_count=0
|
|
sleep 30
|
|
kill -0 "$$" 2> /dev/null || exit
|
|
done
|
|
) > /dev/null 2>&1 &
|
|
|
|
local pid=$!
|
|
echo $pid
|
|
}
|
|
|
|
# Stop sudo keepalive process
|
|
# Args: $1 - PID of keepalive process
|
|
_stop_sudo_keepalive() {
|
|
local pid="${1:-}"
|
|
if [[ -n "$pid" ]]; then
|
|
kill "$pid" 2> /dev/null || true
|
|
wait "$pid" 2> /dev/null || true
|
|
fi
|
|
}
|
|
|
|
# Check if sudo session is active
|
|
has_sudo_session() {
|
|
sudo -n true 2> /dev/null
|
|
}
|
|
|
|
# Request sudo access (wrapper for common.sh function)
|
|
# Args: $1 - prompt message
|
|
request_sudo() {
|
|
local prompt_msg="${1:-Admin access required}"
|
|
|
|
if has_sudo_session; then
|
|
return 0
|
|
fi
|
|
|
|
# Use the robust implementation from common.sh
|
|
if request_sudo_access "$prompt_msg"; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Ensure sudo session is established with keepalive
|
|
# Args: $1 - prompt message
|
|
ensure_sudo_session() {
|
|
local prompt="${1:-Admin access required}"
|
|
|
|
# Check if already established
|
|
if has_sudo_session && [[ "$MOLE_SUDO_ESTABLISHED" == "true" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
# Stop old keepalive if exists
|
|
if [[ -n "$MOLE_SUDO_KEEPALIVE_PID" ]]; then
|
|
_stop_sudo_keepalive "$MOLE_SUDO_KEEPALIVE_PID"
|
|
MOLE_SUDO_KEEPALIVE_PID=""
|
|
fi
|
|
|
|
# Request sudo access
|
|
if ! request_sudo "$prompt"; then
|
|
MOLE_SUDO_ESTABLISHED="false"
|
|
return 1
|
|
fi
|
|
|
|
# Start keepalive
|
|
MOLE_SUDO_KEEPALIVE_PID=$(_start_sudo_keepalive)
|
|
|
|
MOLE_SUDO_ESTABLISHED="true"
|
|
return 0
|
|
}
|
|
|
|
# Stop sudo session and cleanup
|
|
stop_sudo_session() {
|
|
if [[ -n "$MOLE_SUDO_KEEPALIVE_PID" ]]; then
|
|
_stop_sudo_keepalive "$MOLE_SUDO_KEEPALIVE_PID"
|
|
MOLE_SUDO_KEEPALIVE_PID=""
|
|
fi
|
|
MOLE_SUDO_ESTABLISHED="false"
|
|
}
|
|
|
|
# Register cleanup on script exit
|
|
register_sudo_cleanup() {
|
|
trap stop_sudo_session EXIT INT TERM
|
|
}
|
|
|
|
# Check if sudo is likely needed for given operations
|
|
# Args: $@ - list of operations to check
|
|
will_need_sudo() {
|
|
local -a operations=("$@")
|
|
for op in "${operations[@]}"; do
|
|
case "$op" in
|
|
system_update | appstore_update | macos_update | firewall | touchid | rosetta | system_fix)
|
|
return 0
|
|
;;
|
|
esac
|
|
done
|
|
return 1
|
|
}
|