16 Commits

Author SHA1 Message Date
c4f3cc2dc3 0.6.0 2015-02-03 17:07:15 +01:00
4edc17ac99 manager: Fix sorting in GetDevices() output
Sort the devices by ID for the GetDevices() output.
2015-02-03 17:07:15 +01:00
56683b1098 tests: Fix listing/deleting with more than one reader
We were always reading the information for reader 0.
2015-02-03 16:44:31 +01:00
f7c51b0d58 tests: Fix segfault in verify when used without -f
We tried to use strcmp on a NULL string.

https://bugs.freedesktop.org/show_bug.cgi?id=85736
2014-11-02 16:34:02 +01:00
f94c8727d2 main: Don't log about normal operation
Administrators don't need to see this stuff on every boot.  The system
bus itself already logs this anyways (which is itself a bit too
chatty).

https://bugs.freedesktop.org/show_bug.cgi?id=71889
2014-04-25 11:28:20 +02:00
4f9256c033 manager: Don't log when we're exiting
This happens on hardware without fingerprint readers on every boot; we
don't need to log anything about it, it's totally normal.

This patch is part of an initiative to reduce logging spew in GNOME
so that actual errors and important messages are more visible.

https://bugs.freedesktop.org/show_bug.cgi?id=71889
2014-04-25 11:28:20 +02:00
73ed60a60d tests: Fix possible crash in fprintd-verify
https://bugs.freedesktop.org/show_bug.cgi?id=75111
2014-02-18 18:32:48 +01:00
d7e326a776 tests: List possible values for finger when enrolling
When the "-f" parameter of fprintd-enroll is incorrect, list
the possible values.
2014-02-18 18:32:08 +01:00
7e4630ced2 pam: Fix eventfd leak
When we create our own GMainContext, we need to be the ones
disposing of it as well, as GMainLoop won't take ownership of it.

From https://bugzilla.redhat.com/show_bug.cgi?id=1050827
2014-01-27 12:25:57 +01:00
fc228b9976 README: Update README 2013-09-30 09:43:46 +02:00
7710040ea7 data: Fix syntax error in fprintd.pod
fprintd.pod around line 100: =over without closing =back
POD document had syntax errors at /usr/bin/pod2man line 69.
2013-08-11 18:58:20 +02:00
3330b8f351 0.5.1 2013-08-11 17:58:52 +02:00
4183c3cdec build: Dist as a .tar.xz file 2013-08-11 17:58:32 +02:00
7eb1f0fd86 tests: Support -f 'finger' option for enroll
Add support for -f 'finger' option to fprintd-enroll.
Update docs accordingly.

https://bugs.freedesktop.org/show_bug.cgi?id=62644
2013-06-26 13:10:17 +02:00
b4f5304565 pam: return PAM_UNKNOWN_USER when user is unenrolled
This commit makes pam_fprintd return PAM_UNKNOWN_USER when
the user has not enrolled a fingerprint.

This lets the administrator set up pam_fprintd as a required
authentication, method, but only for users that have enrolled a
fingerprint, as such:

auth  [success=ok user_unknown=ignore default=die] pam_fprintd.so max_tries=1 timeout=-1
auth  [success=1  default=ignore]                  pam_unix.so nullok_secure
auth  requisite                                    pam_deny.so

With this config, users w/o an enrolled fingerprint will just be
asked for a password.  Users with an enrolled fingerprint will
required to login using both their fingerprint and a password.

https://bugs.freedesktop.org/show_bug.cgi?id=64781
2013-06-03 08:56:22 -04:00
9c99e5cd59 pam: Make max_tries and timeout arguments.
https://bugs.freedesktop.org/show_bug.cgi?id=49918
2013-03-26 12:45:58 +01:00
12 changed files with 139 additions and 40 deletions

14
NEWS
View File

@ -1,6 +1,20 @@
This file lists notable changes in each release. For the full history of all
changes, see ChangeLog.
version 0.6.0:
- Fix warning in fprintd.pod file
- Reduce logging during normal operation
- Fix eventfd leak in PAM module
- List possible values for finger when enrolling
- Fix possible crash in fprintd-verify
- Fix listing and deleting fingerprints when there's more than
one reader available
version 0.5.1:
- Add max_tries and timeout arguments to PAM module
- Add ability to require the fingerprint for enrolled users
- Add "-f <finger>" option to enroll utilities
version 0.5.0:
- Don't use a device name if there's only one reader
- Avoid possible crash when trying to login without devices

