mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-30 07:37:36 +00:00
macOS never grants Bluetooth to a root launchd daemon: CoreBluetooth answers it Unauthorized whatever the privacy settings say, so the packaged daemon could not use the CoreBluetooth backend at all. When CoreBluetooth refuses the daemon, it listens on ble-agent.sock beside the control socket (/var/run/fips, group fips), and a per-user LaunchAgent runs `fips-ble-agent --ble-agent` in the login session, lending its radio to the daemon over a small framed protocol (io_macos/agent*.rs). Each agent connection that says a valid hello is installed as the radio, replacing the previous one, so the transport is unchanged; a lost agent is a radio switched off. A connection has five seconds to say hello. The agent re-resolves the socket path on every reconnect, so one started before the daemon created its runtime directory does not settle on a fallback path. The agent connects only once its radio is up, and its hello carries the PSM CoreBluetooth published, read afresh for every connection. Before the radio is up `listen` reports only the requested fallback, so a hello sent then told the daemon PSM 133 while the listener was on another, and kept telling it so across reconnects and Bluetooth toggles. fips-ble-agent is a hard link to fips, so Activity Monitor tells the two processes apart. The agent logs to ~/Library/Logs/fips/ble-agent.log, rolled like the daemon's log, rather than to a shared path in /tmp another account could plant a file or symlink in. Install, upgrade and uninstall stop and start the agent in every GUI session, so none keeps running a replaced binary. The agent ends on the stop signal the process holds from the start, so a bootout does not wait out launchd's timeout. The daemon/agent pair is tested end to end over a real Unix socket and MockBleIo on every host: listener PSM, advertising, adverts, dialled and inbound channels both ways, refusal, a lost agent, a connection that never says hello, and an agent whose radio comes up after it starts.
53 lines
1.4 KiB
Bash
Executable File
53 lines
1.4 KiB
Bash
Executable File
#!/bin/sh
|
|
# FIPS uninstall script for macOS
|
|
#
|
|
# Run with: sudo ./uninstall.sh
|
|
set -e
|
|
|
|
PLIST="/Library/LaunchDaemons/com.fips.daemon.plist"
|
|
|
|
# Require root
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
echo "Error: must run as root (sudo $0)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Uninstalling FIPS..."
|
|
|
|
# Stop and unload the service
|
|
if launchctl list com.fips.daemon >/dev/null 2>&1; then
|
|
launchctl unload "$PLIST" 2>/dev/null || true
|
|
echo " Service stopped"
|
|
fi
|
|
|
|
# Remove launchd plist
|
|
rm -f "$PLIST"
|
|
echo " Removed $PLIST"
|
|
|
|
# Stop the BLE agent in every GUI session and remove it
|
|
AGENT="/Library/LaunchAgents/com.fips.ble-agent.plist"
|
|
for AGENT_USER in $(who | awk '$2 == "console" { print $1 }' | sort -u); do
|
|
[ "$AGENT_USER" = "root" ] && continue
|
|
AGENT_UID="$(id -u "$AGENT_USER" 2>/dev/null)" || continue
|
|
launchctl bootout "gui/$AGENT_UID/com.fips.ble-agent" 2>/dev/null || true
|
|
done
|
|
rm -f "$AGENT"
|
|
echo " Removed $AGENT"
|
|
|
|
# Remove DNS resolver
|
|
rm -f /etc/resolver/fips
|
|
dscacheutil -flushcache
|
|
killall -HUP mDNSResponder 2>/dev/null || true
|
|
echo " Removed /etc/resolver/fips"
|
|
|
|
# Remove binaries
|
|
for bin in fips fips-ble-agent fipsctl fipstop; do
|
|
rm -f "/usr/local/bin/$bin"
|
|
done
|
|
echo " Removed binaries from /usr/local/bin/"
|
|
|
|
echo ""
|
|
echo "FIPS uninstalled."
|
|
echo "Config preserved at /usr/local/etc/fips/ (remove manually if desired)"
|
|
echo "Logs preserved at /usr/local/var/log/fips/ (remove manually if desired)"
|