From ed6af58c6cd0c87934284e3cc5d8840c0b383604 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sep 10 2014 14:21:31 +0000 Subject: Add fingerprint plugin This commit adds a plugin to initiate a conversation for fingerprint scans. --- diff --git a/configure.ac b/configure.ac index 4536a28..1524161 100644 --- a/configure.ac +++ b/configure.ac @@ -1474,6 +1474,10 @@ gui/simple-greeter/libgdmsimplegreeter/Makefile gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc gui/simple-greeter/plugins/Makefile gui/simple-greeter/plugins/password/Makefile +gui/simple-greeter/plugins/fingerprint/Makefile +gui/simple-greeter/plugins/fingerprint/icons/Makefile +gui/simple-greeter/plugins/fingerprint/icons/16x16/Makefile +gui/simple-greeter/plugins/fingerprint/icons/48x48/Makefile gui/simple-chooser/Makefile gui/user-switch-applet/Makefile utils/Makefile diff --git a/gui/simple-greeter/plugins/Makefile.am b/gui/simple-greeter/plugins/Makefile.am index c0390db..9811a68 100644 --- a/gui/simple-greeter/plugins/Makefile.am +++ b/gui/simple-greeter/plugins/Makefile.am @@ -1 +1 @@ -SUBDIRS = password +SUBDIRS = password fingerprint diff --git a/gui/simple-greeter/plugins/fingerprint/Makefile.am b/gui/simple-greeter/plugins/fingerprint/Makefile.am new file mode 100644 index 0000000..25fb6e8 --- /dev/null +++ b/gui/simple-greeter/plugins/fingerprint/Makefile.am @@ -0,0 +1,56 @@ +SUBDIRS = icons + +NULL = +PAM_SERVICE_NAME = gdm-fingerprint + +extensiondir = $(extensionsdatadir)/fingerprint +extension_DATA = page.ui + +AM_CPPFLAGS = \ + -I$(top_srcdir)/common \ + -I$(top_srcdir)/gui/simple-greeter/libnotificationarea \ + -I$(top_srcdir)/gui/simple-greeter/libgdmsimplegreeter \ + -DDMCONFDIR=\""$(dmconfdir)"\" \ + -DGDMCONFDIR=\"$(gdmconfdir)\" \ + -DPLUGINDATADIR=\""$(extensiondir)"\" \ + -DPAMSERVICENAME=\""$(PAM_SERVICE_NAME)"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DLIBLOCALEDIR=\""$(prefix)/lib/locale"\" \ + -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ + -DLIBEXECDIR=\""$(libexecdir)"\" \ + -DSBINDIR=\""$(sbindir)"\" \ + $(DISABLE_DEPRECATED_CFLAGS) \ + $(GTK_CFLAGS) \ + $(SIMPLE_GREETER_CFLAGS) \ + $(POLKIT_GNOME_CFLAGS) \ + $(NULL) + + +plugindir = $(GDM_SIMPLE_GREETER_PLUGINS_DIR) +plugin_LTLIBRARIES = fingerprint.la + +fingerprint_la_CFLAGS = \ + $(SIMPLE_GREETER_CFLAGS) \ + $(NULL) + +fingerprint_la_LDFLAGS = -module -avoid-version -export-dynamic +fingerprint_la_LIBADD = ../../../../common/libgdmcommon.la \ + ../../libgdmsimplegreeter/libgdmsimplegreeter.la +fingerprint_la_SOURCES = \ + gdm-fingerprint-extension.h \ + gdm-fingerprint-extension.c \ + plugin.c + +$(PAM_SERVICE_NAME): $(PAM_SERVICE_NAME).pam + cp $(PAM_SERVICE_NAME).pam $(PAM_SERVICE_NAME) + +pamdir = $(PAM_PREFIX)/pam.d +pam_DATA = $(PAM_SERVICE_NAME) + +EXTRA_DIST = $(extension_DATA) $(PAM_SERVICE_NAME).pam +CLEANFILES = $(PAM_SERVICE_NAME) + +MAINTAINERCLEANFILES = \ + *~ \ + $(PAM_SERVICE_NAME) \ + Makefile.in diff --git a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c new file mode 100644 index 0000000..55f5d32 --- /dev/null +++ b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2009 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Written By: Ray Strode + * + */ + +#include +#include + +#include "gdm-fingerprint-extension.h" +#include "gdm-conversation.h" +#include "gdm-task.h" + +#include +#include +#include + +struct _GdmFingerprintExtensionPrivate +{ + GIcon *icon; + GtkWidget *page; + GtkActionGroup *actions; + + GtkWidget *message_label; + GtkWidget *prompt_label; + GtkWidget *prompt_entry; + + guint answer_pending : 1; +}; + +static void gdm_fingerprint_extension_finalize (GObject *object); + +static void gdm_task_iface_init (GdmTaskIface *iface); +static void gdm_conversation_iface_init (GdmConversationIface *iface); +static void gdm_greeter_extension_iface_init (GdmGreeterExtensionIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GdmFingerprintExtension, + gdm_fingerprint_extension, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GDM_TYPE_GREETER_EXTENSION, + gdm_greeter_extension_iface_init) + G_IMPLEMENT_INTERFACE (GDM_TYPE_TASK, + gdm_task_iface_init) + G_IMPLEMENT_INTERFACE (GDM_TYPE_CONVERSATION, + gdm_conversation_iface_init)); + +static void +gdm_fingerprint_extension_set_message (GdmConversation *conversation, + const char *message) +{ + GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation); + gtk_widget_show (extension->priv->message_label); + gtk_label_set_text (GTK_LABEL (extension->priv->message_label), message); +} + +static void +gdm_fingerprint_extension_ask_question (GdmConversation *conversation, + const char *message) +{ + GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation); + gtk_widget_show (extension->priv->prompt_label); + gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), message); + gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), ""); + gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), TRUE); + gtk_widget_show (extension->priv->prompt_entry); + gtk_widget_grab_focus (extension->priv->prompt_entry); + extension->priv->answer_pending = TRUE; +} + +static void +gdm_fingerprint_extension_ask_secret (GdmConversation *conversation, + const char *message) +{ + GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation); + gtk_widget_show (extension->priv->prompt_label); + gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), message); + gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), FALSE); + gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), ""); + gtk_widget_show (extension->priv->prompt_entry); + gtk_widget_grab_focus (extension->priv->prompt_entry); + extension->priv->answer_pending = TRUE; +} + +static void +gdm_fingerprint_extension_reset (GdmConversation *conversation) +{ + GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation); + gtk_widget_hide (extension->priv->prompt_label); + gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), ""); + + gtk_widget_hide (extension->priv->prompt_entry); + gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), ""); + gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), TRUE); + extension->priv->answer_pending = FALSE; + + gdm_task_set_enabled (GDM_TASK (conversation), FALSE); +} + +static void +gdm_fingerprint_extension_set_ready (GdmConversation *conversation) +{ + gdm_task_set_enabled (GDM_TASK (conversation), TRUE); +} + +char * +gdm_fingerprint_extension_get_service_name (GdmConversation *conversation) +{ + return g_strdup (PAMSERVICENAME); +} + +GtkWidget * +gdm_fingerprint_extension_get_page (GdmConversation *conversation) +{ + GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation); + return extension->priv->page; +} + +GtkActionGroup * +gdm_fingerprint_extension_get_actions (GdmConversation *conversation) +{ + GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation); + + return g_object_ref (extension->priv->actions); +} + +void +gdm_fingerprint_extension_request_answer (GdmConversation *conversation) +{ + GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation); + const char *text; + + if (!extension->priv->answer_pending) { + gdm_conversation_answer (conversation, NULL); + return; + } + + extension->priv->answer_pending = FALSE; + text = gtk_entry_get_text (GTK_ENTRY (extension->priv->prompt_entry)); + gdm_conversation_answer (conversation, text); + + gtk_widget_hide (extension->priv->prompt_entry); + gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), ""); + gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), ""); +} + +gboolean +gdm_fingerprint_extension_focus (GdmConversation *conversation) +{ + GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation); + + if (!extension->priv->answer_pending) { + return FALSE; + } + + gtk_widget_grab_focus (extension->priv->prompt_entry); + return TRUE; +} + +GIcon * +gdm_fingerprint_extension_get_icon (GdmTask *task) +{ + GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (task); + return g_object_ref (extension->priv->icon); +} + +char * +gdm_fingerprint_extension_get_name (GdmTask *task) +{ + return g_strdup (_("Fingerprint Authentication")); +} + +char * +gdm_fingerprint_extension_get_description (GdmTask *task) +{ + return g_strdup (_("Log into session with fingerprint")); +} + +gboolean +gdm_fingerprint_extension_is_choosable (GdmTask *task) +{ + return FALSE; +} + +gboolean +gdm_fingerprint_extension_is_visible (GdmTask *task) +{ + char *contents, **lines; + gboolean ret; + guint i; + + /* Stolen from gnome-about-me. + * + * FIXME: We should fix pam_fprintd to return authinfo_unavail instead of + * doing this distro specific hack. + */ + + if (g_file_get_contents ("/etc/sysconfig/authconfig", + &contents, NULL, NULL) == FALSE) { + return FALSE; + } + + lines = g_strsplit (contents, "\n", -1); + g_free (contents); + + ret = FALSE; + + for (i = 0; lines[i] ; i++) { + if (g_str_has_prefix (lines[i], "USEFPRINTD=") != FALSE) { + char *value; + + value = lines[i] + strlen ("USEFPRINTD="); + if (rpmatch (value)) { + ret = TRUE; + break; + } + } + } + + g_strfreev (lines); + + return ret; +} + +static void +gdm_task_iface_init (GdmTaskIface *iface) +{ + iface->get_icon = gdm_fingerprint_extension_get_icon; + iface->get_description = gdm_fingerprint_extension_get_description; + iface->get_name = gdm_fingerprint_extension_get_name; + iface->is_choosable = gdm_fingerprint_extension_is_choosable; + iface->is_visible = gdm_fingerprint_extension_is_visible; +} + +static void +gdm_conversation_iface_init (GdmConversationIface *iface) +{ + iface->set_message = gdm_fingerprint_extension_set_message; + iface->ask_question = gdm_fingerprint_extension_ask_question; + iface->ask_secret = gdm_fingerprint_extension_ask_secret; + iface->reset = gdm_fingerprint_extension_reset; + iface->set_ready = gdm_fingerprint_extension_set_ready; + iface->get_service_name = gdm_fingerprint_extension_get_service_name; + iface->get_page = gdm_fingerprint_extension_get_page; + iface->get_actions = gdm_fingerprint_extension_get_actions; + iface->request_answer = gdm_fingerprint_extension_request_answer; + iface->focus = gdm_fingerprint_extension_focus; +} + +static void +gdm_greeter_extension_iface_init (GdmGreeterExtensionIface *iface) +{ +} + +static void +gdm_fingerprint_extension_class_init (GdmFingerprintExtensionClass *extension_class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (extension_class); + + object_class->finalize = gdm_fingerprint_extension_finalize; + + g_type_class_add_private (extension_class, + sizeof (GdmFingerprintExtensionPrivate)); +} + +static void +gdm_fingerprint_extension_finalize (GObject *object) +{ +} + +static void +create_page (GdmFingerprintExtension *extension) +{ + GtkBuilder *builder; + GObject *object; + GError *error; + + builder = gtk_builder_new (); + + error = NULL; + gtk_builder_add_from_file (builder, + PLUGINDATADIR "/page.ui", + &error); + + if (error != NULL) { + g_warning ("Could not load UI file: %s", error->message); + g_error_free (error); + return; + } + + object = gtk_builder_get_object (builder, "page"); + g_object_ref (object); + + extension->priv->page = GTK_WIDGET (object); + + object = gtk_builder_get_object (builder, "auth-prompt-label"); + g_object_ref (object); + extension->priv->prompt_label = GTK_WIDGET (object); + gtk_widget_hide (extension->priv->prompt_label); + + object = gtk_builder_get_object (builder, "auth-prompt-entry"); + g_object_ref (object); + extension->priv->prompt_entry = GTK_WIDGET (object); + gtk_widget_hide (extension->priv->prompt_entry); + + object = gtk_builder_get_object (builder, "auth-message-label"); + g_object_ref (object); + extension->priv->message_label = GTK_WIDGET (object); + gtk_widget_show (extension->priv->message_label); + + g_object_unref (builder); +} + +static void +create_actions (GdmFingerprintExtension *extension) +{ + extension->priv->actions = gtk_action_group_new ("gdm-fingerprint-extension"); +} + +static void +gdm_fingerprint_extension_init (GdmFingerprintExtension *extension) +{ + extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension, + GDM_TYPE_FINGERPRINT_EXTENSION, + GdmFingerprintExtensionPrivate); + + extension->priv->icon = g_themed_icon_new ("gdm-fingerprint"); + create_page (extension); + create_actions (extension); + gdm_fingerprint_extension_reset (GDM_CONVERSATION (extension)); +} diff --git a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.h b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.h new file mode 100644 index 0000000..5d34b21 --- /dev/null +++ b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written By: Ray Strode + */ + +#ifndef __GDM_FINGERPRINT_EXTENSION_H +#define __GDM_FINGERPRINT_EXTENSION_H + +#include +#include "gdm-greeter-extension.h" + +G_BEGIN_DECLS + +#define GDM_TYPE_FINGERPRINT_EXTENSION (gdm_fingerprint_extension_get_type ()) +#define GDM_FINGERPRINT_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_FINGERPRINT_EXTENSION, GdmFingerprintExtension)) +#define GDM_FINGERPRINT_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_FINGERPRINT_EXTENSION, GdmFingerprintExtensionClass)) +#define GDM_IS_FINGERPRINT_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_FINGERPRINT_EXTENSION)) +#define GDM_IS_FINGERPRINT_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_FINGERPRINT_EXTENSION)) +#define GDM_FINGERPRINT_EXTENSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_FINGERPRINT_EXTENSION, GdmFingerprintExtensionClass)) + +typedef struct _GdmFingerprintExtensionPrivate GdmFingerprintExtensionPrivate; + +typedef struct +{ + GObject parent; + GdmFingerprintExtensionPrivate *priv; +} GdmFingerprintExtension; + +typedef struct +{ + GObjectClass parent_class; +} GdmFingerprintExtensionClass; + +GType gdm_fingerprint_extension_get_type (void); + +GdmFingerprintExtension *gdm_fingerprint_extension_new (void); + +G_END_DECLS + +#endif /* GDM_FINGERPRINT_EXTENSION_H */ diff --git a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint.pam b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint.pam new file mode 100644 index 0000000..1a1c777 --- /dev/null +++ b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint.pam @@ -0,0 +1,17 @@ +# Sample PAM file for doing fingerprint authentication. +# Distros should replace this with what makes sense for them. +auth required pam_env.so +auth required pam_fprintd.so +auth sufficient pam_succeed_if.so uid >= 500 quiet +auth required pam_deny.so + +account required pam_unix.so +account sufficient pam_localuser.so +account sufficient pam_succeed_if.so uid < 500 quiet +account required pam_permit.so + +password required pam_deny.so + +session optional pam_keyinit.so revoke +session required pam_limits.so +session required pam_unix.so diff --git a/gui/simple-greeter/plugins/fingerprint/icons/16x16/Makefile.am b/gui/simple-greeter/plugins/fingerprint/icons/16x16/Makefile.am new file mode 100644 index 0000000..f42e317 --- /dev/null +++ b/gui/simple-greeter/plugins/fingerprint/icons/16x16/Makefile.am @@ -0,0 +1,5 @@ +iconsdir = $(datadir)/icons/hicolor/16x16/apps + +icons_DATA = gdm-fingerprint.png + +EXTRA_DIST = $(icons_DATA) diff --git a/gui/simple-greeter/plugins/fingerprint/icons/16x16/gdm-fingerprint.png b/gui/simple-greeter/plugins/fingerprint/icons/16x16/gdm-fingerprint.png new file mode 100644 index 0000000..4438cee Binary files /dev/null and b/gui/simple-greeter/plugins/fingerprint/icons/16x16/gdm-fingerprint.png differ diff --git a/gui/simple-greeter/plugins/fingerprint/icons/48x48/Makefile.am b/gui/simple-greeter/plugins/fingerprint/icons/48x48/Makefile.am new file mode 100644 index 0000000..f4ab2a0 --- /dev/null +++ b/gui/simple-greeter/plugins/fingerprint/icons/48x48/Makefile.am @@ -0,0 +1,5 @@ +iconsdir = $(datadir)/icons/hicolor/48x48/apps + +icons_DATA = gdm-fingerprint.png + +EXTRA_DIST = $(icons_DATA) diff --git a/gui/simple-greeter/plugins/fingerprint/icons/48x48/gdm-fingerprint.png b/gui/simple-greeter/plugins/fingerprint/icons/48x48/gdm-fingerprint.png new file mode 100644 index 0000000..fd6f546 Binary files /dev/null and b/gui/simple-greeter/plugins/fingerprint/icons/48x48/gdm-fingerprint.png differ diff --git a/gui/simple-greeter/plugins/fingerprint/icons/Makefile.am b/gui/simple-greeter/plugins/fingerprint/icons/Makefile.am new file mode 100644 index 0000000..c20f10d --- /dev/null +++ b/gui/simple-greeter/plugins/fingerprint/icons/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = 16x16 48x48 diff --git a/gui/simple-greeter/plugins/fingerprint/page.ui b/gui/simple-greeter/plugins/fingerprint/page.ui new file mode 100644 index 0000000..7554d80 --- /dev/null +++ b/gui/simple-greeter/plugins/fingerprint/page.ui @@ -0,0 +1,59 @@ + + + + + True + vertical + + + True + 6 + + + True + True + + + False + False + 0 + + + + + True + True + True + + + 1 + + + + + True + True + 0 + + + + + True + + + True + True + + + 0 + + + + + True + True + 1 + + + + diff --git a/gui/simple-greeter/plugins/fingerprint/plugin.c b/gui/simple-greeter/plugins/fingerprint/plugin.c new file mode 100644 index 0000000..5ea9925 --- /dev/null +++ b/gui/simple-greeter/plugins/fingerprint/plugin.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Written By: Ray Strode + * + */ + +#include "gdm-fingerprint-extension.h" + +#include +#include + +GdmGreeterExtension * +gdm_greeter_plugin_get_extension (void) +{ + static GObject *extension; + + if (extension != NULL) { + g_object_ref (extension); + } else { + extension = g_object_new (GDM_TYPE_FINGERPRINT_EXTENSION, NULL); + g_object_add_weak_pointer (extension, (gpointer *) &extension); + } + + return GDM_GREETER_EXTENSION (extension); +} diff --git a/po/POTFILES.in b/po/POTFILES.in index 10fd68d..6e10068 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -82,6 +82,7 @@ gui/simple-greeter/gdm-user.c gui/simple-greeter/gdm-user-chooser-widget.c gui/simple-greeter/greeter-main.c gui/simple-greeter/plugins/password/gdm-password-extension.c +gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c gui/user-switch-applet/applet.c gui/user-switch-applet/gdm-entry-menu-item.c gui/user-switch-applet/GNOME_FastUserSwitchApplet.server.in.in