-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathyubilock.nix
More file actions
160 lines (137 loc) · 4.89 KB
/
yubilock.nix
File metadata and controls
160 lines (137 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
{ 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
];
};
}