Wire up ONNX RetinaFace detector and MobileFaceNet embeddings in the CLI and auth pipeline. Add IR camera detection for Windows Hello-style "Integrated I" cameras and greyscale-only format heuristic. Add histogram normalization for underexposed IR frames from low-power emitters. - Add `onnx` feature flag to CLI crate forwarding to daemon - Wire ONNX detector into `detect` command with fallback to simple detector - Fix IR camera detection for Chicony "Integrated I" naming pattern - Add `normalize_if_dark()` for underexposed IR frames in auth pipeline - Load user config from ~/.config/linux-hello/ as fallback - Update systemd service for IR emitter integration and camera access - Add system installation script and ONNX runtime installer - Update .gitignore for local dev artifacts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
208 lines
6.6 KiB
Bash
Executable File
208 lines
6.6 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Linux Hello System Installation
|
|
#
|
|
# Installs the daemon, PAM module, and GDM integration.
|
|
# Run with: sudo ./scripts/install-system.sh
|
|
#
|
|
set -e
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
|
|
# Check root
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo -e "${RED}Run with sudo: sudo $0${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Check binaries exist
|
|
if [ ! -f "$PROJECT_DIR/target/release/linux-hello-daemon" ]; then
|
|
echo -e "${RED}Build first: cargo build --release --features onnx${NC}"
|
|
exit 1
|
|
fi
|
|
if [ ! -f "$PROJECT_DIR/pam-module/pam_linux_hello.so" ]; then
|
|
echo -e "${RED}Build PAM module first: cd pam-module && make${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${GREEN}=== Linux Hello System Installation ===${NC}"
|
|
echo
|
|
|
|
# 1. Install daemon binary
|
|
echo -e "${YELLOW}[1/7] Installing daemon binary...${NC}"
|
|
install -m 755 "$PROJECT_DIR/target/release/linux-hello-daemon" /usr/libexec/linux-hello-daemon
|
|
|
|
# 2. Install CLI binary
|
|
echo -e "${YELLOW}[2/7] Installing CLI binary...${NC}"
|
|
install -m 755 "$PROJECT_DIR/target/release/linux-hello" /usr/local/bin/linux-hello
|
|
|
|
# 3. Install ONNX models
|
|
echo -e "${YELLOW}[3/7] Installing ONNX models...${NC}"
|
|
install -d /usr/share/linux-hello/models
|
|
for model in "$PROJECT_DIR"/models/*.onnx; do
|
|
[ -f "$model" ] && install -m 644 "$model" /usr/share/linux-hello/models/
|
|
done
|
|
|
|
# 4. Install config
|
|
echo -e "${YELLOW}[4/7] Installing config...${NC}"
|
|
install -d /etc/linux-hello
|
|
if [ ! -f /etc/linux-hello/config.toml ]; then
|
|
# Use the user's tested config if available, otherwise use dist default
|
|
REAL_USER="${SUDO_USER:-$USER}"
|
|
USER_CONFIG="/home/$REAL_USER/.config/linux-hello/config.toml"
|
|
if [ -f "$USER_CONFIG" ]; then
|
|
install -m 644 "$USER_CONFIG" /etc/linux-hello/config.toml
|
|
echo " Using tested config from $USER_CONFIG"
|
|
else
|
|
install -m 644 "$PROJECT_DIR/dist/config.toml" /etc/linux-hello/config.toml
|
|
fi
|
|
else
|
|
echo " Config already exists, skipping"
|
|
fi
|
|
|
|
# 5. Install systemd service (with IR emitter integration)
|
|
echo -e "${YELLOW}[5/7] Installing systemd service...${NC}"
|
|
|
|
# Install linux-enable-ir-emitter if built
|
|
IR_EMITTER="/tmp/linux-enable-ir-emitter/target/release/linux-enable-ir-emitter"
|
|
if [ -f "$IR_EMITTER" ]; then
|
|
install -m 755 "$IR_EMITTER" /usr/local/bin/linux-enable-ir-emitter
|
|
# Copy config from the user who ran configure
|
|
REAL_USER="${SUDO_USER:-$USER}"
|
|
IR_CONFIG="/home/$REAL_USER/.config/linux-enable-ir-emitter.toml"
|
|
IR_CONFIG_ROOT="/root/.config/linux-enable-ir-emitter.toml"
|
|
if [ -f "$IR_CONFIG" ]; then
|
|
install -d /etc/linux-hello
|
|
cp "$IR_CONFIG" /etc/linux-hello/ir-emitter.toml
|
|
elif [ -f "$IR_CONFIG_ROOT" ]; then
|
|
install -d /etc/linux-hello
|
|
cp "$IR_CONFIG_ROOT" /etc/linux-hello/ir-emitter.toml
|
|
fi
|
|
fi
|
|
|
|
# Install ONNX runtime env
|
|
REAL_USER="${SUDO_USER:-$USER}"
|
|
ORT_LIB="/home/$REAL_USER/.local/lib/linux-hello/libonnxruntime.so"
|
|
if [ -f "$ORT_LIB" ]; then
|
|
install -d /usr/local/lib/linux-hello
|
|
install -m 755 "$ORT_LIB" /usr/local/lib/linux-hello/libonnxruntime.so
|
|
fi
|
|
|
|
# Create systemd service with IR emitter pre-start
|
|
cat > /etc/systemd/system/linux-hello.service << 'EOF'
|
|
[Unit]
|
|
Description=Linux Hello Face Authentication Daemon
|
|
Documentation=https://github.com/linux-hello/linux-hello
|
|
After=multi-user.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
Environment=ORT_DYLIB_PATH=/usr/local/lib/linux-hello/libonnxruntime.so
|
|
ExecStartPre=-/usr/local/bin/linux-enable-ir-emitter run
|
|
ExecStart=/usr/libexec/linux-hello-daemon
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
# Security hardening
|
|
NoNewPrivileges=true
|
|
ProtectSystem=strict
|
|
ProtectHome=read-only
|
|
PrivateTmp=true
|
|
ProtectKernelTunables=true
|
|
ProtectKernelModules=true
|
|
ProtectControlGroups=true
|
|
RestrictNamespaces=true
|
|
RestrictRealtime=true
|
|
RestrictSUIDSGID=true
|
|
MemoryDenyWriteExecute=false
|
|
LockPersonality=true
|
|
|
|
# Allow access to required devices
|
|
DeviceAllow=/dev/video* rw
|
|
DeviceAllow=/dev/tpm* rw
|
|
DeviceAllow=/dev/tpmrm* rw
|
|
|
|
# Allow network for D-Bus and Unix socket
|
|
RestrictAddressFamilies=AF_UNIX
|
|
|
|
# State directory
|
|
StateDirectory=linux-hello
|
|
RuntimeDirectory=linux-hello
|
|
ConfigurationDirectory=linux-hello
|
|
|
|
# Read access to models
|
|
ReadOnlyPaths=/usr/share/linux-hello
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
systemctl daemon-reload
|
|
|
|
# 6. Install PAM module
|
|
echo -e "${YELLOW}[6/7] Installing PAM module...${NC}"
|
|
PAM_DIR="/lib/x86_64-linux-gnu/security"
|
|
[ ! -d "$PAM_DIR" ] && PAM_DIR="/lib/security"
|
|
install -m 755 "$PROJECT_DIR/pam-module/pam_linux_hello.so" "$PAM_DIR/"
|
|
echo " Installed to $PAM_DIR/pam_linux_hello.so"
|
|
|
|
# 7. Create GDM PAM config (same pattern as gdm-fingerprint)
|
|
echo -e "${YELLOW}[7/7] Creating GDM PAM config...${NC}"
|
|
if [ ! -f /etc/pam.d/gdm-linux-hello ]; then
|
|
cat > /etc/pam.d/gdm-linux-hello << 'EOF'
|
|
#%PAM-1.0
|
|
# Linux Hello Face Authentication for GDM
|
|
# This provides face auth as an alternative to password on the login screen.
|
|
auth requisite pam_nologin.so
|
|
auth required pam_succeed_if.so user != root quiet_success
|
|
auth required pam_linux_hello.so
|
|
auth optional pam_gnome_keyring.so
|
|
@include common-account
|
|
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
|
|
session required pam_loginuid.so
|
|
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
|
|
session optional pam_keyinit.so force revoke
|
|
session required pam_limits.so
|
|
session required pam_env.so readenv=1
|
|
session required pam_env.so readenv=1 user_readenv=1 envfile=/etc/default/locale
|
|
@include common-session
|
|
session optional pam_gnome_keyring.so auto_start
|
|
EOF
|
|
echo " Created /etc/pam.d/gdm-linux-hello"
|
|
else
|
|
echo " /etc/pam.d/gdm-linux-hello already exists, skipping"
|
|
fi
|
|
|
|
# Migrate templates to system path
|
|
echo
|
|
REAL_USER="${SUDO_USER:-$USER}"
|
|
TEMP_TEMPLATES="/tmp/linux-hello-templates"
|
|
SYSTEM_TEMPLATES="/var/lib/linux-hello/templates"
|
|
if [ -d "$TEMP_TEMPLATES" ] && [ "$(ls -A "$TEMP_TEMPLATES" 2>/dev/null)" ]; then
|
|
echo -e "${YELLOW}Migrating enrolled templates...${NC}"
|
|
install -d "$SYSTEM_TEMPLATES"
|
|
cp -r "$TEMP_TEMPLATES"/* "$SYSTEM_TEMPLATES/" 2>/dev/null || true
|
|
echo " Copied templates to $SYSTEM_TEMPLATES"
|
|
fi
|
|
|
|
echo
|
|
echo -e "${GREEN}=== Installation complete ===${NC}"
|
|
echo
|
|
echo "Next steps:"
|
|
echo " 1. Enable and start the daemon:"
|
|
echo " sudo systemctl enable --now linux-hello.service"
|
|
echo
|
|
echo " 2. Verify it's running:"
|
|
echo " systemctl status linux-hello.service"
|
|
echo
|
|
echo " 3. Log out and back in — GDM should show 'Linux Hello' as an auth option"
|
|
echo
|
|
echo " Your password always works as an alternative."
|
|
echo
|