aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cvsignore31
-rw-r--r--ChangeLog67
-rw-r--r--acinclude.m488
-rw-r--r--configure.ac15
-rw-r--r--etpo/.cvsignore6
-rw-r--r--m4/compiler-flags.m440
-rw-r--r--po/.cvsignore10
-rw-r--r--po/POTFILES.in1
-rw-r--r--po/krb5-auth-dialog.pot2
-rw-r--r--src/.cvsignore5
-rw-r--r--src/Makefile.am2
-rw-r--r--src/dummy-strings.c4
-rw-r--r--src/krb5-auth-applet.c117
-rw-r--r--src/krb5-auth-applet.h21
-rw-r--r--src/krb5-auth-dbus.c1
-rw-r--r--src/krb5-auth-dialog.c417
-rw-r--r--src/krb5-auth-dialog.glade2
-rw-r--r--src/krb5-auth-dialog.h1
-rw-r--r--src/krb5-auth-gconf.c6
-rw-r--r--src/krb5-auth-pwdialog.c246
-rw-r--r--src/krb5-auth-pwdialog.h65
21 files changed, 779 insertions, 368 deletions
diff --git a/.cvsignore b/.cvsignore
deleted file mode 100644
index e3410ea..0000000
--- a/.cvsignore
+++ /dev/null
@@ -1,31 +0,0 @@
-aclocal.m4
-autom4te.cache
-COPYING
-INSTALL
-configure
-config.log
-config.status
-config.h
-config.h.in
-compile
-config.guess
-config.sub
-depcomp
-Makefile
-Makefile.in
-intltool-extract
-intltool-merge
-intltool-update
-intltool-extract.in
-intltool-merge.in
-intltool-update.in
-libtool*
-ltmain.sh
-install-sh
-missing
-mkinstalldirs
-stamp-h1
-krb5-auth-dialog.spec
-krb5-auth-dialog*.tar.bz2
-krb5-auth-dialog*.tar.gz
-
diff --git a/ChangeLog b/ChangeLog
index e9918bc..d1e6757 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,70 @@
+Di Mär 24 00:04:50 CET 2009 Guido Günther <agx@sigxcpu.org>
+
+ monitor ccache via GFileMontor
+ * src/krb5-auth-dialog.c (monitor_ccache, ka_ccache_filename,
+ ccache_changed_cb): new functions
+ (main): monitor ccache via monitor_ccache
+ * configure.ac: look for gio-unix
+
+Di Mär 24 00:01:28 CET 2009 Guido Günther <agx@sigxcpu.org>
+
+ * src/krb5-auth-dialog.c (auth_dialog_prompter): handle
+ GTK_RESPONSE_DELETE_EVENT like GTK_RESPONSE_CANCEL so pressing ESC or
+ closing the dialog has the same effect than pressing cancel.
+ * (ka_grab_credentials): look at "cancled" instead of looking at the
+ kerberos error codes - more robust since heimdal and mit have different
+ responses, let alone pkinit.
+
+Mo Mär 23 23:57:36 CET 2009 Guido Günther <agx@sigxcpu.org>
+
+ split password auth into a separate function
+ * src/krb5-auth-dialog.c (ka_auth_password): new function
+ (grab_credentials): fall back to password auth if no token is
+ present and pkinit is enabled
+
+Mo Mär 23 23:55:20 CET 2009 Guido Günther <agx@sigxcpu.org>
+
+ * src/krb5-auth-pwdialog.h: remove unused headers
+ * src/krb5-auth-applet.h: likewise
+ * src/krb5-auth-dialog.c (is_online): move static variable to the top
+
+Mi Mär 11 17:21:07 CET 2009 Guido Günther <agx@sigxcpu.org>
+
+ silence compiler warnings
+ * src/krb5-auth-{applet,dialog,gconf,pwdialog}.[ch]: mark unused
+ parameters as G_GNUC_UNUSED or drop them, add missing void to
+ prototypes
+
+Mi Mär 11 17:19:02 CET 2009 Guido Günther <agx@sigxcpu.org>
+
+ add more compiler warnings
+ * acinclude.m4: add KA_COMPILE_WARNINGS
+ * compiler-flags.m4: add gl_COMPILER_FLAGS to test compiler options
+ * configure.ac: call KA_COMPILE_WARNINGS and add WARN_CFLAGS to CFLAGS
+
+Mi Mär 11 17:10:11 CET 2009 Guido Günther <agx@sigxcpu.org>
+
+ push the dialog into the foreground and grab the keyboard so we make
+ sure the user gets to see the dialog in all cases (e.g. when an app is
+ requesting the TGT via dbus). Grab the keyboard so the user doesn't
+ type the password somewhere else. Code mostly taken from gnome
+ keyrings's gkr-ask-tool.c.
+ * src/krb5-auth-pwdialog.c (grab_keyboard, ungrab_keyboard,
+ window_state_changed): new functions
+ (ka_pwdialog_run): use these
+
+Mi Mär 11 17:04:03 CET 2009 Guido Günther <agx@sigxcpu.org>
+
+ add a pwdialog gobject - remove lots of duplicate code and splits most
+ of the password dialog handling into its own file
+ * src/krb5-auth-applet.[ch]: move dialog handling from
+ here...
+ * src/krb5-auth-dialog.[ch]: ..and here...
+ * src/krb5-auth-pwdialog.[ch]: ... to here - new files.
+ * src/krb5-auth-dialog.glade: rename krb5_wrong_label to
+ krb5_status_label
+ * po/POTFILES.in, src/Makefile.am: add src/krb5-auth-pwdialog.c
+
Sat Feb 28 16:41:54 CET 2009 Guido Günther <agx@sigxcpu.org>
add DBus interface to acquire TGT
diff --git a/acinclude.m4 b/acinclude.m4
index 7dfad70..e775c28 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -115,3 +115,91 @@ define([GNUPG_CHECK_MLOCK],
fi
fi
])
+
+dnl
+dnl taken from libvirt which was
+dnl taken from gnome-common/macros2/gnome-compiler-flags.m4
+dnl
+dnl We've added:
+dnl -Wextra -Wshadow -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Winline -Wredundant-decls
+dnl We've removed
+dnl CFLAGS="$realsave_CFLAGS"
+dnl to avoid clobbering user-specified CFLAGS
+dnl
+AC_DEFUN([KA_COMPILE_WARNINGS],[
+ dnl ******************************
+ dnl More compiler warnings
+ dnl ******************************
+
+ AC_ARG_ENABLE(compile-warnings,
+ AC_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],
+ [Turn on compiler warnings]),,
+ [enable_compile_warnings="m4_default([$1],[maximum])"])
+
+ warnCFLAGS=
+
+ common_flags="-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fasynchronous-unwind-tables"
+
+ case "$enable_compile_warnings" in
+ no)
+ try_compiler_flags=""
+ ;;
+ minimum)
+ try_compiler_flags="-Wall -Wformat -Wformat-security $common_flags"
+ ;;
+ yes)
+ try_compiler_flags="-Wall -Wformat -Wformat-security -Wmissing-prototypes $common_flags"
+ ;;
+ maximum|error)
+ try_compiler_flags="-Wall -Wformat -Wformat-security -Wmissing-prototypes -Wnested-externs -Wpointer-arith"
+ try_compiler_flags="$try_compiler_flags -Wextra -Wshadow -Wcast-align -Wwrite-strings -Waggregate-return"
+ try_compiler_flags="$try_compiler_flags -Wstrict-prototypes -Winline -Wredundant-decls -Wno-sign-compare"
+ try_compiler_flags="$try_compiler_flags $common_flags"
+ if test "$enable_compile_warnings" = "error" ; then
+ try_compiler_flags="$try_compiler_flags -Werror"
+ fi
+ ;;
+ *)
+ AC_MSG_ERROR(Unknown argument '$enable_compile_warnings' to --enable-compile-warnings)
+ ;;
+ esac
+
+ COMPILER_FLAGS=
+ for option in $try_compiler_flags; do
+ gl_COMPILER_FLAGS($option)
+ done
+ unset option
+ unset try_compiler_flags
+
+ AC_ARG_ENABLE(iso-c,
+ AC_HELP_STRING([--enable-iso-c],
+ [Try to warn if code is not ISO C ]),,
+ [enable_iso_c=no])
+
+ AC_MSG_CHECKING(what language compliance flags to pass to the C compiler)
+ complCFLAGS=
+ if test "x$enable_iso_c" != "xno"; then
+ if test "x$GCC" = "xyes"; then
+ case " $CFLAGS " in
+ *[\ \ ]-ansi[\ \ ]*) ;;
+ *) complCFLAGS="$complCFLAGS -ansi" ;;
+ esac
+ case " $CFLAGS " in
+ *[\ \ ]-pedantic[\ \ ]*) ;;
+ *) complCFLAGS="$complCFLAGS -pedantic" ;;
+ esac
+ fi
+ fi
+ AC_MSG_RESULT($complCFLAGS)
+
+ WARN_CFLAGS="$COMPILER_FLAGS $complCFLAGS"
+ AC_SUBST(WARN_CFLAGS)
+
+ dnl Needed to keep compile quiet on python 2.4
+ COMPILER_FLAGS=
+ gl_COMPILER_FLAGS(-Wno-redundant-decls)
+ WARN_PYTHON_CFLAGS=$COMPILER_FLAGS
+ AC_SUBST(WARN_PYTHON_CFLAGS)
+])
+
+m4_include([m4/compiler-flags.m4])
diff --git a/configure.ac b/configure.ac
index 1a16cd1..89fb2fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,7 @@
-AC_INIT(src/krb5-auth-dialog.c)
-
-AM_INIT_AUTOMAKE(krb5-auth-dialog, 0.8)
+AC_INIT([krb5-auth-dialog], [0.8])
+AC_CONFIG_SRCDIR(src/krb5-auth-dialog.c)
+dnl Make automake keep quiet about wildcards & other GNUmake-isms
+AM_INIT_AUTOMAKE([-Wno-portability])
AM_CONFIG_HEADER(config.h)
AM_MAINTAINER_MODE
@@ -18,6 +19,8 @@ AC_PROG_INTLTOOL
AM_PROG_LEX
AC_PROG_YACC
+KA_COMPILE_WARNINGS([maximum])
+
ALL_LINGUAS="nb de"
AM_GLIB_GNU_GETTEXT
@@ -26,11 +29,13 @@ GLADE_REQUIRED="2.4.0"
DBUS_REQUIRED="0.60"
GCONF_REQUIRED="2.8"
LIBNOTIFY_REQUIRED="0.4"
+GIO_UNIX_REQUIRED="0.0"
PKG_CHECK_MODULES(GTK, gtk+-2.0 >= $GTK_REQUIRED)
PKG_CHECK_MODULES(GLADE, libglade-2.0 >= $GLADE_REQUIRED)
PKG_CHECK_MODULES(DBUS, dbus-glib-1 >= $DBUS_REQUIRED)
PKG_CHECK_MODULES(GCONF, gconf-2.0 >= $GCONF_REQUIRED)
+PKG_CHECK_MODULES(GIO_UNIX, gio-unix-2.0 >= $GIO_UNIX_REQUIRED)
dnl --enable-debug=(yes|no)
AC_ARG_ENABLE(debug,
@@ -200,6 +205,7 @@ CFLAGS="\
$KRB5_CFLAGS \
$NETWORK_MANAGER_CFLAGS \
$LIBNOTIFY_CFLAGS \
+ $WARN_CFLAGS \
$CFLAGS"
AC_OUTPUT([
@@ -225,6 +231,7 @@ AC_MSG_NOTICE([ gtk: $GTK_CFLAGS $GTK_LIBS])
AC_MSG_NOTICE([ glade: $GLADE_CFLAGS $GLADE_LIBS])
AC_MSG_NOTICE([ dbus: $DBUS_CFLAGS $DBUS_LIBS])
AC_MSG_NOTICE([ gconf: $GCONF_CFLAGS $GCONF_LIBS])
+AC_MSG_NOTICE([ gio-unix: $GIO_UNIX_CFLAGS $GIO_UNIX_LIBS])
if test "$with_libnotify" = "yes" ; then
AC_MSG_NOTICE([ libnotify: $LIBNOTIFY_CFLAGS $LIBNOTIFY_LIBS])
else
@@ -238,6 +245,8 @@ fi
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Miscellaneous])
AC_MSG_NOTICE([])
+AC_MSG_NOTICE([ Warnings: $WARN_CFLAGS])
+AC_MSG_NOTICE([ Debug : $enable_debug])
AC_MSG_NOTICE([ Minimum Lifetime: $minimum_lifetime minutes])
AC_MSG_NOTICE([ Check Interval: $check_interval seconds])
AC_MSG_NOTICE([])
diff --git a/etpo/.cvsignore b/etpo/.cvsignore
deleted file mode 100644
index dff7314..0000000
--- a/etpo/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile
-Makefile.in
-etpo
-grammar.c
-grammar.h
-lexer.c
diff --git a/m4/compiler-flags.m4 b/m4/compiler-flags.m4
new file mode 100644
index 0000000..4940a1e
--- /dev/null
+++ b/m4/compiler-flags.m4
@@ -0,0 +1,40 @@
+# serial 3
+# Find valid warning flags for the C Compiler. -*-Autoconf-*-
+#
+# Copyright (C) 2001, 2002, 2006 Free Software Foundation, 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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+# Written by Jesse Thilo.
+
+AC_DEFUN([gl_COMPILER_FLAGS],
+ [AC_MSG_CHECKING(whether compiler accepts $1)
+ AC_SUBST(COMPILER_FLAGS)
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+ AC_TRY_LINK([], [], has_option=yes, has_option=no,)
+ echo 'int x;' >conftest.c
+ $CC $CFLAGS -c conftest.c 2>conftest.err
+ ret=$?
+ if test $ret != 0 -o -s conftest.err -o $has_option = "no"; then
+ AC_MSG_RESULT(no)
+ else
+ AC_MSG_RESULT(yes)
+ COMPILER_FLAGS="$COMPILER_FLAGS $1"
+ fi
+ CFLAGS="$ac_save_CFLAGS"
+ rm -f conftest*
+ ])
diff --git a/po/.cvsignore b/po/.cvsignore
deleted file mode 100644
index 216b8fc..0000000
--- a/po/.cvsignore
+++ /dev/null
@@ -1,10 +0,0 @@
-*.gmo
-*.mo
-*.pot
-Makefile
-Makefile.in
-Makefile.in.in
-POTFILES
-messages
-missing
-notexist
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b9a464f..8ee65fd 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,5 +1,6 @@
src/krb5-auth-dialog.glade
src/krb5-auth-dialog.c
+src/krb5-auth-pwdialog.c
src/dummy-strings.c
src/krb5-auth-applet.c
src/krb5-auth-dialog.desktop.in
diff --git a/po/krb5-auth-dialog.pot b/po/krb5-auth-dialog.pot
index 46a786e..4d639d3 100644
--- a/po/krb5-auth-dialog.pot
+++ b/po/krb5-auth-dialog.pot
@@ -694,7 +694,7 @@ msgstr ""
#. import_err.et:imp:IMPORT_GET_PARAMS
#. kv5m_err.et:kv5m:KV5M_GSS_QUEUE
#: ../src/dummy-strings.c:135 ../src/dummy-strings.c:388
-msgid "$Id: krb5-auth-dialog.pot 115 2009-01-10 13:25:51Z guidog $"
+msgid "$Id$"
msgstr ""
#. kdc5_err.et:kdc5:KDC5_RCSID
diff --git a/src/.cvsignore b/src/.cvsignore
deleted file mode 100644
index b18d7e7..0000000
--- a/src/.cvsignore
+++ /dev/null
@@ -1,5 +0,0 @@
-Makefile
-Makefile.in
-krb5-auth-dialog
-krb5-auth-dialog.1
-krb5-auth-dialog.desktop
diff --git a/src/Makefile.am b/src/Makefile.am
index 1ff6ac0..a0db9ec 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,6 +22,8 @@ krb5_auth_dialog_SOURCES = \
krb5-auth-dialog.h \
krb5-auth-applet.c \
krb5-auth-applet.h \
+ krb5-auth-pwdialog.c \
+ krb5-auth-pwdialog.h \
krb5-auth-gconf.c \
krb5-auth-gconf.h \
krb5-auth-dbus.c \
diff --git a/src/dummy-strings.c b/src/dummy-strings.c
index 6f29d54..e107293 100644
--- a/src/dummy-strings.c
+++ b/src/dummy-strings.c
@@ -132,7 +132,7 @@ realm %s. %s."), /* kpasswd_strings.et:kpws:KPW_STR_CANT_OPEN_ADMIN_SERVER */
N_("while releasing permanent lock"), /* import_err.et:imp:IMPORT_RENAME_UNLOCK */
N_("while closing databases"), /* import_err.et:imp:IMPORT_RENAME_CLOSE */
N_("while retrieving configuration parameters"), /* import_err.et:imp:IMPORT_GET_PARAMS */
- N_("$Id: dummy-strings.c 35 2005-10-31 21:55:46Z caillon $"), /* kdc5_err.et:kdc5:KDC5_RCSID */
+ N_("$Id$"), /* kdc5_err.et:kdc5:KDC5_RCSID */
N_("No server port found"), /* kdc5_err.et:kdc5:KDC5_NOPORT */
N_("Network not initialized"), /* kdc5_err.et:kdc5:KDC5_NONET */
N_("Short write while sending response"), /* kdc5_err.et:kdc5:KDC5_IO_RESPONSE */
@@ -385,7 +385,7 @@ realm %s. %s."), /* kpasswd_strings.et:kpws:KPW_STR_CANT_OPEN_ADMIN_SERVER */
N_("Bad magic number for passwd_phrase_element"), /* kv5m_err.et:kv5m:KV5M_PASSWD_PHRASE_ELEMENT */
N_("Bad magic number for GSSAPI OID"), /* kv5m_err.et:kv5m:KV5M_GSS_OID */
N_("Bad magic number for GSSAPI QUEUE"), /* kv5m_err.et:kv5m:KV5M_GSS_QUEUE */
- N_("$Id: dummy-strings.c 35 2005-10-31 21:55:46Z caillon $"), /* kdb5_err.et:kdb5:KRB5_KDB_RCSID */
+ N_("$Id$"), /* kdb5_err.et:kdb5:KRB5_KDB_RCSID */
N_("Entry already exists in database"), /* kdb5_err.et:kdb5:KRB5_KDB_INUSE */
N_("Database store error"), /* kdb5_err.et:kdb5:KRB5_KDB_UK_SERROR */
N_("Database read error"), /* kdb5_err.et:kdb5:KRB5_KDB_UK_RERROR */
diff --git a/src/krb5-auth-applet.c b/src/krb5-auth-applet.c
index 996d862..34524df 100644
--- a/src/krb5-auth-applet.c
+++ b/src/krb5-auth-applet.c
@@ -64,12 +64,8 @@ struct _KaAppletPrivate
const char* icons[3]; /* for invalid, expiring and valid tickts */
gboolean show_trayicon; /* show the trayicon */
- /* The password dialog */
- GtkWidget* pw_dialog; /* the password dialog itself */
- GladeXML* pw_xml; /* the dialog's glade xml */
- GtkWidget* pw_label; /* the wrong password/timeout label */
+ KaPwDialog* pwdialog; /* the password dialog */
int pw_prompt_secs; /* when to start prompting for a password */
- gboolean pw_dialog_persist; /* don't hide the dialog when creds are still valid */
#ifdef HAVE_LIBNOTIFY
NotifyNotification* notification;/* notification messages */
@@ -160,9 +156,9 @@ ka_applet_dispose(GObject* object)
g_object_unref(applet->priv->tray_icon);
applet->priv->tray_icon = NULL;
}
- if (applet->priv->pw_xml) {
- g_object_unref(applet->priv->pw_xml);
- applet->priv->pw_xml = NULL;
+ if (applet->priv->pwdialog) {
+ g_object_unref(applet->priv->pwdialog);
+ applet->priv->pwdialog = NULL;
}
if (parent_class->dispose != NULL)
@@ -243,7 +239,8 @@ ka_applet_class_init(KaAppletClass *klass)
}
-KaApplet *ka_applet_new(void)
+static KaApplet*
+ka_applet_new(void)
{
return g_object_new (KA_TYPE_APPLET, NULL);
}
@@ -251,7 +248,7 @@ KaApplet *ka_applet_new(void)
/* determine the new tooltip text */
static char*
-ka_applet_tooltip_text(KaApplet* applet, int remaining)
+ka_applet_tooltip_text(int remaining)
{
int hours, minutes;
gchar* tooltip_text;
@@ -292,11 +289,11 @@ ka_applet_select_icon(KaApplet* applet, int remaining)
}
-void
-ka_send_event_notification (KaApplet *applet __attribute__((__unused__)),
- const char *summary __attribute__((__unused__)),
- const char *message __attribute__((__unused__)),
- const char *icon __attribute__((__unused__)))
+static void
+ka_send_event_notification (KaApplet *applet G_GNUC_UNUSED,
+ const char *summary G_GNUC_UNUSED,
+ const char *message G_GNUC_UNUSED,
+ const char *icon G_GNUC_UNUSED)
{
#ifdef HAVE_LIBNOTIFY
const char *notify_icon;
@@ -333,7 +330,7 @@ ka_applet_update_status(KaApplet* applet, krb5_timestamp expiry)
static int last_warn = 0;
static gboolean expiry_notified = FALSE;
const char* tray_icon = ka_applet_select_icon (applet, remaining);
- char* tooltip_text = ka_applet_tooltip_text (applet, remaining);
+ char* tooltip_text = ka_applet_tooltip_text (remaining);
if (remaining > 0) {
if (expiry_notified) {
@@ -378,7 +375,7 @@ ka_applet_menu_add_separator_item (GtkWidget* menu)
/* Free all resources and quit */
static void
-ka_applet_cb_quit (GtkMenuItem* menuitem, gpointer user_data)
+ka_applet_cb_quit (GtkMenuItem* menuitem G_GNUC_UNUSED, gpointer user_data)
{
KaApplet* applet = KA_APPLET(user_data);
@@ -388,16 +385,19 @@ ka_applet_cb_quit (GtkMenuItem* menuitem, gpointer user_data)
static void
-ka_applet_cb_about_dialog (GtkMenuItem* menuitem, gpointer user_data)
+ka_applet_cb_about_dialog (GtkMenuItem* menuitem G_GNUC_UNUSED,
+ gpointer user_data G_GNUC_UNUSED)
{
- gchar* authors[] = { "Christopher Aillon <caillon@redhat.com>",
- "Colin Walters <walters@verbum.org>",
- "Guido Günther <agx@sigxpcu.org>",
- NULL };
+ const gchar* authors[] = { "Christopher Aillon <caillon@redhat.com>",
+ "Colin Walters <walters@verbum.org>",
+ "Guido Günther <agx@sigxpcu.org>",
+ NULL };
gtk_show_about_dialog (NULL,
- "authors", authors,
- "version", VERSION,
- "copyright", "Copyright (C) 2004,2005,2006 Red Hat, Inc.,\n2008,2009 Guido Günther",
+ "authors", authors,
+ "version", VERSION,
+ "copyright",
+ "Copyright (C) 2004,2005,2006 Red Hat, Inc.,\n"
+ "2008,2009 Guido Günther",
NULL);
}
@@ -445,8 +445,10 @@ ka_applet_create_context_menu (KaApplet* applet)
static void
-ka_tray_icon_on_menu (GtkStatusIcon* status_icon, guint button,
- guint activate_time, gpointer user_data)
+ka_tray_icon_on_menu (GtkStatusIcon* status_icon G_GNUC_UNUSED,
+ guint button,
+ guint activate_time,
+ gpointer user_data)
{
KaApplet *applet = KA_APPLET(user_data);
@@ -458,7 +460,8 @@ ka_tray_icon_on_menu (GtkStatusIcon* status_icon, guint button,
static gboolean
-ka_tray_icon_on_click (GtkStatusIcon* status_icon, gpointer data)
+ka_tray_icon_on_click (GtkStatusIcon* status_icon G_GNUC_UNUSED,
+ gpointer data)
{
KaApplet *applet = KA_APPLET(data);
@@ -469,7 +472,9 @@ ka_tray_icon_on_click (GtkStatusIcon* status_icon, gpointer data)
static gboolean
-ka_applet_cb_show_trayicon (KaApplet* applet, GParamSpec* property, gpointer data)
+ka_applet_cb_show_trayicon (KaApplet* applet,
+ GParamSpec* property G_GNUC_UNUSED,
+ gpointer data G_GNUC_UNUSED)
{
g_return_val_if_fail (applet != NULL, FALSE);
g_return_val_if_fail (applet->priv->tray_icon != NULL, FALSE);
@@ -497,7 +502,6 @@ ka_applet_create_tray_icon (KaApplet* applet)
return TRUE;
}
-
static int
ka_applet_setup_icons (KaApplet* applet)
{
@@ -510,27 +514,6 @@ ka_applet_setup_icons (KaApplet* applet)
return TRUE;
}
-
-static gboolean
-ka_applet_glade_init(KaApplet *applet)
-{
- KaAppletPrivate *priv = applet->priv;
-
- priv->pw_xml = glade_xml_new (KA_DATA_DIR G_DIR_SEPARATOR_S
- PACKAGE ".glade", NULL, NULL);
- priv->pw_label = glade_xml_get_widget (priv->pw_xml, "krb5_wrong_label");
- priv->pw_dialog = glade_xml_get_widget (priv->pw_xml, "krb5_dialog");
-
- return TRUE;
-}
-
-
-GladeXML*
-ka_applet_get_pwdialog_xml(const KaApplet* applet)
-{
- return applet->priv->pw_xml;
-}
-
guint
ka_applet_get_pw_prompt_secs(const KaApplet* applet)
{
@@ -555,39 +538,18 @@ ka_applet_get_tgt_renewable(const KaApplet* applet)
return applet->priv->renewable;
}
-gint ka_applet_run_pw_dialog(const KaApplet* applet)
-{
- return gtk_dialog_run (GTK_DIALOG (applet->priv->pw_dialog));
-}
-
-void
-ka_applet_hide_pw_dialog(KaApplet* applet, gboolean force)
-{
- KA_DEBUG("PW Dialog persist: %d", applet->priv->pw_dialog_persist);
- if (!applet->priv->pw_dialog_persist || force)
- gtk_widget_hide(applet->priv->pw_dialog);
-}
-
-void
-ka_applet_set_pw_dialog_persist(KaApplet* applet, gboolean persist)
+KaPwDialog*
+ka_applet_get_pwdialog(const KaApplet* applet)
{
- applet->priv->pw_dialog_persist = persist;
-}
-
-GtkWidget*
-ka_applet_get_pw_label(const KaApplet* applet)
-{
- return applet->priv->pw_label;
+ return applet->priv->pwdialog;
}
/* create the tray icon applet */
KaApplet*
-ka_applet_create()
+ka_applet_create(GladeXML* xml)
{
KaApplet* applet = ka_applet_new();
- ka_applet_glade_init(applet);
-
if (!(ka_applet_setup_icons (applet)))
g_error ("Failure to setup icons");
if (!ka_applet_create_tray_icon (applet))
@@ -598,6 +560,9 @@ ka_applet_create()
g_signal_connect (applet, "notify::show-trayicon",
G_CALLBACK (ka_applet_cb_show_trayicon), NULL);
+ applet->priv->pwdialog = ka_pwdialog_create(xml);
+ g_return_val_if_fail (applet->priv->pwdialog != NULL, NULL);
+
return applet;
}
diff --git a/src/krb5-auth-applet.h b/src/krb5-auth-applet.h
index a33be55..93830a5 100644
--- a/src/krb5-auth-applet.h
+++ b/src/krb5-auth-applet.h
@@ -21,17 +21,13 @@
#ifndef KRB5_AUTH_APPLET_H
#define KRB5_AUTH_APPLET_H
-#include <glib.h>
#include <glib-object.h>
#include <glib/gprintf.h>
-#include <gtk/gtk.h>
#include <glade/glade.h>
-#ifdef HAVE_LIBNOTIFY
-#include <libnotify/notify.h>
-#endif /* HAVE_LIBNOTIFY */
#include <krb5.h>
#include "config.h"
+#include "krb5-auth-pwdialog.h"
G_BEGIN_DECLS
@@ -52,28 +48,21 @@ typedef struct _KaAppletClass KaAppletClass;
typedef struct _KaAppletPrivate KaAppletPrivate;
GType ka_applet_get_type (void);
-KaApplet* ka_applet_new(void) G_GNUC_MALLOC;
/* public functions */
gboolean ka_applet_get_show_trayicon(const KaApplet* applet);
void ka_applet_set_tgt_renewable(KaApplet* applet, gboolean renewable);
gboolean ka_applet_get_tgt_renewable(const KaApplet* applet);
guint ka_applet_get_pw_prompt_secs(const KaApplet* applet);
-
-/* password dialog */
-gint ka_applet_run_pw_dialog(const KaApplet* applet);
-GladeXML* ka_applet_get_pwdialog_xml(const KaApplet* applet);
-void ka_applet_hide_pw_dialog(KaApplet* applet, gboolean force);
-GtkWidget* ka_applet_get_pw_label(const KaApplet* applet);
-void ka_applet_set_pw_dialog_persist(KaApplet* applet, gboolean persist);
-
-G_END_DECLS
+KaPwDialog* ka_applet_get_pwdialog(const KaApplet* applet);
/* create the applet */
-KaApplet* ka_applet_create();
+KaApplet* ka_applet_create(GladeXML* xml);
/* update tooltip and icon */
int ka_applet_update_status(KaApplet* applet, krb5_timestamp expiry);
+G_END_DECLS
+
#ifdef ENABLE_DEBUG
#define KA_DEBUG(fmt,...) \
g_printf ("DEBUG: %s: " fmt "\n", __func__, ##__VA_ARGS__)
diff --git a/src/krb5-auth-dbus.c b/src/krb5-auth-dbus.c
index b4c8742..52dab46 100644
--- a/src/krb5-auth-dbus.c
+++ b/src/krb5-auth-dbus.c
@@ -22,6 +22,7 @@
#include <dbus/dbus-glib.h>
#include "krb5-auth-applet.h"
+#include "krb5-auth-dialog.h"
#include "krb5-auth-dbus.h"
#include "krb5-auth-applet-dbus-glue.h"
diff --git a/src/krb5-auth-dialog.c b/src/krb5-auth-dialog.c
index dfd5ef5..a45c480 100644
--- a/src/krb5-auth-dialog.c
+++ b/src/krb5-auth-dialog.c
@@ -38,6 +38,7 @@
#include "krb5-auth-dialog.h"
#include "krb5-auth-applet.h"
+#include "krb5-auth-pwdialog.h"
#include "krb5-auth-gconf.h"
#include "krb5-auth-dbus.h"
@@ -56,6 +57,7 @@ static krb5_timestamp canceled_creds_expiry;
static gboolean canceled;
static gboolean invalid_auth;
static gboolean always_run;
+static gboolean is_online = TRUE;
static int grab_credentials (KaApplet* applet);
static int ka_renew_credentials (KaApplet* applet);
@@ -158,6 +160,7 @@ ka_krb5_cc_clear_mcred(krb5_creds* mcred)
#endif
}
+
/* ***************************************************************** */
/* ***************************************************************** */
@@ -197,50 +200,29 @@ out:
}
-static gchar* minutes_to_expiry_text (int minutes)
+/* time in seconds the tgt will be still valid */
+int
+ka_tgt_valid_seconds()
{
- gchar *expiry_text;
- gchar *tmp;
+ krb5_timestamp now;
- if (minutes > 0) {
- expiry_text = g_strdup_printf (ngettext("Your credentials expire in %d minute",
- "Your credentials expire in %d minutes",
- minutes),
- minutes);
- } else {
- expiry_text = g_strdup (_("Your credentials have expired"));
- tmp = g_strdup_printf ("<span foreground=\"red\">%s</span>", expiry_text);
- g_free (expiry_text);
- expiry_text = tmp;
- }
+ if (krb5_timeofday(kcontext, &now))
+ return 0;
- return expiry_text;
+ return (creds_expiry - now);
}
-
-static gboolean
-krb5_auth_dialog_wrong_label_update_expiry (GtkWidget* label)
+/* return credential cache filename, strip "FILE:" prefix if necessary */
+static const char*
+ka_ccache_filename (void)
{
- int minutes_left;
- krb5_timestamp now;
- gchar *expiry_text;
- gchar *expiry_markup;
+ const gchar *ccache_name;
- g_return_val_if_fail (label!= NULL, FALSE);
-
- if (krb5_timeofday(kcontext, &now) != 0) {
- return TRUE;
- }
-
- minutes_left = (creds_expiry - now) / 60;
- expiry_text = minutes_to_expiry_text (minutes_left);
-
- expiry_markup = g_strdup_printf ("<span size=\"smaller\" style=\"italic\">%s</span>", expiry_text);
- gtk_label_set_markup (GTK_LABEL (label), expiry_markup);
- g_free (expiry_text);
- g_free (expiry_markup);
-
- return TRUE;
+ ccache_name = krb5_cc_default_name (kcontext);
+ if (g_str_has_prefix (ccache_name, "FILE:"))
+ return &(ccache_name[5]);
+ else
+ return ccache_name;
}
@@ -249,97 +231,29 @@ static gboolean
krb5_auth_dialog_do_updates (gpointer data)
{
KaApplet* applet = KA_APPLET(data);
+ KaPwDialog* pwdialog = ka_applet_get_pwdialog(applet);
- g_return_val_if_fail (applet != NULL, FALSE);
+ g_return_val_if_fail (pwdialog != NULL, FALSE);
/* Update creds_expiry and close the applet if we got the creds by other means (e.g. kinit) */
if (!credentials_expiring_real(applet))
- ka_applet_hide_pw_dialog(applet, FALSE);
+ ka_pwdialog_hide(pwdialog, FALSE);
/* Update the expiry information in the dialog */
- krb5_auth_dialog_wrong_label_update_expiry (ka_applet_get_pw_label(applet));
+ ka_pwdialog_status_update (pwdialog);
return TRUE;
}
-static void
-krb5_auth_dialog_setup (KaApplet *applet,
- const gchar *krb5prompt,
- gboolean hide_password)
-{
- GtkWidget *entry;
- GtkWidget *label;
- gchar *wrong_text;
- gchar *wrong_markup;
- gchar *prompt;
- int pw4len;
-
- if (krb5prompt == NULL) {
- prompt = g_strdup (_("Please enter your Kerberos password."));
- } else {
- /* Kerberos's prompts are a mess, and basically impossible to
- * translate. There's basically no way short of doing a lot of
- * string parsing to translate them. The most common prompt is
- * "Password for $uid:". We special case that one at least. We
- * cannot do any of the fancier strings (like challenges),
- * though. */
- pw4len = strlen ("Password for ");
- if (strncmp (krb5prompt, "Password for ", pw4len) == 0) {
- gchar *uid = (gchar *) (krb5prompt + pw4len);
- prompt = g_strdup_printf (_("Please enter the password for '%s'"), uid);
- } else {
- prompt = g_strdup (krb5prompt);
- }
- }
-
- /* Clear the password entry field */
- entry = glade_xml_get_widget (ka_applet_get_pwdialog_xml(applet),
- "krb5_entry");
- gtk_secure_entry_set_text (GTK_SECURE_ENTRY (entry), "");
-
- /* Use the prompt label that krb5 provides us */
- label = glade_xml_get_widget (ka_applet_get_pwdialog_xml(applet),
- "krb5_message_label");
- gtk_label_set_text (GTK_LABEL (label), prompt);
-
- /* Add our extra message hints, if any */
- wrong_text = NULL;
-
- if (ka_applet_get_pw_label(applet)) {
- if (invalid_auth) {
- wrong_text = g_strdup (_("The password you entered is invalid"));
- } else {
- krb5_timestamp now;
- int minutes_left;
-
- if (krb5_timeofday(kcontext, &now) == 0)
- minutes_left = (creds_expiry - now) / 60;
- else
- minutes_left = 0;
- wrong_text = minutes_to_expiry_text (minutes_left);
- }
- }
-
- if (wrong_text) {
- wrong_markup = g_strdup_printf ("<span size=\"smaller\" style=\"italic\">%s</span>", wrong_text);
- gtk_label_set_markup (GTK_LABEL (ka_applet_get_pw_label(applet)), wrong_markup);
- g_free(wrong_text);
- g_free(wrong_markup);
- } else {
- gtk_label_set_text (GTK_LABEL (ka_applet_get_pw_label(applet)), "");
- }
- g_free (prompt);
-}
-
-
static krb5_error_code
-auth_dialog_prompter (krb5_context ctx,
+auth_dialog_prompter (krb5_context ctx G_GNUC_UNUSED,
void *data,
- const char *name,
- const char *banner,
+ const char *name G_GNUC_UNUSED,
+ const char *banner G_GNUC_UNUSED,
int num_prompts,
krb5_prompt prompts[])
{
- KaApplet* applet = KA_APPLET(data);
+ KaApplet *applet = KA_APPLET(data);
+ KaPwDialog *pwdialog = ka_applet_get_pwdialog(applet);
krb5_error_code errcode;
int i;
@@ -353,27 +267,22 @@ auth_dialog_prompter (krb5_context ctx,
int response;
guint32 source_id;
- GtkWidget *entry;
-
errcode = KRB5_LIBOS_CANTREADPWD;
- krb5_auth_dialog_setup (applet, (gchar *) prompts[i].prompt, prompts[i].hidden);
- entry = glade_xml_get_widget (ka_applet_get_pwdialog_xml(applet), "krb5_entry");
- gtk_widget_grab_focus (entry);
-
source_id = g_timeout_add_seconds (5, (GSourceFunc)krb5_auth_dialog_do_updates, applet);
- response = ka_applet_run_pw_dialog (applet);
+ ka_pwdialog_setup (pwdialog, (gchar *) prompts[i].prompt, invalid_auth);
+ response = ka_pwdialog_run (pwdialog);
switch (response)
{
case GTK_RESPONSE_OK:
- password = gtk_secure_entry_get_text (GTK_SECURE_ENTRY (entry));
+ password = ka_pwdialog_get_password(pwdialog);
password_len = strlen (password);
break;
+ case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_CANCEL:
canceled = TRUE;
break;
case GTK_RESPONSE_NONE:
- case GTK_RESPONSE_DELETE_EVENT:
break;
default:
g_warning ("Unknown Response: %d", response);
@@ -393,14 +302,13 @@ auth_dialog_prompter (krb5_context ctx,
errcode = 0;
}
cleanup:
- ka_applet_hide_pw_dialog (applet, TRUE);
+ ka_pwdialog_hide (pwdialog, TRUE);
/* Reset this, so we know the next time we get a TRUE value, it is accurate. */
invalid_auth = FALSE;
return errcode;
}
-static gboolean is_online = TRUE;
#ifdef ENABLE_NETWORK_MANAGER
static void
@@ -472,7 +380,7 @@ out:
static void
set_options_from_creds(const KaApplet* applet,
- krb5_context context,
+ krb5_context context G_GNUC_UNUSED,
krb5_creds *in,
krb5_get_init_creds_opt *out)
{
@@ -506,10 +414,10 @@ set_options_from_creds(const KaApplet* applet,
}
+#ifdef ENABLE_PKINIT
static krb5_error_code
ka_auth_pkinit(KaApplet* applet, krb5_creds* creds, const char* pk_userid)
{
-#ifdef ENABLE_PKINIT
krb5_get_init_creds_opt *opts = NULL;
krb5_error_code retval;
@@ -538,16 +446,33 @@ ka_auth_pkinit(KaApplet* applet, krb5_creds* creds, const char* pk_userid)
NULL, auth_dialog_prompter, applet,
0, NULL, opts);
out:
- krb5_get_init_creds_opt_free(kcontext, opts);
+ if (opts)
+ krb5_get_init_creds_opt_free(kcontext, opts);
return retval;
-#else /* ENABLE_PKINIT */
- return 0;
-#endif /* ! ENABLE_PKINIT */
}
+#endif /* ! ENABLE_PKINIT */
+static krb5_error_code
+ka_auth_password(KaApplet* applet, krb5_creds* creds)
+{
+ krb5_error_code retval;
+ krb5_get_init_creds_opt *opts = NULL;
-krb5_error_code
-ka_parse_name(KaApplet* applet, krb5_context kcontext, krb5_principal* kprinc)
+ retval = krb5_get_init_creds_opt_alloc (kcontext, &opts);
+ if (retval)
+ goto out;
+ set_options_from_creds (applet, kcontext, creds, opts);
+ retval = krb5_get_init_creds_password(kcontext, creds, kprincipal,
+ NULL, auth_dialog_prompter, applet,
+ 0, NULL, opts);
+out:
+ if (opts)
+ krb5_get_init_creds_opt_free(kcontext, opts);
+ return retval;
+}
+
+static krb5_error_code
+ka_parse_name(KaApplet* applet, krb5_context krbcontext, krb5_principal* kprinc)
{
krb5_error_code ret;
gchar *principal = NULL;
@@ -555,7 +480,7 @@ ka_parse_name(KaApplet* applet, krb5_context kcontext, krb5_principal* kprinc)
g_object_get(applet, "principal", &principal,
NULL);
- ret = krb5_parse_name(kcontext, principal,
+ ret = krb5_parse_name(krbcontext, principal,
kprinc);
g_free(principal);
@@ -563,18 +488,75 @@ ka_parse_name(KaApplet* applet, krb5_context kcontext, krb5_principal* kprinc)
}
+static void
+ccache_changed_cb (GFileMonitor *monitor G_GNUC_UNUSED,
+ GFile *file,
+ GFile *other_file G_GNUC_UNUSED,
+ GFileMonitorEvent event_type,
+ gpointer data)
+{
+ KaApplet *applet = KA_APPLET(data);
+ gchar *ccache_name = g_file_get_path(file);
+
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_DELETED:
+ case G_FILE_MONITOR_EVENT_CREATED:
+ case G_FILE_MONITOR_EVENT_CHANGED:
+ KA_DEBUG ("%s changed", ccache_name);
+ credentials_expiring ((gpointer)applet);
+ break;
+ default:
+ KA_DEBUG ("%s unhandled event: %d", ccache_name, event_type);
+ }
+ g_free (ccache_name);
+}
+
+
+static gboolean
+monitor_ccache(KaApplet* applet)
+{
+ const gchar *ccache_name;
+ GFile *ccache;
+ GFileMonitor *monitor;
+ GError *err = NULL;
+ gboolean ret = FALSE;
+
+ ccache_name = ka_ccache_filename ();
+ g_return_val_if_fail (ccache_name != NULL, FALSE);
+
+ ccache = g_file_new_for_path (ccache_name);
+ monitor = g_file_monitor_file (ccache, G_FILE_MONITOR_NONE, NULL, &err);
+ g_assert ((!monitor && err) || (monitor && !err));
+ if (!monitor) {
+ /* cache disappeared? */
+ if (err->code == G_FILE_ERROR_NOENT)
+ credentials_expiring ((gpointer)applet);
+ else
+ g_warning ("Failed to monitor %s: %s", ccache_name, err->message);
+ goto out;
+ } else {
+ /* g_file_monitor_set_rate_limit(monitor, 10*1000); */
+ g_signal_connect (monitor, "changed", G_CALLBACK (ccache_changed_cb), applet);
+ KA_DEBUG ("Monitoring %s", ccache_name);
+ ret = TRUE;
+ }
+out:
+ g_object_unref (ccache);
+ if (err)
+ g_error_free (err);
+ return ret;
+}
+
+
/* grab credentials interactively */
static int
grab_credentials (KaApplet* applet)
{
- krb5_error_code retval;
+ krb5_error_code retval = KRB5_KDC_UNREACH;
krb5_creds my_creds;
krb5_ccache ccache;
- krb5_get_init_creds_opt *opt = NULL;
gchar *pk_userid = NULL;
-
- g_object_get(applet, "pk-userid", &pk_userid,
- NULL);
+ gboolean pw_auth = TRUE;
memset(&my_creds, 0, sizeof(my_creds));
@@ -588,21 +570,19 @@ grab_credentials (KaApplet* applet)
if (retval)
goto out2;
-#if ENABLE_PKINIT
- if (pk_userid && strlen(pk_userid)) { /* try pkinit */
-#else
- if (0) {
-#endif
+ g_object_get(applet, "pk-userid", &pk_userid, NULL);
+#ifdef ENABLE_PKINIT
+ /* pk_userid set: try pkinit */
+ if (pk_userid && strlen(pk_userid)) {
retval = ka_auth_pkinit(applet, &my_creds, pk_userid);
- } else {
- retval = krb5_get_init_creds_opt_alloc (kcontext, &opt);
- if (retval)
- goto out;
- set_options_from_creds (applet, kcontext, &my_creds, opt);
- retval = krb5_get_init_creds_password(kcontext, &my_creds, kprincipal,
- NULL, auth_dialog_prompter, applet,
- 0, NULL, opt);
+ /* other error than: "no token found" - no need to try password auth: */
+ if (retval != HX509_PKCS11_NO_TOKEN && retval != HX509_PKCS11_NO_SLOT)
+ pw_auth = FALSE;
}
+#endif /* ENABLE_PKINIT */
+ if (pw_auth)
+ retval = ka_auth_password(applet, &my_creds);
+
creds_expiry = my_creds.times.endtime;
if (canceled)
canceled_creds_expiry = creds_expiry;
@@ -615,7 +595,7 @@ grab_credentials (KaApplet* applet)
#endif
/* Invalid password/pin, try again. */
invalid_auth = TRUE;
- goto out;
+ break;
default:
KA_DEBUG("Auth failed with %d: %s", retval,
get_error_message(kcontext, retval));
@@ -630,15 +610,11 @@ grab_credentials (KaApplet* applet)
retval = krb5_cc_store_cred(kcontext, ccache, &my_creds);
if (retval)
goto out;
-
out:
- if (opt)
- krb5_get_init_creds_opt_free(kcontext, opt);
krb5_free_cred_contents (kcontext, &my_creds);
krb5_cc_close (kcontext, ccache);
out2:
g_free(pk_userid);
-
return retval;
}
@@ -735,7 +711,7 @@ out:
}
static gboolean
-using_krb5()
+using_krb5(void)
{
krb5_error_code err;
gboolean have_tgt = FALSE;
@@ -756,7 +732,8 @@ using_krb5()
void
-ka_destroy_cache (GtkMenuItem *menuitem, gpointer data)
+ka_destroy_cache (GtkMenuItem *menuitem G_GNUC_UNUSED,
+ gpointer data)
{
KaApplet *applet = KA_APPLET(data);
krb5_ccache ccache;
@@ -792,7 +769,6 @@ ka_error_dialog(int err)
gboolean
ka_check_credentials (KaApplet *applet, const char* newprincipal)
{
- gboolean renewable;
gboolean success = FALSE;
int retval;
char* principal;
@@ -843,39 +819,78 @@ ka_grab_credentials (KaApplet* applet)
int retval;
gboolean retry;
int success = FALSE;
+ KaPwDialog *pwdialog = ka_applet_get_pwdialog(applet);
- ka_applet_set_pw_dialog_persist(applet, TRUE);
+ ka_pwdialog_set_persist(pwdialog, TRUE);
do {
- retry = TRUE;
retval = grab_credentials (applet);
if (invalid_auth)
continue;
- switch (retval) {
- case 0: /* success */
- success = TRUE;
- case KRB5_LIBOS_PWDINTR: /* canceled (heimdal) */
- case KRB5_LIBOS_CANTREADPWD: /* canceled (mit) */
- retry = FALSE;
- break;
- case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
- default:
- ka_error_dialog(retval);
- retry = FALSE;
- break;
+ if (canceled)
+ break;
+ if (retval) {
+ ka_error_dialog(retval);
+ break;
+ } else {
+ success = TRUE;
+ break;
}
- } while(retry);
+ } while(TRUE);
- ka_applet_set_pw_dialog_persist(applet, FALSE);
+ ka_pwdialog_set_persist(pwdialog, FALSE);
credentials_expiring_real(applet);
return success;
}
+static void
+ka_secmem_init (void)
+{
+ /* Initialize secure memory. 1 is too small, so the default size
+ will be used. */
+ secmem_init (1);
+ secmem_set_flags (SECMEM_WARN);
+ drop_privs ();
+
+ if (atexit (secmem_term))
+ g_error("Couln't register atexit handler");
+}
+
+
+static gboolean
+ka_nm_init(void)
+{
+#ifdef ENABLE_NETWORK_MANAGER
+ libnm_glib_ctx *nm_context;
+ guint32 nm_callback_id;
+
+ nm_context = libnm_glib_init ();
+ if (!nm_context) {
+ g_warning ("Could not initialize libnm_glib");
+ } else {
+ nm_callback_id = libnm_glib_register_callback (nm_context, network_state_cb, &is_online, NULL);
+ if (nm_callback_id == 0) {
+ libnm_glib_shutdown (nm_context);
+ nm_context = NULL;
+
+ g_warning ("Could not connect to NetworkManager, connection status will not be managed!");
+ }
+ }
+#endif /* ENABLE_NETWORK_MANAGER */
+ return TRUE;
+}
+
+
static GtkWidget*
-ka_create_gtk_secure_entry (GladeXML *xml, gchar *func_name, gchar *name,
- gchar *s1, gchar *s2, gint i1, gint i2,
- gpointer user_data)
+ka_create_gtk_secure_entry (GladeXML *xml G_GNUC_UNUSED,
+ gchar *func_name G_GNUC_UNUSED,
+ gchar *name,
+ gchar *s1 G_GNUC_UNUSED,
+ gchar *s2 G_GNUC_UNUSED,
+ gint i1 G_GNUC_UNUSED,
+ gint i2 G_GNUC_UNUSED,
+ gpointer user_data G_GNUC_UNUSED)
{
GtkWidget* entry = NULL;
@@ -890,26 +905,13 @@ ka_create_gtk_secure_entry (GladeXML *xml, gchar *func_name, gchar *name,
}
-static void
-ka_secmem_init ()
-{
- /* Initialize secure memory. 1 is too small, so the default size
- will be used. */
- secmem_init (1);
- secmem_set_flags (SECMEM_WARN);
- drop_privs ();
-
- if (atexit (secmem_term))
- g_error("Couln't register atexit handler");
-}
-
-
int
main (int argc, char *argv[])
{
KaApplet *applet;
GOptionContext *context;
GError *error = NULL;
+ GladeXML *xml;
guint status = 0;
gboolean run_auto = FALSE, run_always = FALSE;
@@ -923,10 +925,6 @@ main (int argc, char *argv[])
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
};
-#ifdef ENABLE_NETWORK_MANAGER
- libnm_glib_ctx *nm_context;
- guint32 nm_callback_id;
-#endif
context = g_option_context_new ("- Kerberos 5 credential checking");
g_option_context_add_main_entries (context, options, NULL);
g_option_context_add_group (context, gtk_get_option_group (TRUE));
@@ -951,35 +949,24 @@ main (int argc, char *argv[])
}
if (using_krb5 () || always_run) {
g_set_application_name (_("Network Authentication"));
- glade_set_custom_handler (&ka_create_gtk_secure_entry, NULL);
- applet = ka_applet_create ();
+ glade_set_custom_handler (&ka_create_gtk_secure_entry, NULL);
+ xml = glade_xml_new (KA_DATA_DIR G_DIR_SEPARATOR_S
+ PACKAGE ".glade", NULL, NULL);
+ applet = ka_applet_create (xml);
if (!applet)
return 1;
if (!ka_gconf_init (applet, argc, argv))
return 1;
-
-#ifdef ENABLE_NETWORK_MANAGER
- nm_context = libnm_glib_init ();
- if (!nm_context) {
- g_warning ("Could not initialize libnm_glib");
- } else {
- nm_callback_id = libnm_glib_register_callback (nm_context, network_state_cb, &is_online, NULL);
- if (nm_callback_id == 0) {
- libnm_glib_shutdown (nm_context);
- nm_context = NULL;
-
- g_warning ("Could not connect to NetworkManager, connection status will not be managed!");
- }
- }
-#endif /* ENABLE_NETWORK_MANAGER */
+ ka_nm_init();
if (credentials_expiring ((gpointer)applet)) {
g_timeout_add_seconds (CREDENTIAL_CHECK_INTERVAL, (GSourceFunc)credentials_expiring, applet);
+ monitor_ccache (applet);
}
ka_dbus_service(applet);
gtk_main ();
+ g_object_unref(xml);
}
-
return 0;
}
diff --git a/src/krb5-auth-dialog.glade b/src/krb5-auth-dialog.glade
index 7440dff..45ab987 100644
--- a/src/krb5-auth-dialog.glade
+++ b/src/krb5-auth-dialog.glade
@@ -202,7 +202,7 @@
</child>
<child>
- <widget class="GtkLabel" id="krb5_wrong_label">
+ <widget class="GtkLabel" id="krb5_status_label">
<property name="visible">True</property>
<property name="label" translatable="no">&lt;span size=&quot;smaller&quot;&gt; &lt;/span&gt;</property>
<property name="use_underline">False</property>
diff --git a/src/krb5-auth-dialog.h b/src/krb5-auth-dialog.h
index 1ecc93d..3e1219d 100644
--- a/src/krb5-auth-dialog.h
+++ b/src/krb5-auth-dialog.h
@@ -26,5 +26,6 @@
void ka_destroy_cache (GtkMenuItem *menuitem, gpointer user_data);
gboolean ka_grab_credentials(KaApplet* applet);
gboolean ka_check_credentials (KaApplet *applet, const char* principal);
+int ka_tgt_valid_seconds(void);
#endif
diff --git a/src/krb5-auth-gconf.c b/src/krb5-auth-gconf.c
index fd573c1..1481591 100644
--- a/src/krb5-auth-gconf.c
+++ b/src/krb5-auth-gconf.c
@@ -166,7 +166,7 @@ ka_gconf_set_show_trayicon (GConfClient* client, KaApplet* applet)
static void
ka_gconf_key_changed_callback (GConfClient* client,
- guint cnxn_id,
+ guint cnxn_id G_GNUC_UNUSED,
GConfEntry* entry,
gpointer user_data)
{
@@ -193,7 +193,9 @@ ka_gconf_key_changed_callback (GConfClient* client,
gboolean
-ka_gconf_init (KaApplet* applet, int argc, char* argv[])
+ka_gconf_init (KaApplet* applet,
+ int argc G_GNUC_UNUSED,
+ char* argv[] G_GNUC_UNUSED)
{
GError *error = NULL;
GConfClient* client;
diff --git a/src/krb5-auth-pwdialog.c b/src/krb5-auth-pwdialog.c
new file mode 100644
index 0000000..7873a8a
--- /dev/null
+++ b/src/krb5-auth-pwdialog.c
@@ -0,0 +1,246 @@
+/* Krb5 Auth Applet -- Acquire and release kerberos tickets
+ *
+ * (C) 2009 Guido Guenther <agx@sigxcpu.org>
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "krb5-auth-applet.h"
+#include "krb5-auth-dialog.h"
+#include "krb5-auth-pwdialog.h"
+
+struct _KaPwDialog {
+ GObject parent;
+
+ KaPwDialogPrivate *priv;
+};
+
+struct _KaPwDialogClass {
+ GObjectClass parent;
+};
+
+G_DEFINE_TYPE(KaPwDialog, ka_pwdialog, G_TYPE_OBJECT);
+
+struct _KaPwDialogPrivate
+{
+ /* The password dialog */
+ GtkWidget* dialog; /* the password dialog itself */
+ GtkWidget* status_label; /* the wrong password/timeout label */
+ GtkWidget* krb_label; /* krb5 passwort prompt label */
+ GtkWidget* pw_entry; /* password entry field */
+ gboolean persist; /* don't hide the dialog when creds are still valid */
+ gboolean grabbed; /* keyboard grabbed? */
+};
+
+
+static void
+ka_pwdialog_init(KaPwDialog *pwdialog)
+{
+ pwdialog->priv = G_TYPE_INSTANCE_GET_PRIVATE(pwdialog,
+ KA_TYPE_PWDIALOG,
+ KaPwDialogPrivate);
+}
+
+static void
+ka_pwdialog_class_init(KaPwDialogClass *klass)
+{
+ g_type_class_add_private(klass, sizeof(KaPwDialogPrivate));
+
+}
+
+static KaPwDialog*
+ka_pwdialog_new(void)
+{
+ return g_object_new (KA_TYPE_PWDIALOG, NULL);
+}
+
+
+static gboolean
+grab_keyboard (GtkWidget *win, GdkEvent *event, gpointer data)
+{
+ KaPwDialog* pwdialog = KA_PWDIALOG(data);
+
+ GdkGrabStatus status;
+ if (!pwdialog->priv->grabbed) {
+ status = gdk_keyboard_grab (win->window, FALSE, gdk_event_get_time (event));
+ if (status == GDK_GRAB_SUCCESS)
+ pwdialog->priv->grabbed = TRUE;
+ else
+ g_message ("could not grab keyboard: %d", (int)status);
+ }
+ return FALSE;
+}
+
+
+static gboolean
+ungrab_keyboard (GtkWidget *win G_GNUC_UNUSED,
+ GdkEvent *event,
+ gpointer data)
+{
+ KaPwDialog* pwdialog = KA_PWDIALOG(data);
+
+ if (pwdialog->priv->grabbed)
+ gdk_keyboard_ungrab (gdk_event_get_time (event));
+ pwdialog->priv->grabbed = FALSE;
+ return FALSE;
+}
+
+
+static gboolean
+window_state_changed (GtkWidget *win, GdkEventWindowState *event, gpointer data)
+{
+ GdkWindowState state = gdk_window_get_state (win->window);
+
+ if (state & GDK_WINDOW_STATE_WITHDRAWN ||
+ state & GDK_WINDOW_STATE_ICONIFIED ||
+ state & GDK_WINDOW_STATE_FULLSCREEN ||
+ state & GDK_WINDOW_STATE_MAXIMIZED)
+ ungrab_keyboard (win, (GdkEvent*)event, data);
+ else
+ grab_keyboard (win, (GdkEvent*)event, data);
+
+ return FALSE;
+}
+
+
+gint
+ka_pwdialog_run(KaPwDialog* pwdialog)
+{
+ GtkWidget* dialog = pwdialog->priv->dialog;
+
+ /* make sure we pop up on top */
+ gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);
+
+ /*
+ * grab the keyboard so that people don't accidentally type their
+ * passwords in other windows.
+ */
+ g_signal_connect (dialog, "map-event", G_CALLBACK (grab_keyboard), pwdialog);
+ g_signal_connect (dialog, "unmap-event", G_CALLBACK (ungrab_keyboard), pwdialog);
+ g_signal_connect (dialog, "window-state-event", G_CALLBACK (window_state_changed), pwdialog);
+
+ gtk_widget_grab_focus (pwdialog->priv->pw_entry);
+ gtk_widget_show(dialog);
+ return gtk_dialog_run (GTK_DIALOG(dialog));
+}
+
+void
+ka_pwdialog_set_persist (KaPwDialog* pwdialog, gboolean persist)
+{
+ pwdialog->priv->persist = persist;
+}
+
+void
+ka_pwdialog_hide (const KaPwDialog* pwdialog, gboolean force)
+{
+ KA_DEBUG("PW Dialog persist: %d", pwdialog->priv->persist);
+ if (!pwdialog->priv->persist || force)
+ gtk_widget_hide(pwdialog->priv->dialog);
+}
+
+const gchar*
+ka_pwdialog_get_password(KaPwDialog *pwdialog)
+{
+ return gtk_secure_entry_get_text (GTK_SECURE_ENTRY (pwdialog->priv->pw_entry));
+}
+
+gboolean
+ka_pwdialog_status_update (KaPwDialog* pwdialog)
+{
+ gchar *expiry_text;
+ gchar *expiry_markup;
+ int minutes_left = ka_tgt_valid_seconds() / 60;
+
+ g_return_val_if_fail (pwdialog != NULL, FALSE);
+ if (minutes_left > 0) {
+ expiry_text = g_strdup_printf (ngettext("Your credentials expire in %d minute",
+ "Your credentials expire in %d minutes",
+ minutes_left), minutes_left);
+ } else {
+ expiry_text = g_strdup_printf ("<span foreground=\"red\">%s</span>",
+ _("Your credentials have expired"));
+ }
+ expiry_markup = g_strdup_printf ("<span size=\"smaller\" style=\"italic\">%s</span>", expiry_text);
+ gtk_label_set_markup (GTK_LABEL(pwdialog->priv->status_label), expiry_markup);
+ g_free (expiry_text);
+ g_free (expiry_markup);
+
+ return TRUE;
+}
+
+void
+ka_pwdialog_setup (KaPwDialog* pwdialog, const gchar *krb5prompt,
+ gboolean invalid_auth)
+{
+ KaPwDialogPrivate *priv = pwdialog->priv;
+ gchar *wrong_markup = NULL;
+ gchar *prompt;
+ int pw4len;
+
+ if (krb5prompt == NULL) {
+ prompt = g_strdup (_("Please enter your Kerberos password."));
+ } else {
+ /* Kerberos's prompts are a mess, and basically impossible to
+ * translate. There's basically no way short of doing a lot of
+ * string parsing to translate them. The most common prompt is
+ * "Password for $uid:". We special case that one at least. We
+ * cannot do any of the fancier strings (like challenges),
+ * though. */
+ pw4len = strlen ("Password for ");
+ if (strncmp (krb5prompt, "Password for ", pw4len) == 0) {
+ gchar *uid = (gchar *) (krb5prompt + pw4len);
+ prompt = g_strdup_printf (_("Please enter the password for '%s'"), uid);
+ } else {
+ prompt = g_strdup (krb5prompt);
+ }
+ }
+
+ /* Clear the password entry field */
+ gtk_secure_entry_set_text (GTK_SECURE_ENTRY (priv->pw_entry), "");
+
+ /* Use the prompt label that krb5 provides us */
+ gtk_label_set_text (GTK_LABEL (priv->krb_label), prompt);
+
+ /* Add our extra message hints */
+ if (invalid_auth) {
+ wrong_markup = g_strdup_printf ("<span size=\"smaller\" style=\"italic\">%s</span>",
+ _("The password you entered is invalid"));
+ gtk_label_set_markup (GTK_LABEL (priv->status_label), wrong_markup);
+ } else
+ ka_pwdialog_status_update (pwdialog);
+
+ g_free(wrong_markup);
+ g_free (prompt);
+}
+
+KaPwDialog*
+ka_pwdialog_create(GladeXML* xml)
+{
+ KaPwDialog *pwdialog = ka_pwdialog_new();
+ KaPwDialogPrivate *priv = pwdialog->priv;
+
+ priv->dialog = glade_xml_get_widget (xml, "krb5_dialog");
+ priv->status_label = glade_xml_get_widget (xml, "krb5_status_label");
+ priv->pw_entry = glade_xml_get_widget (xml, "krb5_entry");
+ priv->krb_label = glade_xml_get_widget (xml, "krb5_message_label");
+
+ return pwdialog;
+}
+
diff --git a/src/krb5-auth-pwdialog.h b/src/krb5-auth-pwdialog.h
new file mode 100644
index 0000000..efd73e6
--- /dev/null
+++ b/src/krb5-auth-pwdialog.h
@@ -0,0 +1,65 @@
+/* Krb5 Auth Applet -- Acquire and release kerberos tickets
+ *
+ * (C) 2009 Guido Guenther <agx@sigxcpu.org>
+ *
+ * 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.
+ *
+ */
+
+#ifndef KRB5_AUTH_PWDIALOG_H
+#define KRB5_AUTH_PWDIALOG_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glade/glade.h>
+
+#include "config.h"
+#include "gtksecentry.h"
+
+G_BEGIN_DECLS
+
+#define KA_TYPE_PWDIALOG (ka_pwdialog_get_type ())
+#define KA_PWDIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), KA_TYPE_PWDIALOG, KaPwDialog))
+#define KA_PWDIALOG_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), KA_TYPE_PWDIALOG, KaPwDialogClass))
+#define KA_IS_PWDIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KA_TYPE_PWDIALOG))
+#define KA_IS_PWDIALOG_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), KA_TYPE_PWDIALOG))
+#define KA_PWDIALOG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), KA_TYPE_PWDIALOG, KaPwDialogClass))
+
+typedef struct _KaPwDialog KaPwDialog;
+typedef struct _KaPwDialogClass KaPwDialogClass;
+typedef struct _KaPwDialogPrivate KaPwDialogPrivate;
+
+GType ka_pwdialog_get_type (void);
+
+/* public functions */
+KaPwDialog* ka_pwdialog_create(GladeXML *xml);
+/* setup everything for the next prompting */
+void ka_pwdialog_setup (KaPwDialog* pwdialog, const gchar *krb5prompt,
+ gboolean invalid_auth);
+gint ka_pwdialog_run(KaPwDialog *applet);
+void ka_pwdialog_hide(const KaPwDialog *applet, gboolean force);
+void ka_pwdialog_set_persist(KaPwDialog *applet, gboolean persist);
+/* update the expiry information in the status entry */
+gboolean ka_pwdialog_status_update (KaPwDialog *pwdialog);
+const gchar* ka_pwdialog_get_password(KaPwDialog *dialog);
+
+G_END_DECLS
+
+#endif
bgstack15