7
README
View File

@ -4,14 +4,13 @@ fprintd
http://www.reactivated.net/fprint/wiki/Fprintd
Daemon to offer libfprint functionality over D-Bus
Currently in early stages. Might eat your kangaroo.
Might eat your kangaroo.
Written in C. Requires bleeding edge libfprint (libusb-1.0 port).
Written in C.
Licensed under the GPL version 2 or any later version (see COPYING).
An experimental PAM login module is included in the 'pam' directory.
This will be moved to a separate package once the system has matured.
A PAM login module is included in the 'pam' directory.
API use cases
=============

View File

@ -1,5 +1,5 @@
AC_INIT([fprintd], [0.5.0])
AM_INIT_AUTOMAKE([1.11 dist-bzip2 no-dist-gzip check-news])
AC_INIT([fprintd], [0.6.0])
AM_INIT_AUTOMAKE([1.11 dist-xz no-dist-gzip check-news])
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADERS([config.h])

View File

@ -4,7 +4,7 @@ fprintd - Fingerprint management daemon, and test applications
=head1 SYNOPSYS
B<fprintd-enroll> [username]
B<fprintd-enroll> [-f finger] [usename]
B<fprintd-list> username [usernames...]
@ -100,3 +100,6 @@ By default, fprintd stores the fingerprints in B</var/lib/fprint/>
=over 8
=item B<dbus-daemon>, B<gnome-about-me>
=back

View File

