Files
Linux-Hello/scripts/install-system.sh
eliott 8c478836d8 feat: ONNX face detection, IR camera support, and PAM authentication
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>
2026-04-02 15:04:52 +02:00

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