Hello community,
here is the log from the commit of package thinkfinger
checked in at Sat Mar 3 14:37:56 CET 2007.
--------
--- thinkfinger/thinkfinger.changes 2007-02-15 17:41:26.000000000 +0100
+++ /mounts/work_src_done/STABLE/thinkfinger/thinkfinger.changes 2007-03-02 15:27:03.661289000 +0100
@@ -1,0 +2,7 @@
+Fri Mar 2 15:26:18 CET 2007 - thoenig@suse.de
+
+- Fix possible overflow in libthinkfinger (b.n.c #250609)
+- Rework the USB communication to make ThinkFinger compatible with
+ more systems (e.g. Lenovo ThinkPad T43p, b.n.c #250608)
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ thinkfinger.spec ++++++
--- /var/tmp/diff_new_pack.c23368/_old 2007-03-03 14:37:39.000000000 +0100
+++ /var/tmp/diff_new_pack.c23368/_new 2007-03-03 14:37:39.000000000 +0100
@@ -15,7 +15,7 @@
Summary: ThinkFinger driver for the SGS Thomson Microelectronics fingerprint reader
BuildRequires: coreutils libusb pam-devel pkgconfig
Version: 0.2.3
-Release: 1
+Release: 2
License: GNU General Public License (GPL)
Group: System/Libraries
Source0: %{name}-%{version}.tar.bz2
@@ -136,7 +136,11 @@
/%_lib/security/pam_thinkfinger.so
%{_mandir}/*/pam_thinkfinger*
-%changelog -n thinkfinger
+%changelog
+* Fri Mar 02 2007 - thoenig@suse.de
+- Fix possible overflow in libthinkfinger (b.n.c #250609)
+- Rework the USB communication to make ThinkFinger compatible with
+ more systems (e.g. Lenovo ThinkPad T43p, b.n.c #250608)
* Tue Feb 13 2007 - thoenig@suse.de
- Use uinput to send a synthetic carriage return after swipe rather
than killing the thread which resides in pam_prompt (b.n.c
++++++ thinkfinger-0.2.3.tar.bz2 ++++++
++++ 3930 lines of diff (skipped)
++++ retrying with extended exclude list
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/thinkfinger-0.2.3/configure.in new/thinkfinger-0.2.3/configure.in
--- old/thinkfinger-0.2.3/configure.in 2007-02-13 14:53:49.000000000 +0100
+++ new/thinkfinger-0.2.3/configure.in 2007-02-27 15:30:21.000000000 +0100
@@ -23,7 +23,7 @@
################################################################################
# Initialize auto{conf,make}
-AC_PREREQ(2.61)
+AC_PREREQ(2.59)
AC_INIT([ThinkFinger],[0.2.3],[http://thinkfinger.sourceforge.net/],[thinkfinger])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE
@@ -40,7 +40,7 @@
# AC_ARG_ENABLE PAM
AC_MSG_CHECKING([whether to build the pluggable authentication module (PAM)])
-AC_ARG_ENABLE(pam, AS_HELP_STRING([--enable-pam],[build PAM module]),enable_pam=$enableval,enable_pam=yes)
+AC_ARG_ENABLE(pam, AC_HELP_STRING([--enable-pam],[build PAM module]),enable_pam=$enableval,enable_pam=yes)
AC_MSG_RESULT([$enable_pam])
if test "x$enable_pam" != "xno"; then
@@ -51,7 +51,6 @@
AC_CHECK_LIB(pam, pam_prompt, , HAVE_OLD_PAM=yes
AC_DEFINE(HAVE_OLD_PAM,1,
[Defined if pam_prompt function does not exist in libpam]))
- AM_CONDITIONAL(HAVE_OLD_PAM, test "x$HAVE_OLD_PAM" = "xyes")
# Check for Linux input and uinput headers
AC_CHECK_HEADER(linux/input.h, HAVE_LINUX_INPUT=1,,)
@@ -67,13 +66,13 @@
fi
# AC_ARG_ENABLE SECUREDIR
-AC_ARG_ENABLE(securedir, AS_HELP_STRING([--with-securedir=dir],[Where to put PAM module @<:@default=$libdir/security@:>@]))
+AC_ARG_ENABLE(securedir, AC_HELP_STRING([--with-securedir=dir],[Where to put PAM module @<:@default=$libdir/security@:>@]))
# AC_ARG_ENABLE_BIR_DIR
-AC_ARG_ENABLE(birdir, AS_HELP_STRING([--with-birdir=dir],[Where to put the biometric identification records (bir files) @<:@default=$sysconfdir/pam_thinkfinger@:>@]))
+AC_ARG_ENABLE(birdir, AC_HELP_STRING([--with-birdir=dir],[Where to put the biometric identification records (bir files) @<:@default=$sysconfdir/pam_thinkfinger@:>@]))
# Check for libusb using pkg-config
-PKG_CHECK_MODULES(USB, libusb >= 0.1.12, usb_found=yes, AC_MSG_ERROR([libusb missing]))
+PKG_CHECK_MODULES(USB, libusb >= 0.1.11, usb_found=yes, AC_MSG_ERROR([libusb missing]))
# Check for Doxygen
AC_CHECK_PROG(DOXYGEN, [doxygen], [doxygen], [])
@@ -165,6 +164,7 @@
# AM_CONDITIONAL
AM_CONDITIONAL(BUILD_PAM, test "x$enable_pam" = "xyes")
+AM_CONDITIONAL(HAVE_OLD_PAM, test "x$HAVE_OLD_PAM" = "xyes")
# AC_CONFIG_FILES
AC_CONFIG_FILES([Makefile
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/thinkfinger-0.2.3/docs/pam_thinkfinger.8 new/thinkfinger-0.2.3/docs/pam_thinkfinger.8
--- old/thinkfinger-0.2.3/docs/pam_thinkfinger.8 2007-02-05 12:27:12.000000000 +0100
+++ new/thinkfinger-0.2.3/docs/pam_thinkfinger.8 2007-03-01 15:05:13.000000000 +0100
@@ -1,13 +1,15 @@
.\" -*- nroff -*-
.\" Copyright (C) 2007 Luca Capello
+.\" 2007 Jose Plans
+.\" 2007 Timo Hoenig
.\"
-.TH PAM_THINKFINGER 8 "Feb 1, 2007"
+.TH PAM_THINKFINGER 8 "Feb 27, 2007"
-.SH NAME
+.SH "NAME"
pam_thinkfinger - PAM module for fingerprint authentication through
libthinkfinger
-.SH DESCRIPTION
+.SH "DESCRIPTION"
ThinkFinger is a driver for the UPEK/SGS Thomson Microelectronics
fingerprint reader (USB ID 0483:2016). The device is being found
either as a standalone USB device, built into USB keyboards or built
@@ -18,7 +20,36 @@
libthinkfinger. The module does only trigger for users which have
deposited their fingerprint in the \fI/etc/pam_thinkfinger\fP folder.
-.SH FILES
+.SH "OPTIONS"
+.PD 0
+.TP
+debug
+Turns on debugging via \fBsyslog\fR(3)
+
+.SH "REQUIREMENTS"
+.PD 0
+In order to use the the PAM module pam_thinkfinger your Linux kernel has to be
+compiled with uinput support (CONFIG_INPUT_UINPUT). The location of the uinput
+interface depends on your distribution. To ensure that your system is properly
+set up, one of the following interfaces have to exist:
+
+.TP
+.I /dev/input/uinput
+.TP
+.I /dev/misc/uinput
+.TP
+.I /dev/uinput
+
+.TP
+If the interface is not there, run:
+
+.TP
+$ modprobe uinput
+
+.TP
+Ask your the maintainers of your distribution to automatically load the module.
+
+.SH "FILES"
.PD 0
.TP
.I /etc/pam_thinkfinger
@@ -27,20 +58,36 @@
.I /lib/security
The default folder for PAM modules
-.SH BUGS
+.SH "EXAMPLES"
+.PP
+Add the following line to \fI/etc/pam.d/common-auth\fR:
+.sp
+.nf
+sufficient auth pam_thinkfinger.so
+.fi
+.sp
+To enable debugging support via \fBsyslog\fR(3), add the following line to \fI/etc/pam.d/common-auth\fR:
+.sp
+.nf
+sufficient auth pam_thinkfinger.so debug
+.fi
+.sp
+
+.SH "BUGS"
Please report bugs to .
-.SH SEE ALSO
+.SH "SEE ALSO"
.BR tf-tool (1),
.BR pam (8)
.BR \fIhttp://thinkfinger.sourceforge.net/\fP
-.SH AUTHORS
+.SH "AUTHORS"
ThinkFinger was written by Timo Hoenig and Pavel
Machek and is licensed under the terms of the GNU
General Public License (GPL).
-This manual page was written by Luca Capello .
+This manual page was written by Luca Capello . Additions
+by Jose Plans.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU General Public License (GPL).
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/thinkfinger-0.2.3/INSTALL new/thinkfinger-0.2.3/INSTALL
--- old/thinkfinger-0.2.3/INSTALL 2007-02-01 12:04:06.000000000 +0100
+++ new/thinkfinger-0.2.3/INSTALL 2007-03-01 15:04:50.000000000 +0100
@@ -18,6 +18,24 @@
- doxygen (http://www.stack.nl/~dimitri/doxygen/)
+Kernel Requirements
+===================
+
+In order to use the the PAM module pam_thinkfinger your Linux kernel has to be
+compiled with uinput support (CONFIG_INPUT_UINPUT). The location of the uinput
+interface depends on your distribution. To ensure that your system is properly
+set up, one of the following interfaces have to exist:
+
+ * /dev/input/uinput
+ * /dev/misc/uinput
+ * /dev/uinput
+
+If the interface is not there, run:
+
+ $ modprobe uinput
+
+Ask your the maintainers of your distribution to automatically load the module.
+
Installation Steps
==================
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/thinkfinger-0.2.3/libthinkfinger/libthinkfinger.c new/thinkfinger-0.2.3/libthinkfinger/libthinkfinger.c
--- old/thinkfinger-0.2.3/libthinkfinger/libthinkfinger.c 2007-02-14 12:34:43.000000000 +0100
+++ new/thinkfinger-0.2.3/libthinkfinger/libthinkfinger.c 2007-03-01 19:54:43.000000000 +0100
@@ -42,8 +42,8 @@
#define VENDOR_ID 0x0483
#define PRODUCT_ID 0x2016
-#define USB_TIMEOUT 1000
-#define USB_RETRY 100
+#define USB_TIMEOUT 250
+#define USB_RETRY 250
#define USB_DELAY 100 * USB_TIMEOUT
static char init_a[17] = {
@@ -76,6 +76,10 @@
0x00, 0x00, 0x6d, 0x7e
};
+static char init_f[6] = {
+ 0x43, 0x69, 0x61, 0x6f, 0x00, 0x40
+};
+
struct init_table {
char *data;
size_t len;
@@ -87,10 +91,11 @@
{ init_c, sizeof (init_c) },
{ init_d, sizeof (init_d) },
{ init_e, sizeof (init_e) },
+ { init_f, sizeof (init_f) },
{ 0x0, 0x0 }
};
-static char ctrlbuf [1024] = {
+static char ctrlbuf[1024] = {
0x43, 0x69, 0x61, 0x6f, 0x00, 0x51, 0x0b, 0x28,
0xb8, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -98,28 +103,34 @@
0x00, 0x00, 0x03
};
-static char enroll_init [23] = {
+static char enroll_init[23] = {
0x43, 0x69, 0x61, 0x6f, 0x00, 0x50, 0x0e, 0x28,
0x0b, 0x00, 0x00, 0x00, 0x02, 0x02, 0xc0, 0xd4,
0x01, 0x00, 0x04, 0x00, 0x08, 0x0f, 0x86
};
-static char scan_sequence_one [17] = {
+static char scan_sequence_a[17] = {
0x43, 0x69, 0x61, 0x6f, 0x00, 0x60, 0x08, 0x28,
0x05, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x49,
0x6b
};
-static char scan_sequence_two [17] = {
+static char scan_sequence_b[17] = {
+ 0x43, 0x69, 0x61, 0x6f, 0x00, 0x70, 0x08, 0x28,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xdf,
+ 0xff
+};
+
+static char scan_sequence_c[17] = {
0x43, 0x69, 0x61, 0x6f, 0x00, 0x80, 0x08, 0x28,
0x05, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x6a,
0xc4
};
struct libthinkfinger_s {
- struct usb_dev_handle *usb_handle;
+ struct usb_dev_handle *usb_dev_handle;
const char *file;
- int fd, usb_retval;
+ int fd;
_Bool write_fingerprint;
libthinkfinger_task task;
@@ -201,18 +212,16 @@
}
-static void
-_libthinkfinger_usb_deinit (libthinkfinger *tf)
+static void _libthinkfinger_usb_deinit (libthinkfinger *tf)
{
- if (tf->usb_handle) {
- usb_release_interface (tf->usb_handle, 0);
- usb_close (tf->usb_handle);
+ if (tf->usb_dev_handle) {
+ usb_release_interface (tf->usb_dev_handle, 0);
+ usb_close (tf->usb_dev_handle);
}
- tf->usb_handle = NULL;
+ tf->usb_dev_handle = NULL;
}
-static libthinkfinger_init_status
-_libthinkfinger_usb_init (libthinkfinger *tf)
+static libthinkfinger_init_status _libthinkfinger_usb_init (libthinkfinger *tf)
{
libthinkfinger_init_status retval = TF_INIT_UNDEFINED;
struct usb_device *usb_dev;
@@ -225,18 +234,18 @@
goto out;
}
- tf->usb_handle = usb_open (usb_dev);
- if (tf->usb_handle == NULL) {
+ tf->usb_dev_handle = usb_open (usb_dev);
+ if (tf->usb_dev_handle == NULL) {
retval = TF_INIT_USB_OPEN_FAILED;
goto out;
}
- if (usb_claim_interface (tf->usb_handle, 0) < 0) {
+ if (usb_claim_interface (tf->usb_dev_handle, 0) < 0) {
retval = TF_INIT_USB_CLAIM_FAILED;
goto out;
}
- if (_libthinkfinger_usb_hello (tf->usb_handle) < 0) {
+ if (_libthinkfinger_usb_hello (tf->usb_dev_handle) < 0) {
retval = TF_INIT_USB_HELLO_FAILED;
goto out;
}
@@ -247,11 +256,10 @@
return retval;
}
-static void
-_libthinkfinger_parse_scan_reply (libthinkfinger *tf, unsigned char *inbuf)
+static void _libthinkfinger_parse_scan_reply (libthinkfinger *tf, unsigned char *inbuf)
{
if (tf == NULL) {
- printf ("Error: libthinkfinger not properly initialized.\n");
+ fprintf (stderr, "Error: libthinkfinger not properly initialized.\n");
goto out;
}
@@ -286,7 +294,7 @@
break;
default:
#ifdef LIBTHINKFINGER_DEBUG
- printf ("Unknown state 0x%x\n", inbuf[18]);
+ fprintf (stderr, "Unknown state 0x%x\n", inbuf[18]);
#endif
break;
}
@@ -295,13 +303,12 @@
return;
}
-static int
-_libthinkfinger_store_fingerprint (libthinkfinger *tf, unsigned char *data)
+static int _libthinkfinger_store_fingerprint (libthinkfinger *tf, unsigned char *data)
{
int retval = -1;
if ((tf == NULL) || (tf->fd < 0)) {
- printf ("Error: libthinkfinger not properly initialized.\n");
+ fprintf (stderr, "Error: libthinkfinger not properly initialized.\n");
goto out;
}
@@ -317,8 +324,7 @@
}
/* returns 1 if it understood the packet */
-static int
-_libthinkfinger_parse (libthinkfinger *tf, unsigned char *inbuf)
+static int _libthinkfinger_parse (libthinkfinger *tf, unsigned char *inbuf)
{
int retval = -1;
@@ -329,7 +335,7 @@
};
if (tf == NULL) {
- printf ("Error: libthinkfinger not properly initialized.\n");
+ fprintf (stderr, "Error: libthinkfinger not properly initialized.\n");
goto out;
}
@@ -350,12 +356,12 @@
break;
case 0x13:
switch (inbuf[14]) {
- case 0x00:
- tf->state = TF_STATE_VERIFY_FAILED;
- break;
- case 0x01:
- tf->state = TF_STATE_VERIFY_SUCCESS;
- break;
+ case 0x00:
+ tf->state = TF_STATE_VERIFY_FAILED;
+ break;
+ case 0x01:
+ tf->state = TF_STATE_VERIFY_SUCCESS;
+ break;
}
break;
case 0x14:
@@ -380,14 +386,13 @@
#define SILENT 1
#define PARSE 2
-static void
-_libthinkfinger_ask_scanner_raw (libthinkfinger *tf, int flags, char *ctrldata, int len)
+static void _libthinkfinger_ask_scanner_raw (libthinkfinger *tf, int flags, char *ctrldata, int len)
{
int usb_retval;
unsigned char inbuf[10240];
if (tf == NULL) {
- printf ("Error: libthinkfinger not properly initialized.\n");
+ fprintf (stderr, "Error: libthinkfinger not properly initialized.\n");
goto out;
}
@@ -395,7 +400,7 @@
goto out;
}
- usb_retval = usb_bulk_read (tf->usb_handle, 0x01, (char *) inbuf, 0x40, USB_TIMEOUT);
+ usb_retval = usb_bulk_read (tf->usb_dev_handle, 0x01, (char *) inbuf, 0x40, USB_TIMEOUT);
if (usb_retval < 0 && usb_retval != -ETIMEDOUT) {
tf->state = TF_STATE_USB_ERROR;
goto out_result;
@@ -419,7 +424,7 @@
*((short *) (ctrldata+len-2)) = udf_crc ((u8*)&(ctrldata[4]), len-6, 0);
- usb_retval = usb_bulk_write (tf->usb_handle, 0x02, (char *) ctrldata, len, USB_TIMEOUT);
+ usb_retval = usb_bulk_write (tf->usb_dev_handle, 0x02, (char *) ctrldata, len, USB_TIMEOUT);
if (usb_retval < 0 && usb_retval != -ETIMEDOUT) {
tf->state = TF_STATE_USB_ERROR;
goto out_result;
@@ -444,8 +449,7 @@
return;
}
-static libthinkfinger_init_status
-_libthinkfinger_init (libthinkfinger *tf)
+static libthinkfinger_init_status _libthinkfinger_init (libthinkfinger *tf)
{
libthinkfinger_init_status retval = TF_INIT_UNDEFINED;
int i = 0;
@@ -460,21 +464,17 @@
} while (init[++i].data);
_libthinkfinger_task_stop (tf);
- retval = _libthinkfinger_usb_init (tf);
- if (retval != TF_INIT_USB_INIT_SUCCESS)
- goto out;
-
retval = TF_INIT_SUCCESS;
out:
return retval;
}
-static int
-_libthinkfinger_verify_run (libthinkfinger *tf)
+static int _libthinkfinger_verify_run (libthinkfinger *tf)
{
int retval = -1;
int header = 13*3-1;
int filesize;
+ libthinkfinger_init_status init_status;
tf->fd = open (tf->file, O_RDONLY);
if (tf->fd < 0) {
@@ -489,15 +489,19 @@
ctrlbuf[6] = (filesize+20511) & 0xff;
ctrlbuf[header+filesize] = 0x4f;
ctrlbuf[header+filesize+1] = 0x47;
-
- if (_libthinkfinger_init (tf) != TF_INIT_SUCCESS)
+
+ init_status = _libthinkfinger_init (tf);
+ if (init_status != TF_INIT_SUCCESS) {
+ tf->state = TF_STATE_USB_ERROR;
goto out_close;
+ }
_libthinkfinger_task_start (tf, TF_TASK_VERIFY);
_libthinkfinger_ask_scanner_raw (tf, 0, ctrlbuf, header+filesize+2);
while (_libthinkfinger_task_running (tf) == true) {
- _libthinkfinger_ask_scanner_raw (tf, PARSE, scan_sequence_one, sizeof(scan_sequence_one));
- _libthinkfinger_ask_scanner_raw (tf, PARSE, scan_sequence_two, sizeof(scan_sequence_two));
+ _libthinkfinger_ask_scanner_raw (tf, PARSE, scan_sequence_a, sizeof(scan_sequence_a));
+ _libthinkfinger_ask_scanner_raw (tf, PARSE, scan_sequence_b, sizeof(scan_sequence_b));
+ _libthinkfinger_ask_scanner_raw (tf, PARSE, scan_sequence_c, sizeof(scan_sequence_c));
}
_libthinkfinger_task_stop (tf);
@@ -511,15 +515,14 @@
return retval;
}
-libthinkfinger_result
-libthinkfinger_verify (libthinkfinger *tf)
+libthinkfinger_result libthinkfinger_verify (libthinkfinger *tf)
{
libthinkfinger_result retval = TF_RESULT_UNDEFINED;
int usb_retry = USB_RETRY;
int result_pending;
if (tf == NULL) {
- printf ("Error: libthinkfinger not properly initialized.\n");
+ fprintf (stderr, "Error: libthinkfinger not properly initialized.\n");
goto out;
}
@@ -553,10 +556,10 @@
return retval;
}
-static int
-_libthinkfinger_acquire_run (libthinkfinger *tf)
+static int _libthinkfinger_acquire_run (libthinkfinger *tf)
{
int retval = -1;
+ libthinkfinger_init_status init_status;
tf->fd = open (tf->file, O_RDWR | O_CREAT, 0600);
if (tf->fd < 0) {
@@ -564,14 +567,18 @@
goto out;
}
- if (_libthinkfinger_init (tf) != TF_INIT_SUCCESS)
+ init_status = _libthinkfinger_init (tf);
+ if (init_status != TF_INIT_SUCCESS) {
+ tf->state = TF_STATE_USB_ERROR;
goto out_close;
+ }
_libthinkfinger_task_start (tf, TF_TASK_ACQUIRE);
_libthinkfinger_ask_scanner_raw (tf, SILENT, enroll_init, sizeof(enroll_init));
while (_libthinkfinger_task_running (tf) == true) {
- _libthinkfinger_ask_scanner_raw (tf, PARSE, scan_sequence_one, sizeof(scan_sequence_one));
- _libthinkfinger_ask_scanner_raw (tf, PARSE, scan_sequence_two, sizeof(scan_sequence_two));
+ _libthinkfinger_ask_scanner_raw (tf, PARSE, scan_sequence_a, sizeof(scan_sequence_a));
+ _libthinkfinger_ask_scanner_raw (tf, PARSE, scan_sequence_b, sizeof(scan_sequence_b));
+ _libthinkfinger_ask_scanner_raw (tf, PARSE, scan_sequence_c, sizeof(scan_sequence_c));
}
_libthinkfinger_task_stop (tf);
@@ -585,13 +592,12 @@
return retval;
}
-libthinkfinger_result
-libthinkfinger_acquire (libthinkfinger *tf)
+libthinkfinger_result libthinkfinger_acquire (libthinkfinger *tf)
{
libthinkfinger_result retval = TF_RESULT_UNDEFINED;
if (tf == NULL) {
- printf ("Error: libthinkfinger not properly initialized.\n");
+ fprintf (stderr, "Error: libthinkfinger not properly initialized.\n");
goto out;
}
@@ -617,13 +623,12 @@
return retval;
}
-int
-libthinkfinger_set_file (libthinkfinger *tf, const char *file)
+int libthinkfinger_set_file (libthinkfinger *tf, const char *file)
{
int retval = -1;
if (tf == NULL) {
- printf ("Error: libthinkfinger not properly initialized.\n");
+ fprintf (stderr, "Error: libthinkfinger not properly initialized.\n");
goto out;
}
@@ -633,13 +638,12 @@
return retval;
}
-int
-libthinkfinger_set_callback (libthinkfinger *tf, libthinkfinger_state_cb cb, void *cb_data)
+int libthinkfinger_set_callback (libthinkfinger *tf, libthinkfinger_state_cb cb, void *cb_data)
{
int retval = -1;
if (tf == NULL) {
- printf ("Error: libthinkfinger not properly initialized.\n");
+ fprintf (stderr, "Error: libthinkfinger not properly initialized.\n");
goto out;
}
@@ -650,8 +654,7 @@
return retval;
}
-libthinkfinger *
-libthinkfinger_new (libthinkfinger_init_status *init_status)
+libthinkfinger *libthinkfinger_new (libthinkfinger_init_status *init_status)
{
libthinkfinger *tf = NULL;
@@ -663,7 +666,7 @@
goto out;
}
- tf->usb_handle = NULL;
+ tf->usb_dev_handle = NULL;
tf->file = NULL;
tf->fd = -1;
tf->write_fingerprint = false;
@@ -678,14 +681,17 @@
return tf;
}
-void
-libthinkfinger_free (libthinkfinger *tf)
+void libthinkfinger_free (libthinkfinger *tf)
{
if (tf == NULL) {
- printf ("Error: libthinkfinger not properly initialized.\n");
+ fprintf (stderr, "Error: libthinkfinger not properly initialized.\n");
goto out;
}
+ /* If the scanner is waiting for a swipe we have to ask the device to reinitialize. Otherwise it gets hot. */
+ if (tf->state == TF_STATE_SWIPE_0 || tf->state == TF_STATE_SWIPE_1 || tf->state == TF_STATE_SWIPE_2)
+ usb_bulk_write (tf->usb_dev_handle, 0x02, (char *) init[0].data, init[0].len, USB_TIMEOUT);
+
_libthinkfinger_usb_deinit (tf);
if (tf->fd)
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/thinkfinger-0.2.3/libthinkfinger/libthinkfinger.h new/thinkfinger-0.2.3/libthinkfinger/libthinkfinger.h
--- old/thinkfinger-0.2.3/libthinkfinger/libthinkfinger.h 2007-02-13 17:08:02.000000000 +0100
+++ new/thinkfinger-0.2.3/libthinkfinger/libthinkfinger.h 2007-02-27 13:33:13.000000000 +0100
@@ -82,7 +82,7 @@
TF_STATE_VERIFY_FAILED = 0x0b, // verification failed
TF_STATE_USB_ERROR = 0xfd, // USB error
TF_STATE_COMM_FAILED = 0xfe, // communication error
- TF_STATE_UNDEFINED = 0xff // undefined
+ TF_STATE_UNDEFINED = 0xff // undefined
} libthinkfinger_state;
typedef enum {
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/thinkfinger-0.2.3/pam/Makefile.am new/thinkfinger-0.2.3/pam/Makefile.am
--- old/thinkfinger-0.2.3/pam/Makefile.am 2007-02-12 15:11:29.000000000 +0100
+++ new/thinkfinger-0.2.3/pam/Makefile.am 2007-02-27 13:32:18.000000000 +0100
@@ -1,14 +1,12 @@
-INSTALL_PROGRAM= @INSTALL_PROGRAM@ -m 644
-
pam_PROGRAMS = pam_thinkfinger.so
pamdir = $(SECUREDIR)
INCLUDES = -I$(top_srcdir)/libthinkfinger
if HAVE_OLD_PAM
-pam_thinkfinger_so_SOURCES = pam_thinkfinger-compat.c pam_thinkfinger-compat.h pam_thinkfinger-uinput.c pam_thinkfinger-uinput.h pam_thinkfinger.c
+pam_thinkfinger_so_SOURCES = pam_thinkfinger-compat.c pam_thinkfinger-compat.h pam_thinkfinger-uinput.c pam_thinkfinger-uinput.h pam_thinkfinger.c
else
-pam_thinkfinger_so_SOURCES = pam_thinkfinger-uinput.c pam_thinkfinger-uinput.h pam_thinkfinger.c
+pam_thinkfinger_so_SOURCES = pam_thinkfinger-uinput.c pam_thinkfinger-uinput.h pam_thinkfinger.c
endif
pam_thinkfinger_so_LDFLAGS = -shared --strip-all -Wl,-soname,pam_thinkfinger.so -Wl,--as-needed
pam_thinkfinger_so_CFLAGS = $(CFLAGS)
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/thinkfinger-0.2.3/pam/pam_thinkfinger.c new/thinkfinger-0.2.3/pam/pam_thinkfinger.c
--- old/thinkfinger-0.2.3/pam/pam_thinkfinger.c 2007-02-14 12:28:19.000000000 +0100
+++ new/thinkfinger-0.2.3/pam/pam_thinkfinger.c 2007-03-02 14:40:58.000000000 +0100
@@ -27,6 +27,7 @@
#include
#include
+#include
#include
#include
#include
@@ -38,11 +39,14 @@
#include
#endif
-#define MAX_PATH 256
+#define MAX_PATH 256
#define PAM_SM_AUTH
+#define PAM_TF_MODULE "pam_thinkfinger"
-struct pam_thinkfinger_s {
+volatile static int pam_tf_debug = 0;
+
+typedef struct {
libthinkfinger *tf;
const char *user;
pthread_t t_pam_prompt;
@@ -52,18 +56,49 @@
int isatty;
int uinput_fd;
pam_handle_t *pamh;
-};
+} pam_thinkfinger_s;
+
+static void pam_thinkfinger_log (const pam_thinkfinger_s *pam_thinkfinger, int type, const char *format, ...)
+{
+ char message[LINE_MAX];
+ va_list ap;
+
+ if (pam_tf_debug) {
+ va_start (ap, format);
+ vsnprintf (message, sizeof(message), format, ap);
+ va_end(ap);
+ pam_syslog (pam_thinkfinger->pamh, type, message);
+ }
+}
+
+static void pam_thinkfinger_options (const pam_thinkfinger_s *pam_thinkfinger, int argc, const char **argv)
+{
+ int i;
-static int pam_thinkfinger_check_user (const char *user)
+ for (i = 0; i < argc; i++) {
+ if (!strcmp(argv[i], "debug"))
+ pam_tf_debug = 1;
+ else if (!strcmp(argv[i], " ") || !strcmp(argv[i], "\t"))
+ continue;
+ else
+ pam_thinkfinger_log (pam_thinkfinger, LOG_INFO,
+ "Option '%s' is not recognised or not yet supported.", *(argv+i));
+ }
+}
+
+static int pam_thinkfinger_check_user (const pam_thinkfinger_s *pam_thinkfinger)
{
int retval = -1;
int fd;
char bir_file[MAX_PATH];
- snprintf (bir_file, MAX_PATH-1, "%s/%s.bir", PAM_BIRDIR, user);
+ snprintf (bir_file, MAX_PATH-1, "%s/%s.bir", PAM_BIRDIR, pam_thinkfinger->user);
fd = open (bir_file, O_RDONLY);
- if (fd == -1)
+ if (fd == -1) {
+ pam_thinkfinger_log (pam_thinkfinger, LOG_ERR,
+ "Could not open '%s/%s.bir'.", PAM_BIRDIR, pam_thinkfinger->user);
goto out;
+ }
retval = 0;
close (fd);
@@ -72,7 +107,7 @@
return retval;
}
-static libthinkfinger_state pam_thinkfinger_verify (const struct pam_thinkfinger_s *pam_thinkfinger)
+static libthinkfinger_state pam_thinkfinger_verify (const pam_thinkfinger_s *pam_thinkfinger)
{
libthinkfinger_state tf_state = TF_STATE_VERIFY_FAILED;
char bir_file[MAX_PATH];
@@ -91,38 +126,44 @@
static void thinkfinger_thread (void *data)
{
- struct pam_thinkfinger_s *pam_thinkfinger = data;
+ int ret;
+ pam_thinkfinger_s *pam_thinkfinger = data;
libthinkfinger_state tf_state;
+ pam_thinkfinger_log (pam_thinkfinger, LOG_NOTICE, "%s called.", __FUNCTION__);
+
pam_thinkfinger->swipe_retval = PAM_SERVICE_ERR;
tf_state = pam_thinkfinger_verify (pam_thinkfinger);
if (tf_state == TF_RESULT_VERIFY_SUCCESS) {
pam_thinkfinger->swipe_retval = PAM_SUCCESS;
- pam_syslog (pam_thinkfinger->pamh, LOG_NOTICE,
- "%s authenticated (biometric identification record matched)",
- pam_thinkfinger->user);
+ pam_thinkfinger_log (pam_thinkfinger, LOG_NOTICE,
+ "User '%s' authenticated (biometric identification record matched).", pam_thinkfinger->user);
} else if (tf_state == TF_RESULT_VERIFY_FAILED) {
pam_thinkfinger->swipe_retval = PAM_AUTH_ERR;
- pam_syslog (pam_thinkfinger->pamh, LOG_NOTICE,
- "%s verication failed (biometric identification record not matched)",
- pam_thinkfinger->user);
+ pam_thinkfinger_log (pam_thinkfinger, LOG_NOTICE,
+ "User '%s' verification failed (biometric identification record not matched).",
+ pam_thinkfinger->user);
} else {
pam_thinkfinger->swipe_retval = PAM_AUTH_ERR;
- pam_syslog (pam_thinkfinger->pamh, LOG_NOTICE,
- "%s verication failed (0x%x)",
- pam_thinkfinger->user, tf_state);
+ pam_thinkfinger_log (pam_thinkfinger, LOG_NOTICE,
+ "User '%s' verification failed (0x%x).", pam_thinkfinger->user, tf_state);
goto out;
}
- if (uinput_cr (&pam_thinkfinger->uinput_fd) < 0)
- pam_syslog (pam_thinkfinger->pamh, LOG_ERR, "Could not send carriage return via uinput");
+ ret = uinput_cr (&pam_thinkfinger->uinput_fd);
+ if (ret != 0)
+ pam_thinkfinger_log (pam_thinkfinger, LOG_ERR,
+ "Could not send carriage return via uinput: %s.", strerror (ret));
out:
+ pam_thinkfinger_log (pam_thinkfinger, LOG_NOTICE,
+ "%s returning '%d': %s.", __FUNCTION__, pam_thinkfinger->swipe_retval,
+ pam_thinkfinger->swipe_retval ? pam_strerror (pam_thinkfinger->pamh, pam_thinkfinger->swipe_retval) : "success");
pthread_exit (NULL);
}
static void pam_prompt_thread (void *data)
{
- struct pam_thinkfinger_s *pam_thinkfinger = data;
+ pam_thinkfinger_s *pam_thinkfinger = data;
char *resp;
pam_prompt (pam_thinkfinger->pamh, PAM_PROMPT_ECHO_OFF, &resp, "Password or swipe finger: ");
@@ -165,35 +206,42 @@
PAM_EXTERN
int pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, const char **argv)
{
- int retval = PAM_SERVICE_ERR;
- struct pam_thinkfinger_s pam_thinkfinger;
+ int ret;
+ int retval = PAM_AUTH_ERR;
+ pam_thinkfinger_s pam_thinkfinger;
struct termios term_attr;
libthinkfinger_init_status init_status;
+ pam_thinkfinger.pamh = pamh;
+
+ pam_thinkfinger_options (&pam_thinkfinger, argc, argv);
+ pam_thinkfinger_log (&pam_thinkfinger, LOG_INFO, "%s called.", __FUNCTION__);
+
pam_thinkfinger.isatty = isatty (STDIN_FILENO);
if (pam_thinkfinger.isatty == 1)
tcgetattr (STDIN_FILENO, &term_attr);
pam_get_user (pamh, &pam_thinkfinger.user, NULL);
- if (pam_thinkfinger_check_user (pam_thinkfinger.user) < 0) {
+ if (pam_thinkfinger_check_user (&pam_thinkfinger) < 0) {
+ pam_thinkfinger_log (&pam_thinkfinger, LOG_ERR, "User '%s' is unknown.", pam_thinkfinger.user);
retval = PAM_USER_UNKNOWN;
goto out;
}
- if (uinput_open (&pam_thinkfinger.uinput_fd) < 0) {
- pam_syslog (pamh, LOG_ERR, "Initializing uinput failed.");
- retval = PAM_IGNORE;
+ ret = uinput_open (&pam_thinkfinger.uinput_fd);
+ if (ret != 0) {
+ pam_thinkfinger_log (&pam_thinkfinger, LOG_ERR, "Initializing uinput failed: %s.", strerror (ret));
+ retval = PAM_AUTHINFO_UNAVAIL;
goto out;
}
pam_thinkfinger.tf = libthinkfinger_new (&init_status);
if (init_status != TF_INIT_SUCCESS) {
- pam_syslog (pamh, LOG_ERR, "%s", handle_error (init_status));
- retval = PAM_IGNORE;
+ pam_thinkfinger_log (&pam_thinkfinger, LOG_ERR, "Error: %s", handle_error (init_status));
+ retval = PAM_AUTHINFO_UNAVAIL;
goto out;
}
- pam_thinkfinger.pamh = pamh;
pthread_create (&pam_thinkfinger.t_thinkfinger, NULL, (void *) &thinkfinger_thread, &pam_thinkfinger);
pthread_create (&pam_thinkfinger.t_pam_prompt, NULL, (void *) &pam_prompt_thread, &pam_thinkfinger);
pthread_join (pam_thinkfinger.t_pam_prompt, NULL);
@@ -210,8 +258,10 @@
if (pam_thinkfinger.swipe_retval == PAM_SUCCESS)
retval = PAM_SUCCESS;
else
- retval = PAM_SERVICE_ERR;
+ retval = PAM_AUTHINFO_UNAVAIL;
out:
+ pam_thinkfinger_log (&pam_thinkfinger, LOG_INFO,
+ "%s returning '%d': %s.", __FUNCTION__, retval, retval ? pam_strerror (pamh, retval) : "success");
return retval;
}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/thinkfinger-0.2.3/pam/pam_thinkfinger-uinput.c new/thinkfinger-0.2.3/pam/pam_thinkfinger-uinput.c
--- old/thinkfinger-0.2.3/pam/pam_thinkfinger-uinput.c 2007-02-12 17:52:46.000000000 +0100
+++ new/thinkfinger-0.2.3/pam/pam_thinkfinger-uinput.c 2007-02-27 17:52:50.000000000 +0100
@@ -29,69 +29,83 @@
#include
#include
#include
-
-#define UINPUT_DEVICE "/dev/input/uinput"
+#include
int uinput_cr (int *fd)
{
- int retval = -1;
+ int retval = 0, ev_size = 0;
struct input_event ev = {
.type = EV_KEY,
.code = KEY_ENTER,
.time = {0, }
};
+ ev_size = sizeof (ev);
+
/* key press */
ev.value = 1;
- if (write (*fd, &ev, sizeof ev) != sizeof ev)
+ if (write (*fd, &ev, ev_size) != ev_size) {
+ retval = errno;
goto out;
+ }
/* key release */
ev.value = 0;
- if (write (*fd, &ev, sizeof ev) != sizeof ev)
+ if (write (*fd, &ev, ev_size) != ev_size) {
+ retval = errno;
goto out;
+ }
- retval = 0;
out:
return retval;
}
int uinput_close (int *fd)
{
- int retval = -1;
+ int retval = 0;
/* destroy virtual input device */
if (ioctl (*fd, UI_DEV_DESTROY, 0) < 0)
- goto out;
+ retval = errno;
+
+ if (close (*fd) < 0)
+ retval = errno;
- retval = 0;
-out:
return retval;
}
int uinput_open (int *fd)
{
- int retval = -1;
- int i;
+ int retval = 0, i, device_size = 0;
struct uinput_user_dev device = {
.name = "Virtual ThinkFinger Keyboard"
};
- *fd = open (UINPUT_DEVICE, O_WRONLY | O_NDELAY);
- if (*fd < 0)
+ *fd = open ("/dev/input/uinput", O_WRONLY | O_NDELAY);
+ if (*fd < 0)
+ *fd = open ("/dev/misc/uinput", O_WRONLY | O_NDELAY);
+ if (*fd < 0)
+ *fd = open ("/dev/uinput", O_WRONLY | O_NDELAY);
+ if (*fd < 0) {
+ retval = errno;
goto out;
+ }
+
+ device_size = sizeof (device);
+
/* our single key keyboard */
i = ioctl (*fd, UI_SET_EVBIT, EV_KEY) < 0;
i |= ioctl (*fd, UI_SET_KEYBIT, KEY_ENTER) < 0;
- if (write (*fd, &device, sizeof device) != sizeof device)
+ if (write (*fd, &device, device_size) != device_size) {
+ retval = errno;
goto out;
+ }
+
/* create virtual input device */
if (ioctl (*fd, UI_DEV_CREATE, 0) < 0)
- goto out;
+ retval = errno;
- retval = 0;
out:
return retval;
}
-
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/thinkfinger-0.2.3/tf-tool/tf-tool.c new/thinkfinger-0.2.3/tf-tool/tf-tool.c
--- old/thinkfinger-0.2.3/tf-tool/tf-tool.c 2007-02-14 12:27:41.000000000 +0100
+++ new/thinkfinger-0.2.3/tf-tool/tf-tool.c 2007-02-28 12:05:08.000000000 +0100
@@ -220,8 +220,10 @@
}
printf (" done.\n");
- libthinkfinger_set_file (tf, tfdata->bir);
- libthinkfinger_set_callback (tf, callback, (void *)tfdata);
+ if (libthinkfinger_set_file (tf, tfdata->bir) < 0)
+ goto out;
+ if (libthinkfinger_set_callback (tf, callback, (void *)tfdata) < 0)
+ goto out;
tf_state = libthinkfinger_acquire (tf);
switch (tf_state) {
@@ -240,7 +242,7 @@
retval = -1;
break;
default:
- printf ("Undefined error occured.\n");
+ printf ("Undefined error occured (%i).\n", tf_state);
retval = -1;
break;
}
@@ -290,7 +292,7 @@
retval = -1;
break;
default:
- printf ("Undefined error occured.\n");
+ printf ("Undefined error occured. (%i)\n", tf_state);
retval = -1;
break;
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
---------------------------------------------------------------------
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org