@ -21,6 +21,7 @@
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
@ -39,8 +40,11 @@
#include "fingerprint-strings.h"
#define MAX_TRIES 3
#define TIMEOUT 30
#define DEFAULT_MAX_TRIES 3
#define DEFAULT_TIMEOUT 30
#define MAX_TRIES_MATCH "max-tries="
#define TIMEOUT_MATCH "timeout="
#define D(pamh, ...) { \
if (debug) { \
@ -53,6 +57,8 @@
static gboolean debug = FALSE;
static guint max_tries = DEFAULT_MAX_TRIES;
static guint timeout = DEFAULT_TIMEOUT;
static gboolean send_info_msg(pam_handle_t *pamh, const char *msg)
{
@ -164,6 +170,17 @@ static void close_and_unref (DBusGConnection *connection)
dbus_g_connection_unref (connection);
}
static void unref_loop (GMainLoop *loop)
{
GMainContext *ctx;
/* The main context was created separately, so
* we'll need to unref it ourselves */
ctx = g_main_loop_get_context (loop);
g_main_loop_unref (loop);
g_main_context_unref (ctx);
}
#define DBUS_TYPE_G_OBJECT_PATH_ARRAY (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH))
static DBusGProxy *open_device(pam_handle_t *pamh, DBusGConnection *connection, DBusGProxy *manager, const char *username, gboolean *has_multiple_devices)
@ -271,7 +288,7 @@ static int do_verify(GMainLoop *loop, pam_handle_t *pamh, DBusGProxy *dev, gbool
int ret;
data = g_new0 (verify_data, 1);
data->max_tries = MAX_TRIES;
data->max_tries = max_tries;
data->pamh = pamh;
data->loop = loop;
@ -304,13 +321,16 @@ static int do_verify(GMainLoop *loop, pam_handle_t *pamh, DBusGProxy *dev, gbool
GSource *source;
/* Set up the timeout on our non-default context */
source = g_timeout_source_new_seconds (TIMEOUT);
source = g_timeout_source_new_seconds (timeout);
g_source_attach (source, g_main_loop_get_context (loop));
g_source_set_callback (source, verify_timeout_cb, data, NULL);
data->timed_out = FALSE;
if (!dbus_g_proxy_call (dev, "VerifyStart", &error, G_TYPE_STRING, "any", G_TYPE_INVALID, G_TYPE_INVALID)) {
if (dbus_g_error_has_name(error, "net.reactivated.Fprint.Error.NoEnrolledPrints"))
ret = PAM_USER_UNKNOWN;
D(pamh, "VerifyStart failed: %s", error->message);
g_error_free (error);
@ -388,13 +408,13 @@ static int do_auth(pam_handle_t *pamh, const char *username)
dev = open_device(pamh, connection, manager, username, &has_multiple_devices);
g_object_unref (manager);
if (!dev) {
g_main_loop_unref (loop);
unref_loop (loop);
close_and_unref (connection);
return PAM_AUTHINFO_UNAVAIL;
}
ret = do_verify(loop, pamh, dev, has_multiple_devices);
g_main_loop_unref (loop);
unref_loop (loop);
release_device(pamh, dev);
g_object_unref (dev);
close_and_unref (connection);
@ -429,9 +449,23 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
return PAM_AUTHINFO_UNAVAIL;
for (i = 0; i < argc; i++) {
if (argv[i] != NULL && g_str_equal (argv[i], "debug")) {
g_message ("debug on");
debug = TRUE;
if (argv[i] != NULL) {
if(g_str_equal (argv[i], "debug")) {
g_message ("debug on");
debug = TRUE;
}
else if (strncmp(argv[i], MAX_TRIES_MATCH, strlen (MAX_TRIES_MATCH)) == 0 && strlen(argv[i]) == strlen (MAX_TRIES_MATCH) + 1) {
max_tries = atoi (argv[i] + strlen (MAX_TRIES_MATCH));
if (max_tries < 1)
max_tries = DEFAULT_MAX_TRIES;
D(pamh, "max_tries specified as: %d", max_tries);
}
else if (strncmp(argv[i], TIMEOUT_MATCH, strlen (TIMEOUT_MATCH)) == 0 && strlen(argv[i]) <= strlen (TIMEOUT_MATCH) + 2) {
timeout = atoi (argv[i] + strlen (TIMEOUT_MATCH));
if (timeout < 10)
timeout = DEFAULT_TIMEOUT;
D(pamh, "timeout specified as: %d", timeout);
}
}
}

View File

@ -358,17 +358,17 @@ int main(int argc, char **argv)
goto err;
}
g_print("Launching FprintObject\n");
g_debug("Launching FprintObject");
/* create the one instance of the Manager object to be shared between
* all fprintd users */
manager = fprint_manager_new(no_timeout);
g_message("D-Bus service launched with name: %s", FPRINT_SERVICE_NAME);
g_debug("D-Bus service launched with name: %s", FPRINT_SERVICE_NAME);
g_message("entering main loop");
g_debug("entering main loop");
g_main_loop_run(loop);
g_message("main loop completed");
g_debug("main loop completed");
g_object_unref (manager);

View File

@ -79,7 +79,6 @@ static gchar *get_device_path(FprintDevice *rdev)
static gboolean
fprint_manager_timeout_cb (FprintManager *manager)
{
g_message ("No devices in use, exit");
//FIXME kill all the devices
exit(0);
return FALSE;
@ -160,15 +159,19 @@ static gboolean fprint_manager_get_devices(FprintManager *manager,
GPtrArray **devices, GError **error)
{
FprintManagerPrivate *priv = FPRINT_MANAGER_GET_PRIVATE (manager);
GSList *elem = priv->dev_registry;
GSList *elem = g_slist_reverse(g_slist_copy(priv->dev_registry));
GSList *l;
int num_open = g_slist_length(elem);
GPtrArray *devs = g_ptr_array_sized_new(num_open);
if (num_open > 0)
do {
FprintDevice *rdev = elem->data;
if (num_open > 0) {
for (l = elem; l != NULL; l = l->next) {
FprintDevice *rdev = l->data;
g_ptr_array_add(devs, get_device_path(rdev));
} while ((elem = g_slist_next(elem)) != NULL);
}
}
g_slist_free(elem);
*devices = devs;
return TRUE;
@ -182,7 +185,7 @@ static gboolean fprint_manager_get_default_device(FprintManager *manager,
int num_open = g_slist_length(elem);
if (num_open > 0) {
*device = get_device_path (elem->data);
*device = get_device_path (g_slist_last (elem)->data);
return TRUE;
} else {
g_set_error (error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_DEVICE,

View File

@ -9,7 +9,7 @@ fprintd_verify_CFLAGS = $(WARN_CFLAGS) $(GLIB_CFLAGS)
fprintd_verify_LDADD = $(GLIB_LIBS)
fprintd_enroll_SOURCES = enroll.c $(MARSHALFILES)
fprintd_enroll_CFLAGS = $(WARN_CFLAGS) $(GLIB_CFLAGS)
fprintd_enroll_CFLAGS = $(WARN_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/pam
fprintd_enroll_LDADD = $(GLIB_LIBS)
fprintd_list_SOURCES = list.c

View File

@ -95,7 +95,7 @@ static void process_devices(char **argv)
guint j;
DBusGProxy *dev;
path = g_ptr_array_index(devices, 0);
path = g_ptr_array_index(devices, i);
g_print("Using device %s\n", path);
/* FIXME use for_name_owner?? */

View File

@ -18,13 +18,20 @@
*/
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus-glib-bindings.h>
#include "manager-dbus-glue.h"
#include "device-dbus-glue.h"
#include "marshal.h"
#define N_(x) x
#define TR(x) x
#include "fingerprint-strings.h"
static DBusGProxy *manager = NULL;
static DBusGConnection *connection = NULL;
static char *finger_name = "right-index-finger";
static char **usernames = NULL;
static void create_manager(void)
{
@ -84,13 +91,37 @@ static void do_enroll(DBusGProxy *dev)
{
GError *error = NULL;
gboolean enroll_completed = FALSE;
gboolean found;
guint i;
dbus_g_proxy_add_signal(dev, "EnrollStatus", G_TYPE_STRING, G_TYPE_BOOLEAN, NULL);
dbus_g_proxy_connect_signal(dev, "EnrollStatus", G_CALLBACK(enroll_result),
&enroll_completed, NULL);
g_print("Enrolling right index finger.\n");
if (!net_reactivated_Fprint_Device_enroll_start(dev, "right-index-finger", &error)) {
found = FALSE;
for (i = 0; fingers[i].dbus_name != NULL; i++) {
if (g_strcmp0 (fingers[i].dbus_name, finger_name) == 0) {
found = TRUE;
break;
}
}
if (!found) {
GString *s;
s = g_string_new (NULL);
g_string_append_printf (s, "Invalid finger name '%s'. Name must be one of ", finger_name);
for (i = 0; fingers[i].dbus_name != NULL; i++) {
g_string_append_printf (s, "%s", fingers[i].dbus_name);
if (fingers[i + 1].dbus_name != NULL)
g_string_append (s, ", ");
}
g_warning ("%s", s->str);
g_string_free (s, TRUE);
exit (1);
}
g_print("Enrolling %s finger.\n", finger_name);
if (!net_reactivated_Fprint_Device_enroll_start(dev, finger_name, &error)) {
g_print("EnrollStart failed: %s\n", error->message);
exit (1);
}
@ -116,22 +147,35 @@ static void release_device(DBusGProxy *dev)
}
}
static const GOptionEntry entries[] = {
{ "finger", 'f', 0, G_OPTION_ARG_STRING, &finger_name, "Finger selected to verify (default is automatic)", NULL },
{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &usernames, NULL, "[username]" },
{ NULL }
};
int main(int argc, char **argv)
{
GOptionContext *context;
GError *err = NULL;
DBusGProxy *dev;
char *username;
g_type_init();
dbus_g_object_register_marshaller (fprintd_marshal_VOID__STRING_BOOLEAN,
G_TYPE_NONE, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID);
context = g_option_context_new ("Enroll a fingerprint");
g_option_context_add_main_entries (context, entries, NULL);
if (g_option_context_parse (context, &argc, &argv, &err) == FALSE) {
g_print ("couldn't parse command-line options: %s\n", err->message);
g_error_free (err);
return 1;
}
create_manager();
username = NULL;
if (argc == 2)
username = argv[1];
dev = open_device(username);
dev = open_device(usernames ? usernames[0] : NULL);
do_enroll(dev);
release_device(dev);
return 0;

View File

@ -111,7 +111,7 @@ static void process_devices(char **argv)
guint j;
DBusGProxy *dev;
path = g_ptr_array_index(devices, 0);
path = g_ptr_array_index(devices, i);
g_print("Using device %s\n", path);
/* FIXME use for_name_owner?? */

View File

@ -27,7 +27,7 @@
static DBusGProxy *manager = NULL;
static DBusGConnection *connection = NULL;
static char *finger_name = "any";
static char *finger_name = NULL;
static gboolean g_fatal_warnings = FALSE;
static char **usernames = NULL;
@ -99,8 +99,10 @@ static void find_finger(DBusGProxy *dev, const char *username)
g_print(" - #%d: %s\n", i, fingers[i]);
}
if (strcmp (finger_name, "any") == 0)
finger_name = fingers[0];
if (finger_name == NULL || strcmp (finger_name, "any") == 0) {
g_free (finger_name);
finger_name = g_strdup (fingers[0]);
}
g_strfreev (fingers);
}