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 (e.g. Puppet,…)

svn checkout http://nfc-tools.googlecode.com/svn/trunk/nfc-eventd 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 (1.7.0-3 atm in trusty)

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

Next, install some packages and headers for compiling the source

sudo apt-get install devscripts build-essential libnfc-dev debhelper libdbus-1-dev libdbus-glib-1-dev autoconf automake libtool -y

Finally, build the package

autoreconf -vis
debuild -us -uc

Answer this question with yes as the package will be built:

This package has a Debian revision number but there does not seem to be an appropriate original tar file or .orig directory in the parent directory; (expected one of nfc-eventd_0.1.7.orig.tar.gz, nfc-eventd_0.1.7.orig.tar.bz2, nfc-eventd_0.1.7.orig.tar.lzma, nfc-eventd_0.1.7.orig.tar.xz or nfc-eventd.orig) continue anyway? (y/n)

Now we’ve got a deb package to install one folder up.

Installation

Grab the package built above and install it (or add it to your existing repo like freight or reprepro). This command might differ in version numbers and architecture and assumes you’re still in the current pam_nfc directory. Adjust to your needs.

sudo apt-get install ../nfc-eventd_0.1.7-0_amd64.deb

Configuration

As the screensaver 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 ~/nfc-eventd.conf

# 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 = "/usr/local/bin/screen-lock $TAG_UID unlock"
		}
	
		# Tag has been removed
		event tag_remove { 
			on_error = ignore;
			action = "/usr/local/bin/screen-lock $TAG_UID lock"
		}
	
		# Too much time card removed
		event expire_time { 
			on_error = ignore;
			action = "/bin/false";
		}
	}

}

locking script

This one placed in /usr/local/bin/screen-lock is using the existing user-uid mappings file from pam_nfc to check for valid tokens. 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
PAM_NFC_FILE="/etc/pam_nfc.conf"

case $ACTION in
	lock)
		DISPLAY=:0 /usr/bin/cinnamon-screensaver-command -a
	;;

	unlock)
		HASH=$(perl -le 'print crypt("'$NFC_UID'", "RC")')
		if [[ $(grep -Ec '^'$USER'\s'$HASH'' $PAM_NFC_FILE) == "1" ]]; then
		  pgrep cinnamon-screen && DISPLAY=:0 /usr/bin/cinnamon-screensaver-command -d
		else
		  exit 1
		fi
	;;
esac

Do not forget to make it executable:

sudo chmod +x /usr/local/bin/screen-lock

Now, time for a test ride. If everything works out, you can add it to your start programs manager.