diff options
-rw-r--r-- | .cvsignore | 31 | ||||
-rw-r--r-- | ChangeLog | 67 | ||||
-rw-r--r-- | acinclude.m4 | 88 | ||||
-rw-r--r-- | configure.ac | 15 | ||||
-rw-r--r-- | etpo/.cvsignore | 6 | ||||
-rw-r--r-- | m4/compiler-flags.m4 | 40 | ||||
-rw-r--r-- | po/.cvsignore | 10 | ||||
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | po/krb5-auth-dialog.pot | 2 | ||||
-rw-r--r-- | src/.cvsignore | 5 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/dummy-strings.c | 4 | ||||
-rw-r--r-- | src/krb5-auth-applet.c | 117 | ||||
-rw-r--r-- | src/krb5-auth-applet.h | 21 | ||||
-rw-r--r-- | src/krb5-auth-dbus.c | 1 | ||||
-rw-r--r-- | src/krb5-auth-dialog.c | 417 | ||||
-rw-r--r-- | src/krb5-auth-dialog.glade | 2 | ||||
-rw-r--r-- | src/krb5-auth-dialog.h | 1 | ||||
-rw-r--r-- | src/krb5-auth-gconf.c | 6 | ||||
-rw-r--r-- | src/krb5-auth-pwdialog.c | 246 | ||||
-rw-r--r-- | src/krb5-auth-pwdialog.h | 65 |
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 - @@ -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"><span size="smaller"> </span></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 |