Locking the laptop screen is not somthing anyone wants to do manually when they go to get their coffee.
Automating this task with udev rules adds no overhead to the machine and is an easy / fun way to lock the machine. If you choose to use this make sure to lock down the script permissions (chmod 700).
cat /etc/udev/rules.d/99-sec-dev-plug.rules
SUBSYSTEM=="usbmisc", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0010|0110|0111|0114|0116|0401|0403|0405|0407|0410", ACTION=="add", RUN+="/usr/local/bin/secdev.sh"
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0010|0110|0111|0114|0116|0401|0403|0405|0407|0410", ACTION=="remove", RUN+="/usr/local/bin/secdev.sh"
I chose to have two seperate rules one for add and one for removing as I'm using a yubikey. When plugging this device a number of leds, input devices and hid devices are presented, however I found only one usbmisc device. Similarily only one hidraw device on removal.
Using these subsystems ensures the script secdev.sh is only called once.
cat /usr/local/bin/secdev.sh
#!/bin/bash
if [ "$ACTION" == "add" ]; then
echo "Device added"
echo "added $DEVNAME" >> /home/mike/test.out
else
echo "Device removed"
sudo -u mike xflock4
echo "removed $DEVNAME" >> /home/mike/test.out
fi
Now whenever the Yubikey is removed the screensave automatically pops up requiring a password to unlock the terminal. I may look into an auto-unlock based off a HMAC-SHA1 challenge response upon plugin soon. This would reduce the number of times the password is entered and so the number of times people may see the password.
Update Mon 12 Sep 20:11:34 BST 2016
I've updated my scripts for more stability, namley to ignore events when the device removes and re-attaches itself. This is performed when the yubikey performs various tasks like challenge responses.
New udev rules
The new rules are more generic to flood the scripts with more events;
ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0010|0110|0111|0114|0116|0401|0403|0405|0407|0410", ACTION=="add", RUN+="/usr/local/bin/secdev_unlock.sh"
ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0010|0110|0111|0114|0116|0401|0403|0405|0407|0410", ACTION=="remove", RUN+="/usr/local/bin/secdev_lock.sh"
New Unlock Script
I tested auto unlock using challenge response for authentication, however I belive this should be managed by pam rather than any script unlocking the laptop. Instead I've gone with the approach that should the unlock script be triggered it will;
- Prevent the lock script from running at that moment in time
- Bring up the prompt in xscreensaver for login
#!/bin/bash
LOG_FILE="/var/log/secdev.log"
if [ -z "$DEVNAME" ]; then
exit
fi
if [ $(pidof -x $0| wc -w) -gt 2 ]; then
echo "$(date +"%Y-%m-%d %T") One at a time matey... $DEVNAME" >> $LOG_FILE
exit
fi
echo "$(date +"%Y-%m-%d %T") added $DEVNAME" >> $LOG_FILE
#CHAL_RES=$(ykchalresp -2 SECRETCHAL1)
killall secdev_lock.sh
#if [ "$CHAL_RES" == "blabla1" -o "$CHAL_RES" == "blabla2" ]; then
sudo -u mike xscreensaver-command -deactivate
#fi
New Lock Script
The main changes to the lock script is that it is intended to be flooded with udev events, it will ignore a number of events and only lock the screen if a device is missing after two secconds.
#!/bin/bash
LOG_FILE="/var/log/secdev.log"
if [ -z "$DEVNAME" ]; then
exit
fi
if [ $(pidof -x $0| wc -w) -gt 2 ]; then
echo "$(date +"%Y-%m-%d %T") One at a time matey... $DEVNAME" >> $LOG_FILE
exit
fi
echo "$(date +"%Y-%m-%d %T") removed $DEVNAME" >> $LOG_FILE
env >> /home/mike/tmp_rem/rem_$(date +"%s")_$RANDOM
if [ -z "$(ps -ef | grep -v grep | grep -i xscreensaver)" ]; then
echo "$(date +"%Y-%m-%d %T") no xscreensaver..." >> $LOG_FILE
sudo -u mike xscreensaver -no-splash &
sleep 1
fi
sleep 2
if [ -a "/dev/hidraw0" ]; then
echo "$(date +"%Y-%m-%d %T") skip device returned... $DEVNAME" >> $LOG_FILE
exit
fi
echo "$(date +"%Y-%m-%d %T") Locking screen..." >> $LOG_FILE
sudo -u mike xflock4