January 13, 2015

lock/unlock screen using nfc tag and nfc-eventd


UPDATE 2020-04-03

Updating for Ubuntu Focal Fossa 20.04


Instead of having 2 factor auth like in my last blog post, i’d like to lock my screen when leaving the workstation (and take my tag) and unlock when i’m back.

compile and install

Checkout source code and create a debian package for further automated distribution.

docker run --rm -it -v /tmp/:/host --tmpfs /buildroot:exec -w /buildroot ubuntu:focal bash
apt-get update
apt-get install dpkg-dev git-core libnfc-dev autoconf libtool pkg-config debhelper libdbus-1-dev libdbus-glib-1-dev -y
git clone --depth 1 https://github.com/nfc-tools/nfc-eventd

Now we need to adjust some requirements for libraries if we’re using Ubuntu as the debian control file requires libnfc2 (>= 1.5.0) which is not present in Ubuntu. Instead it’s called libnfc5.

cd nfc-eventd
sed -i 's,libnfc2 (>= 1.5.1),libnfc5 (>= 1.7.0),' debian/control

Build the package

autoreconf -vis
dpkg-buildpackage -us -uc

Now we’ve got a deb package to install one folder up which you can copy to your host system:

cp ../nfc-eventd_0.1.7-0_amd64.deb /host
exit # the container
sudo dpkg -i /tmp/nfc-eventd_0.1.7-0_amd64.deb

Configuration

As the screensavers are all running in user context, we can run the daemon there too, so we won’t need to find out who is locking/unlocking the thing.

Instead of using the default config file in /etc/nfc-eventd.conf we’ll create our own in ~/.config/nfc/nfc-eventd.conf (make sure to adjust your NFC device):

# Sample nfc-eventd configuration file
#
nfc-eventd {

	# Run in background? Implies debug=false if true
	daemon = true;

	# show debug messages?
	debug = false;
	
	# polling time in seconds
	polling_time = 1;

	# expire time in seconds
	# default = 0 ( no expire )
	expire_time = 0;
	
	device default {
		driver = "ACR122";
		name = "ACS ACR 38U-CCID 01 00";
	}

	# which device to use ? note: if this part is commented out, nfc-eventd will try to pick up device automagically...
	nfc_device = "default";

	# list of events and actions
	module nem_execute {
		# Tag inserted
		event tag_insert {
			# what to do if an action fail?
			# ignore  : continue to next action
			# return  : end action sequence
			# quit    : end program
			on_error = ignore ;
	
			# You can enter several, comma-separated action entries
			# they will be executed in turn
			action = "~/bin/screen-lock $TAG_UID unlock"
		}
	
		# Tag has been removed
		event tag_remove { 
			on_error = ignore;
			action = "~/bin/screen-lock $TAG_UID lock"
		}
	
		# Too much time card removed
		event expire_time { 
			on_error = ignore;
			action = "/bin/false";
		}
	}

}

locking script

The script ~/bin/screen-lock is just an example which looks up tags ids in a file and unlocks the screenaver if found. My example is controlling cinnamon-screensaver, this might differ for you. You can have a look at more lock/unlock commands here

#!/bin/bash

NFC_UID=$1
ACTION=$2
TOKEN_FILE="$HOME/.config/nfc/tags"
ID="nfc-screensaver-lock"
export DISPLAY=:0

case $ACTION in
	lock)
		/usr/bin/cinnamon-screensaver-command -a
		logger -t $ID "locked screen"
	;;

	unlock)
		if grep -Eq "^${NFC_UID}$" $TOKEN_FILE; then
		  pgrep cinnamon-screen && /usr/bin/cinnamon-screensaver-command -d
		  logger -t $ID "unlocked screen"
		else
		  exit 1
		fi
	;;
esac

Do not forget to make it executable:

sudo chmod +x ~/bin/screen-lock

Now, time for a test ride:

nfc-eventd config_file=~/.config/nfc/nfc-eventd.conf

If everything works out, you can add it to your start programs manager.