{"id":408,"date":"2014-10-07T00:46:12","date_gmt":"2014-10-06T22:46:12","guid":{"rendered":"http:\/\/www.hauweele.net\/~gawen\/blog\/?p=408"},"modified":"2014-11-17T23:58:09","modified_gmt":"2014-11-17T22:58:09","slug":"configure-the-fingerprint-reader-on-freebsd","status":"publish","type":"post","link":"https:\/\/hauweele.net\/~gawen\/blog\/?p=408","title":{"rendered":"Fingerprint reader on FreeBSD"},"content":{"rendered":"<p>This solution is very similar to the way fingerprint readers work under Linux. So if you already\u00a0configured your fingerprint reader on Linux chances are you will find these instructions familiar. However keep in mind than these instructions are for FreeBSD. In particular I did\u00a0this on 11-CURRENT but it should also work on 10-RELEASE.<\/p>\n<p>The\u00a0libfprint library provides the support for the fingerprint readers. In particular it provides drivers for some fingerprint readers (you can find the list on their <a title=\"libfprint\" href=\"http:\/\/www.freedesktop.org\/wiki\/Software\/fprint\/libfprint\/\">website<\/a>), and an API to manipulate the device including the code to enroll\/match a fingerprint. This library uses libusb-1.0 for communication with the device.\u00a0FreeBSD 8 and above already include a reimplementation of this library. This also means that you do not have to enable the device kernel-side. As long as libfprint supports the device and you have access to it (\/dev\/ugen*), it should work.<\/p>\n<p>The pam_fprint module allows you to use your fingerprint reader\u00a0for authentication. When correctly configured, you are asked to swipe your fingerprint across the reader instead of a password prompt. This module relies on libfprint to access the device and reads the fingerprints from your home directory. However\u00a0the sync mechanism used by this module can\u00a0pose problems when multiple applications try to access the device at the same time.<\/p>\n<p>To address this problem the fprintd daemon offers libfprint functionality via D-Bus. In the same way as pam_fprint, this daemon also provides a PAM module, pam_fprintd, for authentication. This module stores the fingerprints into the\u00a0<em>\/var\/lib\/fprint\u00a0<\/em>directory with permission 700. In other words, this directory is not readable\/browsable by other users. Also the fprintd daemon is\u00a0launched\u00a0by D-Bus with root permissions. Since it is this daemon in particular that accesses the device, you do not have to change the permissions for your user to access it.<\/p>\n<p>In this article I will present you both method, the direct direct method through libfprint (pam_fprint) and the D-Bus method through fprintd (pam_fprintd). However I would strongly recommend the D-Bus method as it requires less configuration, it is more reliable and also more secure to my opinion.<\/p>\n<p>Note that an application must use PAM in order to authenticate with the fingerprint reader. Some ports, for example xscreensaver, disable PAM authentication by default. So you need to\u00a0recompile it with PAM enabled as described in a <a title=\"Fingerprint and XScreenSaver\" href=\"http:\/\/www.hauweele.net\/~gawen\/blog\/?p=285\">previous article<\/a>.<\/p>\n<h2>Direct method<\/h2>\n<p>First you need to install the following ports:<\/p>\n<ul>\n<li>security\/libfprint<\/li>\n<li>security\/pam_fprint<\/li>\n<\/ul>\n<p>You may also install security\/fprint_demo which will come up handy to test that your fingerprint reader works correctly with libfprint.<\/p>\n<p>Then you need to ensure that the device is accessible by the users. To do so, we first identify the usb port the fingerprint reader is attached to. Then we create a special group for the users that can access the device. After that\u00a0we create a devfs rule to change the group and permission of the device&#8217;s usb port.<\/p>\n<p>First we identify the usb port of the fingerprint reader:<\/p>\n<pre># usbconfig\r\n...\r\nugen0.3: &lt;Biometric Coprocessor UPEK&gt; at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA)\r\n...<\/pre>\n<p>Now we know it&#8217;s on <em>ugen0.3<\/em>. It&#8217;s time to add a special group for this kind of device:<\/p>\n<pre># pw groupadd fprint\r\n# pw groupmod -m user1,user2,user3\r\n<\/pre>\n<p>In this case, <em>user1<\/em>, <em>user2<\/em> and <em>user3<\/em> will have access to the fingerprint reader and so will be authenticated with their fingerprint. We can tell devfs to change the permission and group of <em>ugen0.3<\/em> to fingerprint and 660. Note that <em>\/dev\/ugen0.3<\/em> is a symlink to <em>\/dev\/usb\/0.3.0<\/em> so we change the group and permission of that file too:<\/p>\n<pre>\/etc\/rc.conf:\r\ndevfs_system_ruleset=\"localrules\"\r\n\r\n\/etc\/devfs.rules:\r\n[localrules=10]\r\nadd path 'ugen0.3' mode 0660 group fprint\r\nadd path 'usb\/0.3.0' mode 0660 group fprint\r\n<\/pre>\n<p>Now we take the changes into account and test that the device is accessible for say <em>user1<\/em>. However to make sure that the changes are enabled on all active session, you may as well just reboot your system:<\/p>\n<pre># service devfs restart\r\n# su user1\r\n$ usbconfig\r\nugen0.3: &lt;Biometric Coprocessor UPEK&gt; at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA)\r\n<\/pre>\n<p>If you installed\u00a0<em>fprint_demo<\/em> you can also test that the fingerprint reader works via libfprint with this command. If it works, it will show the device, in my case <em>&#8220;UPEK Eikon 2&#8221;<\/em>,\u00a0say it\u00a0is ready to use and propose to enroll your fingerprints.<\/p>\n<p>Note this solution is not ideal since the device may not always be attached to the same port. A better solution would be a devd rule that matches the device more precisely.with vendor\/product id. I tried to do so but I&#8217;m still fairly new to devd\u00a0and probably got it wrong. Since I found another method that does not involve changing the permissions, I did not look into this. If someone knows better he&#8217;s welcome to post\u00a0his solution below.<\/p>\n<p>Now that we have access to the device, we can tell PAM to authenticate the users with the fingerprint reader when possible. PAM looks for its modules in <em>\/usr\/lib<\/em>. However pam_fprint installs itself in\u00a0<em>\/usr\/local\/lib<\/em>. To avoid absolute path in the PAM configuration, I create the following symlink <code>\/usr\/lib\/pam_fprint.so -&gt; \/usr\/local\/lib\/pam_fprint.so<\/code>. It&#8217;s time to configure PAM. Most services (slim, xscreensaver, &#8230;) will refer to\u00a0<em>\/etc\/pam.d\/system<\/em> for their PAM configuration, so we only configure this one. We add the pam_fprint module as sufficient to authenticate the user, just before pam_unix (password authentication):<\/p>\n<pre>\/etc\/pam.d\/system:\r\n...\r\n# auth\r\nauth    sufficient   pam_fprint.so\r\nauth    required     pam_unix.so     no_warn try_first_pass nullok local_pass\r\n...<\/pre>\n<p>Now\u00a0we can enroll our fingerprints. You need to do this for each user that will authenticate with the fingerprint reader:<\/p>\n<pre>$ pam_fprint_enroll\r\nThis program will enroll your finger, unconditionally overwriting any selected print that was enrolled previously. If you want to continue, press enter, otherwise hit Ctrl+C\r\n\r\nFound device claimed by UPEK Eikon 2 driver\r\nOpened device. It's now time to enroll your finger.\r\n\r\nYou will need to successfully scan your Right Index Finger 5 times to complete the process.\r\n\r\nScan your finger now.\r\nEnroll stage passed. Yay!\r\n\r\n...\r\n\r\nScan your finger now.\r\nEnroll complete!\r\nEnrollment completed!\r\n<\/pre>\n<p>Finally we can test if everything works correctly. In this case we use sudo to authenticate with our own user:<\/p>\n<pre>$ sudo -i\r\nSwipe your right index finger across the fingerprint reader\r\n#<\/pre>\n<p>If you can do this, it works.<\/p>\n<h2>D-Bus method<\/h2>\n<p>In this method we use the fprintd deamon to access libfprint functionality via D-Bus. To my opinion, this method is simpler, more reliable and more secure than the direct method presented above. The only problems are that the D-Bus daemon is harder to understand and thus debug, also if you have a problem with D-Bus, you are stuck.<\/p>\n<p>First you need to install the following ports:<\/p>\n<ul>\n<li>security\/libfprint<\/li>\n<li>security\/fprintd<\/li>\n<\/ul>\n<p>You do not have to ensure that the device is accessible by the users as the fprintd daemon is launched by D-Bus with root permissions. The only thing we have to do now is to tell PAM to authenticate the users with the fingerprint reader when possible. PAM looks for its modules in <em>\/usr\/lib<\/em>. However fprintd\u00a0installs\u00a0the pam_fprintd module\u00a0in\u00a0<em>\/usr\/local\/lib<\/em>. To avoid absolute path in the PAM configuration, I create the following symlink <code>\/usr\/lib\/pam_fprintd.so -&gt; \/usr\/local\/lib\/pam_fprintd.so<\/code>. It&#8217;s time to configure PAM. Most services (slim, xscreensaver, &#8230;) will refer to\u00a0<em>\/etc\/pam.d\/system<\/em> for their PAM configuration, so we only configure this one. We add the pam_fprintd module as sufficient to authenticate the user, just before pam_unix (password authentication):<\/p>\n<pre>\/etc\/pam.d\/system:\r\n...\r\n# auth\r\nauth    sufficient   pam_fprintd.so\r\nauth    required     pam_unix.so     no_warn try_first_pass nullok local_pass\r\n...<\/pre>\n<p>Now\u00a0we can enroll our fingerprints. You need to do this for each user that will authenticate with the fingerprint reader:<\/p>\n<pre>$ fprintd-enroll\r\nUsing device \/net\/reactivated\/Fprint\/Device\/0\r\nEnrolling right-index-finger finger.\r\nEnroll result: enroll-stage-passed\r\n...\r\nEnroll result: enroll-completed\r\n<\/pre>\n<p>Finally we can test if everything works correctly. In this case we use sudo to authenticate with our own user:<\/p>\n<pre>$ sudo -i\r\nSwipe your right index finger across the fingerprint reader\r\n#<\/pre>\n<p>If you can do this, it works.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This solution is very similar to the way fingerprint readers work under Linux. So if you already\u00a0configured your fingerprint reader on Linux chances are you will find these instructions familiar. However keep in mind than these instructions are for FreeBSD. &hellip; <a href=\"https:\/\/hauweele.net\/~gawen\/blog\/?p=408\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[390,391,433,389,437,438,456,457],"class_list":["post-408","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-fingerprint","tag-fprint","tag-fprintd","tag-freebsd","tag-pam_fprint","tag-pam_fprintd","tag-reader","tag-upek"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/hauweele.net\/~gawen\/blog\/index.php?rest_route=\/wp\/v2\/posts\/408","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hauweele.net\/~gawen\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hauweele.net\/~gawen\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hauweele.net\/~gawen\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hauweele.net\/~gawen\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=408"}],"version-history":[{"count":0,"href":"https:\/\/hauweele.net\/~gawen\/blog\/index.php?rest_route=\/wp\/v2\/posts\/408\/revisions"}],"wp:attachment":[{"href":"https:\/\/hauweele.net\/~gawen\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hauweele.net\/~gawen\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hauweele.net\/~gawen\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}