Tuesday, December 27, 2011

Using Fingerprint Scanner on Ubuntu

I recently acquired a new Lenovo W520 which included a biometric fingerprint scanner and since I generally shun windows in favor of Ubuntu 11.10, I really wanted to be able to use the scanner with Ubuntu.

Open Source Sweetness
Setting up the fingerprint reader on Ubuntu was a piece of cake. I just installed this fingerprint application and within seconds I was recording my index finger and using it to unlock my screen saver. It even works with sudo commands, kudos to the guys that put this together!

I think my only gripe, and this seems to be a popular one, is that the gui could use a little polish. So I decided to pull out my C++ skills of yore and see if I could make a few changes - this is open source after all and anyone brave enough can get the code and compile it.

Not So Easy
As with most open source bundles, I found a readme file with directions on how to build the package. Unfortunately that didn't work for me, I ran into a compile error:
In file included from ../../src/MainWindowImpl.cpp:46:0:
../../src/../include/UserSettings.h:30:20: fatal error: QtCrypto: No such file or directory
compilation terminated.
make[2]: *** [MainWindowImpl.o] Error 1
make[2]: Leaving directory `/home/dsixe/Downloads/fingerprint-gui-1.03/bin/fingerprint-gui'
make[1]: *** [sub-fingerprint-gui-make_default] Error 2
make[1]: Leaving directory `/home/dsixe/Downloads/fingerprint-gui-1.03/bin'
make: *** [sub-bin-make_default] Error 2

Taking a look at the makefile in /fingerprint-gui-1.03/bin/fingerprint-gui I found that a reference to QtCrypto was missing, so I added it:
INCPATH       = -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/QtCrypto -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtXml -I/usr/include/qt4 -I. -I../../include -I../../upek/include -I. -I.
Note that for some reason QtCrypto doesn't live in qt4 like the other Qt libraries.

Recompile, now I see:
g++ -m64 -Wl,-O1 -o fingerprint-gui DeviceHandler.o PermissionHandler.o AboutImpl.o ExistDialogImpl.o Fingerprint.o FingerprintData.o UpekDevice.o GenericDevice.o FingerprintGUI.o MainWindowImpl.o SavedDialogImpl.o MessageDialogImpl.o PamTester.o xmlwriter.o UserSettings.o UsbDevice.o moc_DeviceHandler.o moc_AboutImpl.o moc_ExistDialogImpl.o moc_Fingerprint.o moc_FingerprintDevice.o moc_FingerprintData.o moc_MainWindowImpl.o moc_SavedDialogImpl.o moc_MessageDialogImpl.o moc_PamTester.o qrc_GUI-res.o qrc_About-res.o    -L/usr/lib/x86_64-linux-gnu -lusb-1.0 -lfprint -lpam -ldl -lpthread -lQtXml -lQtGui -lQtCore
UserSettings.o: In function `UserSettings::UserSettings(char*)':
UserSettings.cpp:(.text+0x1fcc): undefined reference to `QCA::Cipher::~Cipher()'
UserSettings.cpp:(.text+0x1fd4): undefined reference to `QCA::SecureArray::~SecureArray()'
UserSettings.cpp:(.text+0x1fe1): undefined reference to `QCA::SecureArray::~SecureArray()'
It took me a long time to figure out that it was failing to link in the QtCrypto library. Resolved by adding -lqca to the same makefile:
LIBS          = $(SUBLIBS)  -L/usr/lib/x86_64-linux-gnu -lusb-1.0 -lfprint -lpam -ldl -lpthread -lQtXml -lQtGui -lQtCore -lqca
Finally, a clean compile!

Changing the Image
Now that I could compile the code, I went about making a simple change which didn't really involve altering any code. I wanted to change the animated gif file fingerprint-gui-1.03/src/res/Animation.gif to something else, and this required recompiling. For testing purposes I just converted the existing Fingerprint.png file to a gif and renamed it Animation.gif.

Now all I had to do is run make install and it should work. Once again, not so fast, something wasn't working. I finally just reinstalled clean from the repository and manually copied the file myself:
sudo cp fingerprint-gui-1.03/bin/fingerprint-plugin/fingerprint-plugin /usr/lib/fingerprint-gui/fingerprint-plugin
And now this is what I see when prompted to scan my finger: