Use clever yubilock
This commit is contained in:
@@ -87,5 +87,9 @@ in
|
|||||||
settings.folders.PhotoArchive.enabled = true;
|
settings.folders.PhotoArchive.enabled = true;
|
||||||
settings.folders.books.enabled = true;
|
settings.folders.books.enabled = true;
|
||||||
};
|
};
|
||||||
|
yubilock = {
|
||||||
|
enable = true;
|
||||||
|
autoRestore = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
167
modules/hm/yubilock.nix
Normal file
167
modules/hm/yubilock.nix
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
# 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
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
services.udev.extraRules = ''
|
|
||||||
ACTION=="remove",\
|
|
||||||
ENV{ID_BUS}=="usb",\
|
|
||||||
ENV{ID_MODEL_ID}=="0407",\
|
|
||||||
ENV{ID_VENDOR_ID}=="1050",\
|
|
||||||
ENV{ID_VENDOR}=="Yubico",\
|
|
||||||
RUN+="${pkgs.systemd}/bin/loginctl lock-sessions"
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user