Commit 768fe8d5 authored by Ray Strode's avatar Ray Strode

greeter: Add a login extension mechanism to greeter

This allows extensions to drive which PAM conversations
get run and potentially augment the login window UI.
This commit adds one builtin extension that
does the traditional unified authentication thing, and
a plugin for password-only based authentication.

By default we use the builtin extension, but enable
the plugin with --enable-split-authentication

Subsequent commits will add support for fingerprint and smartcard
plugins.
parent 0d928919
...@@ -5,3 +5,4 @@ VOID:STRING,STRING ...@@ -5,3 +5,4 @@ VOID:STRING,STRING
VOID:UINT,UINT VOID:UINT,UINT
VOID:STRING,INT VOID:STRING,INT
VOID:DOUBLE VOID:DOUBLE
BOOLEAN:STRING
...@@ -18,6 +18,22 @@ AC_PROG_CXX ...@@ -18,6 +18,22 @@ AC_PROG_CXX
AM_PROG_CC_C_O AM_PROG_CC_C_O
AC_PROG_LIBTOOL() AC_PROG_LIBTOOL()
## increment if the plugin interface has additions, changes, removals.
LT_CURRENT=1
## increment any time the source changes; set to
## 0 if you increment CURRENT
LT_REVISION=0
## increment if any interfaces have been added; set to 0
## if any interfaces have been changed or removed. removal has
## precedence over adding, so set to 0 if both happened.
LT_AGE=0
AC_SUBST(LT_CURRENT)
AC_SUBST(LT_REVISION)
AC_SUBST(LT_AGE)
AC_HEADER_STDC AC_HEADER_STDC
AC_SUBST(VERSION) AC_SUBST(VERSION)
...@@ -76,6 +92,8 @@ PKG_CHECK_MODULES(DAEMON, ...@@ -76,6 +92,8 @@ PKG_CHECK_MODULES(DAEMON,
AC_SUBST(DAEMON_CFLAGS) AC_SUBST(DAEMON_CFLAGS)
AC_SUBST(DAEMON_LIBS) AC_SUBST(DAEMON_LIBS)
GLIB_GSETTINGS
PKG_CHECK_MODULES(XLIB, x11 xau xrandr, , PKG_CHECK_MODULES(XLIB, x11 xau xrandr, ,
[AC_PATH_XTRA [AC_PATH_XTRA
if test "x$no_x" = xyes; then if test "x$no_x" = xyes; then
...@@ -195,6 +213,11 @@ AC_SUBST(dmconfdir) ...@@ -195,6 +213,11 @@ AC_SUBST(dmconfdir)
dnl --------------------------------------------------------------------------- dnl ---------------------------------------------------------------------------
dnl - Configure arguments dnl - Configure arguments
dnl --------------------------------------------------------------------------- dnl ---------------------------------------------------------------------------
AC_ARG_ENABLE(split-authentication,
AS_HELP_STRING([--enable-split-authentication],
[Enable multiple simultaneous PAM conversations during login @<:@default=yes@:>@]),,
enable_split_authentication=no)
AM_CONDITIONAL(ENABLE_SPLIT_AUTHENTICATION, test x$enable_split_authentication = xyes)
AC_ARG_ENABLE(console-helper, AC_ARG_ENABLE(console-helper,
AS_HELP_STRING([--enable-console-helper], AS_HELP_STRING([--enable-console-helper],
...@@ -1259,6 +1282,14 @@ fi ...@@ -1259,6 +1282,14 @@ fi
AC_SUBST(GDM_SCREENSHOT_DIR) AC_SUBST(GDM_SCREENSHOT_DIR)
dnl ---------------------------------------------------------------------------
dnl - Directory for simple greeter extensions
dnl ---------------------------------------------------------------------------
GDM_SIMPLE_GREETER_PLUGINS_DIR=${libdir}/gdm/simple-greeter/extensions
AC_SUBST(GDM_SIMPLE_GREETER_PLUGINS_DIR)
GDM_SIMPLE_GREETER_EXTENSIONS_DATA_DIR=${datadir}/gdm/simple-greeter/extensions
AC_SUBST(GDM_SIMPLE_GREETER_EXTENSIONS_DATA_DIR)
dnl --------------------------------------------------------------------------- dnl ---------------------------------------------------------------------------
dnl - Finish dnl - Finish
...@@ -1384,6 +1415,11 @@ daemon/Makefile ...@@ -1384,6 +1415,11 @@ daemon/Makefile
docs/Makefile docs/Makefile
gui/Makefile gui/Makefile
gui/simple-greeter/Makefile gui/simple-greeter/Makefile
gui/simple-greeter/libgdmsimplegreeter/Makefile
gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc
gui/simple-greeter/extensions/Makefile
gui/simple-greeter/extensions/unified/Makefile
gui/simple-greeter/extensions/password/Makefile
gui/simple-chooser/Makefile gui/simple-chooser/Makefile
utils/Makefile utils/Makefile
data/gdm.conf data/gdm.conf
......
NULL = NULL =
SUBDIRS = \
libgdmsimplegreeter \
extensions \
$(NULL)
AM_CPPFLAGS = \ AM_CPPFLAGS = \
-I$(top_srcdir)/common \ -I$(top_srcdir)/common \
-I$(top_builddir)/common \ -I$(top_builddir)/common \
-I$(top_srcdir)/gui/simple-greeter/libgdmsimplegreeter \
-DDMCONFDIR=\""$(dmconfdir)"\" \ -DDMCONFDIR=\""$(dmconfdir)"\" \
-DGDMCONFDIR=\"$(gdmconfdir)\" \ -DGDMCONFDIR=\"$(gdmconfdir)\" \
-DDATADIR=\""$(datadir)"\" \ -DDATADIR=\""$(datadir)"\" \
...@@ -15,6 +20,7 @@ AM_CPPFLAGS = \ ...@@ -15,6 +20,7 @@ AM_CPPFLAGS = \
-DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \ -DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \
-DAT_SPI_REGISTRYD_DIR="\"$(AT_SPI_REGISTRYD_DIR)\"" \ -DAT_SPI_REGISTRYD_DIR="\"$(AT_SPI_REGISTRYD_DIR)\"" \
$(UPOWER_CFLAGS) \ $(UPOWER_CFLAGS) \
-DGDM_SIMPLE_GREETER_PLUGINS_DIR="\"$(GDM_SIMPLE_GREETER_PLUGINS_DIR)\""\
$(DISABLE_DEPRECATED_CFLAGS) \ $(DISABLE_DEPRECATED_CFLAGS) \
$(GTK_CFLAGS) \ $(GTK_CFLAGS) \
$(SIMPLE_GREETER_CFLAGS) \ $(SIMPLE_GREETER_CFLAGS) \
...@@ -60,10 +66,14 @@ test_greeter_login_window_SOURCES = \ ...@@ -60,10 +66,14 @@ test_greeter_login_window_SOURCES = \
gdm-user-chooser-widget.c \ gdm-user-chooser-widget.c \
gdm-user-chooser-dialog.h \ gdm-user-chooser-dialog.h \
gdm-user-chooser-dialog.c \ gdm-user-chooser-dialog.c \
gdm-extension-list.h \
gdm-extension-list.c \
$(NULL) $(NULL)
test_greeter_login_window_LDADD = \ test_greeter_login_window_LDADD = \
$(top_builddir)/common/libgdmcommon.la \ $(top_builddir)/common/libgdmcommon.la \
$(top_builddir)/gui/simple-greeter/libgdmsimplegreeter/libgdmsimplegreeter.la \
$(top_builddir)/gui/simple-greeter/extensions/unified/libunified.la \
$(COMMON_LIBS) \ $(COMMON_LIBS) \
$(SIMPLE_GREETER_LIBS) \ $(SIMPLE_GREETER_LIBS) \
$(RBAC_LIBS) \ $(RBAC_LIBS) \
...@@ -104,6 +114,7 @@ test_greeter_panel_SOURCES = \ ...@@ -104,6 +114,7 @@ test_greeter_panel_SOURCES = \
test_greeter_panel_LDADD = \ test_greeter_panel_LDADD = \
$(top_builddir)/common/libgdmcommon.la \ $(top_builddir)/common/libgdmcommon.la \
$(top_builddir)/gui/simple-greeter/libgdmsimplegreeter/libgdmsimplegreeter.la \
$(SIMPLE_GREETER_LIBS) \ $(SIMPLE_GREETER_LIBS) \
$(GTK_LIBS) \ $(GTK_LIBS) \
$(GCONF_LIBS) \ $(GCONF_LIBS) \
...@@ -251,10 +262,14 @@ gdm_simple_greeter_SOURCES = \ ...@@ -251,10 +262,14 @@ gdm_simple_greeter_SOURCES = \
gdm-session-option-widget.c \ gdm-session-option-widget.c \
gdm-user-chooser-widget.h \ gdm-user-chooser-widget.h \
gdm-user-chooser-widget.c \ gdm-user-chooser-widget.c \
gdm-extension-list.h \
gdm-extension-list.c \
$(NULL) $(NULL)
gdm_simple_greeter_LDADD = \ gdm_simple_greeter_LDADD = \
$(top_builddir)/common/libgdmcommon.la \ $(top_builddir)/common/libgdmcommon.la \
$(top_builddir)/gui/simple-greeter/libgdmsimplegreeter/libgdmsimplegreeter.la \
$(top_builddir)/gui/simple-greeter/extensions/unified/libunified.la \
$(COMMON_LIBS) \ $(COMMON_LIBS) \
$(EXTRA_GREETER_LIBS) \ $(EXTRA_GREETER_LIBS) \
$(SIMPLE_GREETER_LIBS) \ $(SIMPLE_GREETER_LIBS) \
......
SUBDIRS = unified
if ENABLE_SPLIT_AUTHENTICATION
SUBDIRS += password
endif
NULL =
PAM_SERVICE_NAME = gdm-password
extensiondir = $(GDM_SIMPLE_GREETER_EXTENSIONS_DATA_DIR)/password
extension_DATA = page.ui
AM_CPPFLAGS = \
-I$(top_srcdir)/common \
-I$(top_srcdir)/gui/simple-greeter/libgdmsimplegreeter \
-DDMCONFDIR=\""$(dmconfdir)"\" \
-DGDMCONFDIR=\"$(gdmconfdir)\" \
-DPLUGINDATADIR=\""$(extensiondir)"\" \
-DGDM_PASSWORD_EXTENSION_SERVICE_NAME=\""$(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 = libpassword.la
libpassword_la_CFLAGS = \
$(SIMPLE_GREETER_CFLAGS) \
$(NULL)
libpassword_la_LDFLAGS = -module -avoid-version -export-dynamic
libpassword_la_LIBADD = ../../../../common/libgdmcommon.la \
../../libgdmsimplegreeter/libgdmsimplegreeter.la
libpassword_la_SOURCES = \
gdm-password-extension.h \
gdm-password-extension.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
# Sample PAM file for doing password authentication.
# Distros should replace this with what makes sense for them.
auth required pam_env.so
auth sufficient pam_unix.so nullok try_first_pass
auth requisite 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 requisite pam_cracklib.so try_first_pass retry=3 type=
password sufficient pam_unix.so nullok try_first_pass use_authtok
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
session required pam_unix.so
/*
* 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 <rstrode@redhat.com>
*
*/
#include <config.h>
#include "gdm-password-extension.h"
#include "gdm-login-extension.h"
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
struct _GdmPasswordExtensionPrivate
{
GIcon *icon;
GtkWidget *page;
GtkActionGroup *actions;
GtkAction *login_action;
GtkWidget *message_label;
GtkWidget *prompt_label;
GtkWidget *prompt_entry;
GQueue *message_queue;
guint message_timeout_id;
guint answer_pending : 1;
};
typedef struct {
char *text;
GdmServiceMessageType type;
} QueuedMessage;
static void gdm_password_extension_finalize (GObject *object);
static void gdm_login_extension_iface_init (GdmLoginExtensionIface *iface);
G_DEFINE_TYPE_WITH_CODE (GdmPasswordExtension,
gdm_password_extension,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDM_TYPE_LOGIN_EXTENSION,
gdm_login_extension_iface_init));
static void
set_message (GdmPasswordExtension *extension,
const char *message)
{
gtk_widget_show (extension->priv->message_label);
gtk_label_set_text (GTK_LABEL (extension->priv->message_label), message);
}
static void
free_queued_message (QueuedMessage *message)
{
g_free (message->text);
g_slice_free (QueuedMessage, message);
}
static void
purge_message_queue (GdmPasswordExtension *extension)
{
if (extension->priv->message_timeout_id) {
g_source_remove (extension->priv->message_timeout_id);
extension->priv->message_timeout_id = 0;
}
g_queue_foreach (extension->priv->message_queue,
(GFunc) free_queued_message,
NULL);
g_queue_clear (extension->priv->message_queue);
}
static gboolean
dequeue_message (GdmPasswordExtension *extension)
{
if (!g_queue_is_empty (extension->priv->message_queue)) {
int duration;
gboolean needs_beep;
QueuedMessage *message;
message = (QueuedMessage *) g_queue_pop_head (extension->priv->message_queue);
switch (message->type) {
case GDM_SERVICE_MESSAGE_TYPE_INFO:
needs_beep = FALSE;
break;
case GDM_SERVICE_MESSAGE_TYPE_PROBLEM:
needs_beep = TRUE;
break;
default:
g_assert_not_reached ();
}
set_message (extension, message->text);
duration = (int) (g_utf8_strlen (message->text, -1) / 66.0) * 1000;
duration = CLAMP (duration, 400, 3000);
extension->priv->message_timeout_id = g_timeout_add (duration,
(GSourceFunc) dequeue_message,
extension);
if (needs_beep) {
gdk_window_beep (gtk_widget_get_window (GTK_WIDGET (extension->priv->page)));
}
free_queued_message (message);
} else {
extension->priv->message_timeout_id = 0;
_gdm_login_extension_emit_message_queue_empty (GDM_LOGIN_EXTENSION (extension));
}
return FALSE;
}
static void
gdm_password_extension_queue_message (GdmLoginExtension *login_extension,
GdmServiceMessageType type,
const char *text)
{
GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (login_extension);
QueuedMessage *message = g_slice_new (QueuedMessage);
message->text = g_strdup (text);
message->type = type;
g_queue_push_tail (extension->priv->message_queue, message);
if (extension->priv->message_timeout_id == 0) {
dequeue_message (extension);
}
}
static void
gdm_password_extension_ask_question (GdmLoginExtension *login_extension,
const char *message)
{
GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (login_extension);
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;
gtk_action_set_sensitive (extension->priv->login_action, TRUE);
}
static void
gdm_password_extension_ask_secret (GdmLoginExtension *login_extension,
const char *message)
{
GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (login_extension);
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;
gtk_action_set_sensitive (extension->priv->login_action, TRUE);
}
static void
gdm_password_extension_reset (GdmLoginExtension *login_extension)
{
GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (login_extension);
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;
set_message (extension, "");
purge_message_queue (extension);
gdm_login_extension_set_enabled (login_extension, FALSE);
}
static void
gdm_password_extension_set_ready (GdmLoginExtension *extension)
{
gdm_login_extension_set_enabled (extension, TRUE);
}
static char *
gdm_password_extension_get_service_name (GdmLoginExtension *extension)
{
return g_strdup (GDM_PASSWORD_EXTENSION_SERVICE_NAME);
}
static GtkWidget *
gdm_password_extension_get_page (GdmLoginExtension *login_extension)
{
GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (login_extension);
return extension->priv->page;
}
static GtkActionGroup *
gdm_password_extension_get_actions (GdmLoginExtension *login_extension)
{
GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (login_extension);
return g_object_ref (extension->priv->actions);
}
static void
request_answer (GdmPasswordExtension *extension)
{
const char *text;
if (!extension->priv->answer_pending) {
_gdm_login_extension_emit_answer (GDM_LOGIN_EXTENSION (extension), NULL);
return;
}
extension->priv->answer_pending = FALSE;
text = gtk_entry_get_text (GTK_ENTRY (extension->priv->prompt_entry));
_gdm_login_extension_emit_answer (GDM_LOGIN_EXTENSION (extension), text);
gtk_widget_hide (extension->priv->prompt_entry);
gtk_widget_hide (extension->priv->prompt_label);
gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), "");
gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
}
static gboolean
gdm_password_extension_focus (GdmLoginExtension *login_extension)
{
GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (login_extension);
if (!extension->priv->answer_pending) {
_gdm_login_extension_emit_answer (login_extension, NULL);
return FALSE;
}
gtk_widget_grab_focus (extension->priv->prompt_entry);
return TRUE;
}
static gboolean
gdm_password_extension_has_queued_messages (GdmLoginExtension *login_extension)
{
GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (login_extension);
if (extension->priv->message_timeout_id != 0) {
return TRUE;
}
if (!g_queue_is_empty (extension->priv->message_queue)) {
return TRUE;
}
return FALSE;
}
static GIcon *
gdm_password_extension_get_icon (GdmLoginExtension *login_extension)
{
GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (login_extension);
return g_object_ref (extension->priv->icon);
}
static char *
gdm_password_extension_get_name (GdmLoginExtension *login_extension)
{
return g_strdup (_("Password Authentication"));
}
static char *
gdm_password_extension_get_description (GdmLoginExtension *login_extension)
{
return g_strdup (_("Log into session with username and password"));
}
static gboolean
gdm_password_extension_is_choosable (GdmLoginExtension *login_extension)
{
return FALSE;
}
static gboolean
gdm_password_extension_is_visible (GdmLoginExtension *login_extension)
{
return TRUE;
}
static void
gdm_login_extension_iface_init (GdmLoginExtensionIface *iface)
{
iface->get_icon = gdm_password_extension_get_icon;
iface->get_description = gdm_password_extension_get_description;
iface->get_name = gdm_password_extension_get_name;
iface->is_choosable = gdm_password_extension_is_choosable;
iface->is_visible = gdm_password_extension_is_visible;
iface->queue_message = gdm_password_extension_queue_message;
iface->ask_question = gdm_password_extension_ask_question;
iface->ask_secret = gdm_password_extension_ask_secret;
iface->reset = gdm_password_extension_reset;
iface->set_ready = gdm_password_extension_set_ready;
iface->get_service_name = gdm_password_extension_get_service_name;
iface->get_page = gdm_password_extension_get_page;
iface->get_actions = gdm_password_extension_get_actions;
iface->focus = gdm_password_extension_focus;
iface->has_queued_messages = gdm_password_extension_has_queued_messages;
}
static void
gdm_password_extension_class_init (GdmPasswordExtensionClass *extension_class)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (extension_class);
object_class->finalize = gdm_password_extension_finalize;
g_type_class_add_private (extension_class,
sizeof (GdmPasswordExtensionPrivate));
}
static void
gdm_password_extension_finalize (GObject *object)
{
GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (object);
purge_message_queue (extension);
}
static void
on_activate_log_in (GdmPasswordExtension *extension,
GtkAction *action)
{
request_answer (extension);
gtk_action_set_sensitive (action, FALSE);
}
static void
create_page (GdmPasswordExtension *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 (GdmPasswordExtension *extension)
{
GtkAction *action;
extension->priv->actions = gtk_action_group_new (GDM_PASSWORD_EXTENSION_NAME);
action = gtk_action_new (GDM_LOGIN_EXTENSION_DEFAULT_ACTION,
_("Log In"), NULL, NULL);
g_signal_connect_swapped (action, "activate",
G_CALLBACK (on_activate_log_in), extension);
g_object_set (G_OBJECT (action), "icon-name", "go-home", NULL);
gtk_action_group_add_action (extension->priv->actions,
action);
extension->priv->login_action = action;
}
static void
gdm_password_extension_init (GdmPasswordExtension *extension)
{
extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension,
GDM_TYPE_PASSWORD_EXTENSION,
GdmPasswordExtensionPrivate);
extension->priv->icon = g_themed_icon_new ("dialog-password");
create_page (extension);
create_actions (extension);
extension->priv->message_queue = g_queue_new ();
gdm_password_extension_reset (GDM_LOGIN_EXTENSION (extension));
}
void
g_io_module_load (GIOModule *module)
{
g_io_extension_point_implement (GDM_LOGIN_EXTENSION_POINT_NAME,
GDM_TYPE_PASSWORD_EXTENSION,
GDM_PASSWORD_EXTENSION_NAME,
G_MAXINT);
}
void
g_io_module_unload (GIOModule *module)
{
}
/*
* Copyright (C) 2009 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify