168 lines
4.9 KiB
Nix
168 lines
4.9 KiB
Nix
# Stealed from https://github.com/guttermonk/yubilock
|
|
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.services.yubilock;
|
|
|
|
# Script paths - users should copy scripts to their ~/.config/waybar/scripts/
|
|
yubilockScript = pkgs.writeShellScript "yubilock" ''
|
|
STATE_FILE="$HOME/.cache/yubilock-state"
|
|
LOG_FILE="$HOME/.cache/yubilock.log"
|
|
PID_FILE="$HOME/.cache/yubilock.pid"
|
|
|
|
# Function to check if a YubiKey is currently plugged in
|
|
check_yubikey() {
|
|
if ${pkgs.usbutils}/bin/lsusb | ${pkgs.gnugrep}/bin/grep -i "yubikey" > /dev/null; then
|
|
return 0 # device is present
|
|
else
|
|
return 1 # device is not present
|
|
fi
|
|
}
|
|
|
|
# Function to lock the screen
|
|
lock_screen() {
|
|
# Using loginctl for systemd-based systems
|
|
${pkgs.systemd}/bin/loginctl lock-session
|
|
echo "Screen locked at $(date)" >> "$LOG_FILE"
|
|
}
|
|
|
|
# Create state file if it doesn't exist
|
|
if [ ! -f "$STATE_FILE" ]; then
|
|
echo "off" > "$STATE_FILE"
|
|
fi
|
|
|
|
# Record PID for later termination
|
|
echo "$$" > "$PID_FILE"
|
|
|
|
# Main monitoring loop
|
|
echo "YubiKey monitoring started at $(date)" >> "$LOG_FILE"
|
|
|
|
while true; do
|
|
# Check if monitoring is still enabled
|
|
if [ "$(cat "$STATE_FILE")" != "on" ]; then
|
|
echo "YubiKey monitoring stopped at $(date)" >> "$LOG_FILE"
|
|
exit 0
|
|
fi
|
|
|
|
if check_yubikey; then
|
|
echo "YubiKey detected at $(date)" >> "$LOG_FILE"
|
|
|
|
# Wait until the YubiKey is removed
|
|
while check_yubikey && [ "$(cat "$STATE_FILE")" = "on" ]; do
|
|
sleep 1
|
|
done
|
|
|
|
# If we exited because service was disabled, exit gracefully
|
|
if [ "$(cat "$STATE_FILE")" != "on" ]; then
|
|
echo "YubiKey monitoring stopped at $(date)" >> "$LOG_FILE"
|
|
exit 0
|
|
fi
|
|
|
|
echo "YubiKey removed at $(date)" >> "$LOG_FILE"
|
|
lock_screen
|
|
else
|
|
echo "No YubiKey detected. Checking again in 10 seconds..." >> "$LOG_FILE"
|
|
# Check less frequently to reduce system load
|
|
sleep 10
|
|
fi
|
|
done
|
|
'';
|
|
|
|
yubilockRestoreScript = pkgs.writeShellScript "yubilock-restore" ''
|
|
STATE_FILE="$HOME/.cache/yubilock-state"
|
|
LOG_FILE="$HOME/.cache/yubilock-restore.log"
|
|
|
|
echo "[$(date)] Checking yubilock state on login" >> "$LOG_FILE"
|
|
|
|
# Create state file if it doesn't exist
|
|
if [ ! -f "$STATE_FILE" ]; then
|
|
echo "off" > "$STATE_FILE"
|
|
echo "[$(date)] No state file found, defaulting to off" >> "$LOG_FILE"
|
|
exit 0
|
|
fi
|
|
|
|
# Read the saved state
|
|
saved_state=$(cat "$STATE_FILE")
|
|
echo "[$(date)] Saved state: $saved_state" >> "$LOG_FILE"
|
|
|
|
# If it was enabled before, re-enable it
|
|
if [ "$saved_state" = "on" ]; then
|
|
if ! ${pkgs.systemd}/bin/systemctl --user is-active yubilock.service > /dev/null 2>&1; then
|
|
echo "[$(date)] Restoring yubilock service" >> "$LOG_FILE"
|
|
${pkgs.systemd}/bin/systemctl --user start yubilock.service
|
|
echo "[$(date)] Yubilock service restored" >> "$LOG_FILE"
|
|
else
|
|
echo "[$(date)] Yubilock service already running" >> "$LOG_FILE"
|
|
fi
|
|
fi
|
|
'';
|
|
|
|
in
|
|
{
|
|
options.services.yubilock = {
|
|
enable = mkEnableOption "YubiKey screen lock monitor";
|
|
|
|
autoRestore = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = ''
|
|
Automatically restore yubilock state on login.
|
|
If enabled, the yubilock service will be restarted on login
|
|
if it was running when you last logged out.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
# Systemd user service for yubilock
|
|
systemd.user.services.yubilock = {
|
|
Unit = {
|
|
Description = "YubiKey lock screen monitor";
|
|
After = [ "graphical-session.target" ];
|
|
PartOf = [ "graphical-session.target" ];
|
|
};
|
|
Service = {
|
|
Type = "simple";
|
|
ExecStart = "${yubilockScript}";
|
|
Restart = "on-failure";
|
|
RestartSec = "5s";
|
|
# Ensure state persists
|
|
ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p %h/.cache";
|
|
# Clean state on stop
|
|
ExecStopPost = "${pkgs.bash}/bin/bash -c 'echo off > %h/.cache/yubilock-state'";
|
|
};
|
|
Install = {
|
|
WantedBy = [ "graphical-session.target" ];
|
|
};
|
|
};
|
|
|
|
# Systemd user service to restore yubilock state on login
|
|
systemd.user.services.yubilock-restore = mkIf cfg.autoRestore {
|
|
Unit = {
|
|
Description = "Restore YubiKey monitor state on login";
|
|
After = [ "graphical-session.target" ];
|
|
};
|
|
Service = {
|
|
Type = "oneshot";
|
|
ExecStart = "${yubilockRestoreScript}";
|
|
RemainAfterExit = false;
|
|
};
|
|
Install = {
|
|
WantedBy = [ "graphical-session.target" ];
|
|
};
|
|
};
|
|
|
|
# Ensure required packages are available
|
|
home.packages = with pkgs; [
|
|
usbutils # for lsusb command
|
|
];
|
|
};
|
|
}
|