From aca6027e6ddb0194baf4da1d7453398042054bc0 Mon Sep 17 00:00:00 2001 From: guidog Date: Sat, 10 Jan 2009 13:25:20 +0000 Subject: add a tray icon git-svn-id: http://svn.gnome.org/svn/krb5-auth-dialog/trunk@100 517b70f8-ed25-0410-8bf6-f5db08f7b76e --- ChangeLog | 12 ++ Makefile.am | 2 +- README | 14 ++- configure.ac | 94 ++++++++++++++-- etpo/Makefile.am | 20 +++- icons/Makefile.am | 10 ++ icons/krb-no-valid-ticket.png | Bin 0 -> 1234 bytes icons/krb-valid-ticket.png | Bin 0 -> 1126 bytes src/Makefile.am | 16 ++- src/krb5-auth-applet.c | 238 +++++++++++++++++++++++++++++++++++++++ src/krb5-auth-applet.h | 68 ++++++++++++ src/krb5-auth-dialog.c | 252 +++++++++++++++++++++++++++++------------- src/krb5-auth-dialog.h | 30 +++++ src/krb5-auth-gconf.c | 206 ++++++++++++++++++++++++++++++++++ src/krb5-auth-gconf.h | 28 +++++ src/krb5-auth-notify.c | 57 ++++++++++ src/krb5-auth-notify.h | 32 ++++++ 17 files changed, 988 insertions(+), 91 deletions(-) create mode 100644 icons/Makefile.am create mode 100644 icons/krb-no-valid-ticket.png create mode 100644 icons/krb-valid-ticket.png create mode 100644 src/krb5-auth-applet.c create mode 100644 src/krb5-auth-applet.h create mode 100644 src/krb5-auth-dialog.h create mode 100644 src/krb5-auth-gconf.c create mode 100644 src/krb5-auth-gconf.h create mode 100644 src/krb5-auth-notify.c create mode 100644 src/krb5-auth-notify.h diff --git a/ChangeLog b/ChangeLog index f35a038..a71dd03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Sun Jan 4 14:28:06 CET 2009 Guido Günther + + add a tray icon + * configure.ac: check for libnotify, dbus, gconf + * Makefile.am, icons/krb-{no-,}valid-ticket.png: add icons + * src/krb5-auth-applet.[ch]: new files + * src/krb5-auth-gconf.[ch]: new files + * src/krb5-auth-notify.[ch]: new files + * src/Makefile.am: expand krb5_auth_dialog_SOURCES and + krb5_auth_dialog_LDADD + * README: document gconf keys + 2008-09-26 Guido Guenther * src/krb5-auth-dialog.glade: remove width_request from diff --git a/Makefile.am b/Makefile.am index aed71c3..ce1e5c4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = src po etpo +SUBDIRS = src po etpo icons EXTRA_DIST = \ intltool-extract.in \ diff --git a/README b/README index 1029b29..58a81ea 100644 --- a/README +++ b/README @@ -2,8 +2,20 @@ krb5-auth-dialog is a simple dialog that monitors kerberos tickets, and pops up a dialog when they are about to expire. Eventually, we expect it to be part of GNOME. -A note on translations: +Configuration: +Configuration settings are handled via gconf. + +You can set the principal that is used to acquire tickets via: +gconftool-2 --type=string --set /apps/krb5-auth-dialog/principal "principal@YOUR.REALM" + +You can hide the tray icon via: +gconftool-2 --type=bool --set /apps/krb5-auth-dialog/show_trayicon false +You can set the time of the first password prompt via: +gconftool-2 --type=int --set /apps/krb5-auth-dialog/prompt_minutes 30 + + +A note on translations: Kerberos doesn't translate either its prompts or its error messages. As the prompt is very visible, we need to translate it externally. To do this, the etpo binary in etpo/ can be used to extract the public diff --git a/configure.ac b/configure.ac index 8efdbdb..988e9fd 100644 --- a/configure.ac +++ b/configure.ac @@ -21,12 +21,25 @@ AC_PROG_YACC ALL_LINGUAS="nb" AM_GLIB_GNU_GETTEXT -PKG_CHECK_MODULES(GNOME, -[ - gtk+-2.0 >= 2.4.0 - libglade-2.0 >= 2.4.0 - dbus-glib-1 >= 0.60 -]) +GTK_REQUIRED="2.4.0" +GLADE_REQUIRED="2.4.0" +DBUS_REQUIRED="0.60" +GCONF_REQUIRED="2.8" +LIBNOTIFY_REQUIRED="0.4" + +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) + +dnl --enable-debug=(yes|no) +AC_ARG_ENABLE(debug, + AC_HELP_STRING([--enable-debug=no/yes], + [enable debugging output]),[],[enable_debug=no]) +if test x"$enable_debug" = x"yes"; then + AC_DEFINE(ENABLE_DEBUG, 1, [whether debugging is enabled]) +fi + AC_PATH_PROG([KRB5_CONFIG], krb5-config, none, $PATH:/usr/kerberos/bin) if test "x$KRB5_CONFIG" != "xnone"; then @@ -79,7 +92,6 @@ CFLAGS="$savedCFLAGS" LIBS="$savedLIBS" dnl NetworkManager - AC_MSG_CHECKING([whether to enable NetworkManager support]) AC_ARG_ENABLE([network-manager], AS_HELP_STRING([--enable-network-manager],[Whether to enable automatic network status with NetworkManager]), @@ -96,9 +108,35 @@ fi if test "x$enable_network_manager" = "xyes"; then AC_DEFINE([ENABLE_NETWORK_MANAGER],[1],[Define for NetworkManager support]) fi - AM_CONDITIONAL([ENABLE_NETWORK_MANAGER],[test "x$enable_network_manager" = "xyes"]) +dnl libnotify +LIBNOTIFY_CFLAGS= +LIBNOTIFY_LIBS= +AC_ARG_WITH(libnotify, + [ --with-libnotify use libnotify for status messages], + [], + [with_libnotify=check]) + +if test "x$with_libnotify" = "xyes" -o "x$with_libnotify" = "xcheck"; then + PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= $LIBNOTIFY_REQUIRED, + [with_libnotify=yes], [ + if test "x$with_libnotify" = "xcheck" ; then + with_libnotify=no + else + AC_MSG_ERROR( + [You must install libnotify >= $LIBNOTIFY_REQUIRED to compile krb5-auth-dialog]) + fi + ]) + if test "x$with_libnotify" = "xyes" ; then + AC_DEFINE_UNQUOTED(HAVE_LIBNOTIFY, 1, + [use libnotify for status messages]) + fi +fi +AM_CONDITIONAL(HAVE_LIBNOTIFY, [test "x$with_libnotify" = "xyes"]) +AC_SUBST(LIBNOTIFY_CFLAGS) +AC_SUBST(LIBNOTIFY_LIBS) + check_interval=30 AC_DEFINE_UNQUOTED(CREDENTIAL_CHECK_INTERVAL,[$check_interval], [Define the to number of seconds to wait between checks of @@ -112,13 +150,51 @@ AC_DEFINE_UNQUOTED(MINUTES_BEFORE_PROMPTING,[$minimum_lifetime], fresh credentials.]) AC_SUBST(minimum_lifetime) -CFLAGS="$GNOME_CFLAGS $KRB5_CFLAGS $NETWORK_MANAGER_CFLAGS $CFLAGS" +CFLAGS="\ + $GTK_CFLAGS \ + $GLADE_CFLAGS \ + $DBUS_CFLAGS \ + $GCONF_CFLAGS \ + $KRB5_CFLAGS \ + $NETWORK_MANAGER_CFLAGS \ + $LIBNOTIFY_CFLAGS \ + $CFLAGS" AC_OUTPUT([ Makefile krb5-auth-dialog.spec src/Makefile src/krb5-auth-dialog.1 +icons/Makefile etpo/Makefile po/Makefile.in ]) + +AC_MSG_NOTICE([]) +AC_MSG_NOTICE([Configuration summary]) +AC_MSG_NOTICE([=====================]) +AC_MSG_NOTICE([]) +AC_MSG_NOTICE([Libraries]) +AC_MSG_NOTICE([]) +AC_MSG_NOTICE([ kerberos: $KRB5_CFLAGS $KRB5_LIBS]) +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]) +if test "$with_libnotify" = "yes" ; then +AC_MSG_NOTICE([ libnotify: $LIBNOTIFY_CFLAGS $LIBNOTIFY_LIBS]) +else +AC_MSG_NOTICE([ libnotify: no]) +fi +if test "$enable_network_manager" = "yes" ; then +AC_MSG_NOTICE([ Network Manager: $NETWORK_MANAGER_CFLAGS $NETWORK_MANAGER_LIBS]) +else +AC_MSG_NOTICE([ Network Manager: no]) +fi +AC_MSG_NOTICE([]) +AC_MSG_NOTICE([Miscellaneous]) +AC_MSG_NOTICE([]) +AC_MSG_NOTICE([ Minimum Lifetime: $minimum_lifetime minutes]) +AC_MSG_NOTICE([ Check Interval: $check_interval seconds]) +AC_MSG_NOTICE([]) + diff --git a/etpo/Makefile.am b/etpo/Makefile.am index 4034f53..632ec22 100644 --- a/etpo/Makefile.am +++ b/etpo/Makefile.am @@ -2,7 +2,23 @@ noinst_PROGRAMS = etpo etpo_SOURCES = lexer.l grammar.y lexer.c: grammar.h AM_YFLAGS=-d -AM_CFLAGS=@GNOME_CFLAGS@ -AM_LDFLAGS=@GNOME_LIBS@ +AM_CFLAGS=\ + @GTK_CFLAGS@ \ + @GLADE_CFLAGS@ \ + @DBUS_CFLAGS@ \ + @GCONF_CFLAGS@ \ + @KRB5_CFLAGS@ \ + @NETWORK_MANAGER_CFLAGS@ \ + @LIBNOTIFY_CFLAGS@ \ + @CFLAGS@ +AM_LDFLAGS=\ + @NETWORK_MANAGER_LIBS@ \ + @KRB5_LIBS@ \ + @LIBNOTIFY_LIBS@ \ + @DBUS_LIBS@ \ + @GCONF_LIBS@ \ + @GLADE_LIBS@ \ + @GTK_LIBS@ + DISTCLEANFILES=lexer.c diff --git a/icons/Makefile.am b/icons/Makefile.am new file mode 100644 index 0000000..b771676 --- /dev/null +++ b/icons/Makefile.am @@ -0,0 +1,10 @@ +NULL = + +smallicondir=${datadir}/icons/hicolor/22x22/apps +smallicon_DATA= \ + krb-valid-ticket.png \ + krb-no-valid-ticket.png \ + $(NULL) + +EXTRA_DIST=\ + $(smallicon_DATA) diff --git a/icons/krb-no-valid-ticket.png b/icons/krb-no-valid-ticket.png new file mode 100644 index 0000000..eb9f16e Binary files /dev/null and b/icons/krb-no-valid-ticket.png differ diff --git a/icons/krb-valid-ticket.png b/icons/krb-valid-ticket.png new file mode 100644 index 0000000..f911152 Binary files /dev/null and b/icons/krb-valid-ticket.png differ diff --git a/src/Makefile.am b/src/Makefile.am index b2f4abf..aaf09d9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,9 +12,23 @@ autostart_DATA = $(autostart_in_files:.desktop.in=.desktop) krb5_auth_dialog_SOURCES = \ krb5-auth-dialog.c \ + krb5-auth-dialog.h \ + krb5-auth-applet.c \ + krb5-auth-applet.h \ + krb5-auth-gconf.c \ + krb5-auth-gconf.h \ + krb5-auth-notify.c \ + krb5-auth-notify.h \ dummy-strings.c -krb5_auth_dialog_LDADD = @NETWORK_MANAGER_LIBS@ @KRB5_LIBS@ @GNOME_LIBS@ +krb5_auth_dialog_LDADD = \ + @NETWORK_MANAGER_LIBS@ \ + @KRB5_LIBS@ \ + @LIBNOTIFY_LIBS@ \ + @DBUS_LIBS@ \ + @GCONF_LIBS@ \ + @GLADE_LIBS@ \ + @GTK_LIBS@ gladedir = $(datadir)/krb5-auth-dialog glade_DATA = \ diff --git a/src/krb5-auth-applet.c b/src/krb5-auth-applet.c new file mode 100644 index 0000000..5dc9145 --- /dev/null +++ b/src/krb5-auth-applet.c @@ -0,0 +1,238 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther + * + * 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 + +#include "krb5-auth-applet.h" +#include "krb5-auth-dialog.h" +#ifdef HAVE_LIBNOTIFY +#include "krb5-auth-notify.h" +#endif + + +/* update the tray icon's tooltip and icon */ +int +ka_update_status(Krb5AuthApplet* applet, krb5_timestamp expiry) +{ + gchar* expiry_text; + int interval = expiry - time (0); + static gboolean expiry_notified = FALSE; + + if (interval > 0) { + int hours, minutes; + if (interval >= 3600) { + hours = interval / 3600; + minutes = (interval % 3600) / 60; + expiry_text = g_strdup_printf (_("Your credentials expire in %.2d:%.2dh"), hours, minutes); + } else { + minutes = interval / 60; + expiry_text = g_strdup_printf (ngettext( + "Your credentials expire in %d minute", + "Your credentials expire in %d minutes", + minutes), minutes); + } + gtk_status_icon_set_from_icon_name (applet->tray_icon, applet->icons[1]); +#ifdef HAVE_LIBNOTIFY + if (expiry_notified) { + ka_send_event_notification (applet, NOTIFY_URGENCY_NORMAL, + _("Network credentials valid"), + _("Your Kerberos credentials have been refreshed."), NULL); + expiry_notified = FALSE; + } +#endif + } else { + expiry_text = g_strdup (_("Your credentials have expired")); + gtk_status_icon_set_from_icon_name (applet->tray_icon, applet->icons[0]); +#ifdef HAVE_LIBNOTIFY + if (!expiry_notified) { + ka_send_event_notification (applet, NOTIFY_URGENCY_NORMAL, + _("Network credentials expired"), + _("Your Kerberos credentails have expired."), NULL); + expiry_notified = TRUE; + } +#endif + } + + gtk_status_icon_set_tooltip (applet->tray_icon, expiry_text); + g_free (expiry_text); + return 0; +} + + +static void +ka_menu_add_separator_item (GtkWidget* menu) +{ + GtkWidget* menu_item; + + menu_item = gtk_separator_menu_item_new (); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + gtk_widget_show (menu_item); +} + + +/* Free all resources and quit */ +static void +ka_quit_applet (GtkMenuItem* menuitem, gpointer user_data) +{ + Krb5AuthApplet* applet = (Krb5AuthApplet*) user_data; + + g_free (applet->principal); + g_free (applet); + gtk_main_quit (); +} + + +static void +ka_about_dialog (GtkMenuItem* menuitem, gpointer user_data) +{ + gchar* authors[] = { "Christopher Aillon ", + "Colin Walters ", + "Guido Günther ", + NULL }; + gtk_show_about_dialog (NULL, + "authors", authors, + "version", VERSION, + "copyright", "Copyright (C) 2004,2005,2006 Red Hat, Inc.,\n2008 Guido Günther", + NULL); +} + + +/* The tray icon's context menu */ +static GtkWidget* +ka_create_context_menu (Krb5AuthApplet* applet) +{ + GtkWidget* menu; + GtkWidget* menu_item; + GtkWidget* image; + + menu = gtk_menu_new (); + + /* kdestroy */ + menu_item = gtk_image_menu_item_new_with_mnemonic (_("Remove Credentials _Cache")); + g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (ka_destroy_cache), applet); + image = gtk_image_new_from_stock (GTK_STOCK_CANCEL, GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + + ka_menu_add_separator_item (menu); + + /* About item */ + menu_item = gtk_image_menu_item_new_with_mnemonic (_("_About")); + g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (ka_about_dialog), applet); + image = gtk_image_new_from_stock (GTK_STOCK_ABOUT, GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + + ka_menu_add_separator_item (menu); + + /* Quit */ + menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Quit")); + g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (ka_quit_applet), applet); + image = gtk_image_new_from_stock (GTK_STOCK_QUIT, GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + + gtk_widget_show_all (menu); + + return menu; +} + + +static void +ka_tray_icon_on_menu (GtkStatusIcon* status_icon, guint button, + guint activate_time, gpointer user_data) +{ + Krb5AuthApplet* applet = (Krb5AuthApplet*) user_data; + + KA_DEBUG("Trayicon right clicked: %d", applet->pw_prompt_secs); + gtk_menu_popup (GTK_MENU (applet->context_menu), NULL, NULL, + gtk_status_icon_position_menu, applet->tray_icon, + button, activate_time); +} + + +static gboolean +ka_tray_icon_on_click (GtkStatusIcon* status_icon, gpointer data) +{ + Krb5AuthApplet* applet = (Krb5AuthApplet*) data; + g_return_val_if_fail (applet != NULL, FALSE); + + KA_DEBUG("Trayicon clicked: %d", applet->pw_prompt_secs); + ka_grab_credentials (applet); + return TRUE; +} + + +gboolean +ka_show_tray_icon (Krb5AuthApplet* applet) +{ + g_return_val_if_fail (applet != NULL, FALSE); + g_return_val_if_fail (applet->tray_icon != NULL, FALSE); + + gtk_status_icon_set_visible (applet->tray_icon, applet->show_trayicon); + return TRUE; +} + + +static GtkStatusIcon* +ka_create_tray_icon (Krb5AuthApplet* applet) +{ + GtkStatusIcon* tray_icon; + + tray_icon = gtk_status_icon_new (); + g_signal_connect (G_OBJECT(tray_icon), "activate", + G_CALLBACK(ka_tray_icon_on_click), applet); + g_signal_connect (G_OBJECT(tray_icon), + "popup-menu", + G_CALLBACK(ka_tray_icon_on_menu), applet); + gtk_status_icon_set_from_icon_name (tray_icon, applet->icons[0]); + gtk_status_icon_set_tooltip (tray_icon, PACKAGE); + return tray_icon; +} + + +int +ka_setup_icons (Krb5AuthApplet* applet) +{ + applet->icons[0] = "krb-no-valid-ticket"; + applet->icons[1] = "krb-valid-ticket"; + return TRUE; +} + + +/* create the tray icon applet */ +Krb5AuthApplet* +ka_create_applet() +{ + Krb5AuthApplet* applet = g_malloc0 (sizeof(Krb5AuthApplet)); + + if (!(ka_setup_icons (applet))) + g_error ("Failure to setup icons"); + if (!(applet->tray_icon = ka_create_tray_icon (applet))) + g_error ("Failure to create tray icon"); + if (!(applet->context_menu = ka_create_context_menu (applet))) + g_error ("Failure to create context menu"); + ka_show_tray_icon (applet); + + return applet; +} + diff --git a/src/krb5-auth-applet.h b/src/krb5-auth-applet.h new file mode 100644 index 0000000..062e148 --- /dev/null +++ b/src/krb5-auth-applet.h @@ -0,0 +1,68 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther + * + * 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_APPLET_H +#define KRB5_AUTH_APPLET_H + +#include +#include +#include +#include +#ifdef HAVE_LIBNOTIFY +#include +#endif /* HAVE_LIBNOTIFY */ +#include + +#include "config.h" + +typedef struct { + GtkStatusIcon* tray_icon; /* the tray icon */ + GtkWidget* context_menu; /* the tray icon's context menu */ + const char* icons[2]; /* for expired 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_wrong_label; /* the wrong password/timeout label */ + 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 */ +#endif /* HAVE_LIBNOTIFY */ + char* principal; /* the principal to request */ +} Krb5AuthApplet; + +Krb5AuthApplet* ka_create_applet(); +/* update tooltip and icon */ +int ka_update_status(Krb5AuthApplet* applet, krb5_timestamp expiry); +/* show or hide the tray icon */ +gboolean ka_show_tray_icon(Krb5AuthApplet* applet); + +#ifdef ENABLE_DEBUG +#define KA_DEBUG(fmt,...) \ + g_printf ("DEBUG: %s: " fmt "\n", __func__, __VA_ARGS__) +#else +#define KA_DEBUG(fmt,...) \ + do { } while (0) +#endif /* !ENABLE_DEBUG */ + +#endif diff --git a/src/krb5-auth-dialog.c b/src/krb5-auth-dialog.c index 38eeb6c..9942d35 100644 --- a/src/krb5-auth-dialog.c +++ b/src/krb5-auth-dialog.c @@ -31,12 +31,14 @@ #include #include +#include "krb5-auth-dialog.h" +#include "krb5-auth-applet.h" +#include "krb5-auth-gconf.h" #ifdef ENABLE_NETWORK_MANAGER #include #endif -static GladeXML *xml = NULL; static krb5_context kcontext; static krb5_principal kprincipal; static krb5_timestamp creds_expiry; @@ -45,7 +47,7 @@ static gboolean canceled; static gboolean invalid_password; static gboolean always_run; -static int grab_credentials (gboolean renewable); +static int grab_credentials (Krb5AuthApplet* applet, gboolean renewable); static gboolean get_tgt_from_ccache (krb5_context context, krb5_creds *creds); /* YAY for different Kerberos implementations */ @@ -121,6 +123,42 @@ get_principal_realm_data(krb5_principal p) /* ***************************************************************** */ /* ***************************************************************** */ +static gboolean +credentials_expiring_real (Krb5AuthApplet* applet, gboolean *renewable) +{ + krb5_creds my_creds; + krb5_timestamp now; + gboolean retval = FALSE; + *renewable = FALSE; + + if (!get_tgt_from_ccache (kcontext, &my_creds)) { + creds_expiry = 0; + retval = TRUE; + goto out; + } + + if (krb5_principal_compare (kcontext, my_creds.client, kprincipal)) { + krb5_free_principal(kcontext, kprincipal); + krb5_copy_principal(kcontext, my_creds.client, &kprincipal); + } + creds_expiry = my_creds.times.endtime; + if ((krb5_timeofday(kcontext, &now) == 0) && + (now + applet->pw_prompt_secs > my_creds.times.endtime)) + retval = TRUE; + + /* If our creds are expiring, determine whether they are renewable */ + if (retval && get_cred_renewable(&my_creds) && my_creds.times.renew_till > now) { + *renewable = TRUE; + } + + krb5_free_cred_contents (kcontext, &my_creds); + +out: + ka_update_status(applet, creds_expiry); + return retval; +} + + static gchar* minutes_to_expiry_text (int minutes) { gchar *expiry_text; @@ -141,16 +179,16 @@ static gchar* minutes_to_expiry_text (int minutes) return expiry_text; } + static gboolean -krb5_auth_dialog_wrong_label_update_expiry (gpointer data) +krb5_auth_dialog_wrong_label_update_expiry (GtkWidget* label) { - GtkWidget *label = GTK_WIDGET(data); int minutes_left; krb5_timestamp now; gchar *expiry_text; gchar *expiry_markup; - g_return_val_if_fail (label != NULL, FALSE); + g_return_val_if_fail (label!= NULL, FALSE); if (krb5_timeofday(kcontext, &now) != 0) { return TRUE; @@ -167,19 +205,42 @@ krb5_auth_dialog_wrong_label_update_expiry (gpointer data) return TRUE; } + +/* Check for things we have to do while the password dialog is open */ +static gboolean +krb5_auth_dialog_do_updates (gpointer data) +{ + Krb5AuthApplet* applet = (Krb5AuthApplet*)data; + gboolean refreshable; + + g_return_val_if_fail (applet != 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, &refreshable)) { + KA_DEBUG("PW Dialog persist is %d", applet->pw_dialog_persist); + if (!applet->pw_dialog_persist) + gtk_widget_hide(applet->pw_dialog); + } + + /* Update the expiry information in the dialog */ + krb5_auth_dialog_wrong_label_update_expiry (applet->pw_wrong_label); + return TRUE; +} + + static void -krb5_auth_dialog_setup (GtkWidget *dialog, +krb5_auth_dialog_setup (Krb5AuthApplet *applet, const gchar *krb5prompt, gboolean hide_password) { GtkWidget *entry; GtkWidget *label; - GtkWidget *wrong_label; gchar *wrong_text; gchar *wrong_markup; gchar *prompt; int pw4len; + if (krb5prompt == NULL) { prompt = g_strdup (_("Please enter your Kerberos password.")); } else { @@ -199,47 +260,44 @@ krb5_auth_dialog_setup (GtkWidget *dialog, } /* Clear the password entry field */ - entry = glade_xml_get_widget (xml, "krb5_entry"); + entry = glade_xml_get_widget (applet->pw_xml, "krb5_entry"); gtk_entry_set_text (GTK_ENTRY (entry), ""); gtk_entry_set_visibility (GTK_ENTRY (entry), !hide_password); /* Use the prompt label that krb5 provides us */ - label = glade_xml_get_widget (xml, "krb5_message_label"); + label = glade_xml_get_widget (applet->pw_xml, "krb5_message_label"); gtk_label_set_text (GTK_LABEL (label), prompt); /* Add our extra message hints, if any */ - wrong_label = glade_xml_get_widget (xml, "krb5_wrong_label"); wrong_text = NULL; - if (wrong_label) { + if (applet->pw_wrong_label) { if (invalid_password) { wrong_text = g_strdup (_("The password you entered is invalid")); } else { krb5_timestamp now; int minutes_left; - if (krb5_timeofday(kcontext, &now) == 0) { + if (krb5_timeofday(kcontext, &now) == 0) minutes_left = (creds_expiry - now) / 60; - } else { + else minutes_left = 0; - } - wrong_text = minutes_to_expiry_text (minutes_left); } } if (wrong_text) { wrong_markup = g_strdup_printf ("%s", wrong_text); - gtk_label_set_markup (GTK_LABEL (wrong_label), wrong_markup); + gtk_label_set_markup (GTK_LABEL (applet->pw_wrong_label), wrong_markup); g_free(wrong_text); g_free(wrong_markup); } else { - gtk_label_set_text (GTK_LABEL (wrong_label), ""); + gtk_label_set_text (GTK_LABEL (applet->pw_wrong_label), ""); } - g_free (prompt); } + static krb5_error_code auth_dialog_prompter (krb5_context ctx, void *data, @@ -248,8 +306,7 @@ auth_dialog_prompter (krb5_context ctx, int num_prompts, krb5_prompt prompts[]) { - GtkWidget *dialog; - GtkWidget *wrong_label; + Krb5AuthApplet* applet = (Krb5AuthApplet*)data; krb5_error_code errcode; int i; @@ -257,8 +314,6 @@ auth_dialog_prompter (krb5_context ctx, canceled = FALSE; canceled_creds_expiry = 0; - dialog = glade_xml_get_widget (xml, "krb5_dialog"); - for (i = 0; i < num_prompts; i++) { const gchar *password = NULL; int password_len = 0; @@ -269,15 +324,12 @@ auth_dialog_prompter (krb5_context ctx, errcode = KRB5_LIBOS_CANTREADPWD; - entry = glade_xml_get_widget(xml, "krb5_entry"); - krb5_auth_dialog_setup (dialog, (gchar *) prompts[i].prompt, prompts[i].hidden); + entry = glade_xml_get_widget (applet->pw_xml, "krb5_entry"); + krb5_auth_dialog_setup (applet, (gchar *) prompts[i].prompt, prompts[i].hidden); gtk_widget_grab_focus (entry); - wrong_label = glade_xml_get_widget (xml, "krb5_wrong_label"); - source_id = g_timeout_add_seconds (5, (GSourceFunc)krb5_auth_dialog_wrong_label_update_expiry, - wrong_label); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); + source_id = g_timeout_add_seconds (5, (GSourceFunc)krb5_auth_dialog_do_updates, applet); + response = gtk_dialog_run (GTK_DIALOG (applet->pw_dialog)); switch (response) { case GTK_RESPONSE_OK: @@ -288,6 +340,7 @@ auth_dialog_prompter (krb5_context ctx, case GTK_RESPONSE_CANCEL: canceled = TRUE; break; + case GTK_RESPONSE_NONE: case GTK_RESPONSE_DELETE_EVENT: break; default: @@ -302,7 +355,7 @@ auth_dialog_prompter (krb5_context ctx, } /* Reset this, so we know the next time we get a TRUE value, it is accurate. */ - gtk_widget_hide (dialog); + gtk_widget_hide (applet->pw_dialog); invalid_password = FALSE; return errcode; @@ -338,37 +391,6 @@ network_state_cb (libnm_glib_ctx *context, } #endif -static gboolean -credentials_expiring_real (gboolean *renewable) -{ - krb5_creds my_creds; - krb5_timestamp now; - gboolean retval = FALSE; - *renewable = FALSE; - - if (!get_tgt_from_ccache (kcontext, &my_creds)) { - creds_expiry = 0; - return TRUE; - } - - if (krb5_principal_compare (kcontext, my_creds.client, kprincipal)) { - krb5_free_principal(kcontext, kprincipal); - krb5_copy_principal(kcontext, my_creds.client, &kprincipal); - } - creds_expiry = my_creds.times.endtime; - if ((krb5_timeofday(kcontext, &now) == 0) && - (now + MINUTES_BEFORE_PROMPTING * 60 > my_creds.times.endtime)) - retval = TRUE; - - /* If our creds are expiring, determine whether they are renewable */ - if (retval && get_cred_renewable(&my_creds) && my_creds.times.renew_till > now) { - *renewable = TRUE; - } - - krb5_free_cred_contents (kcontext, &my_creds); - - return retval; -} static gboolean credentials_expiring (gpointer *data) @@ -376,12 +398,14 @@ credentials_expiring (gpointer *data) int retval; gboolean give_up; gboolean renewable; + Krb5AuthApplet* applet = (Krb5AuthApplet*) data; - if (credentials_expiring_real (&renewable) && is_online) { + KA_DEBUG("Checking expiry: %d", applet->pw_prompt_secs); + if (credentials_expiring_real (applet, &renewable) && is_online) { give_up = canceled && (creds_expiry == canceled_creds_expiry); if (!give_up) { do { - retval = grab_credentials (renewable); + retval = grab_credentials (applet, renewable); give_up = canceled && (creds_expiry == canceled_creds_expiry); } while ((retval != 0) && @@ -391,12 +415,14 @@ credentials_expiring (gpointer *data) !give_up); } } - + ka_update_status(applet, creds_expiry); return TRUE; } + static void -set_options_using_creds(krb5_context context, +set_options_using_creds(const Krb5AuthApplet* applet, + krb5_context context, krb5_creds *creds, krb5_get_init_creds_opt *opts) { @@ -415,7 +441,7 @@ set_options_using_creds(krb5_context context, renew_lifetime); } if (creds->times.endtime > - creds->times.starttime + MINUTES_BEFORE_PROMPTING * 60) { + creds->times.starttime + applet->pw_prompt_secs) { krb5_get_init_creds_opt_set_tkt_life(opts, creds->times.endtime - creds->times.starttime); @@ -425,7 +451,7 @@ set_options_using_creds(krb5_context context, } static int -grab_credentials (gboolean renewable) +grab_credentials (Krb5AuthApplet* applet, gboolean renewable) { krb5_error_code retval; krb5_creds my_creds; @@ -435,7 +461,7 @@ grab_credentials (gboolean renewable) memset(&my_creds, 0, sizeof(my_creds)); if (kprincipal == NULL) { - retval = krb5_parse_name(kcontext, g_get_user_name (), + retval = krb5_parse_name(kcontext, applet->principal, &kprincipal); if (retval) { return retval; @@ -448,7 +474,7 @@ grab_credentials (gboolean renewable) krb5_get_init_creds_opt_init (&opts); if (get_tgt_from_ccache (kcontext, &my_creds)) { - set_options_using_creds (kcontext, &my_creds, &opts); + set_options_using_creds (applet, kcontext, &my_creds, &opts); creds_expiry = my_creds.times.endtime; if (renewable) { @@ -466,7 +492,7 @@ grab_credentials (gboolean renewable) } retval = krb5_get_init_creds_password(kcontext, &my_creds, kprincipal, - NULL, auth_dialog_prompter, NULL, + NULL, auth_dialog_prompter, applet, 0, NULL, &opts); if (canceled) { canceled_creds_expiry = creds_expiry; @@ -567,10 +593,74 @@ using_krb5() return have_tgt; } + +void +ka_destroy_cache (GtkMenuItem *menuitem, gpointer data) +{ + Krb5AuthApplet* applet = (Krb5AuthApplet*) data; + krb5_ccache ccache; + const char* cache; + krb5_error_code ret; + gboolean renewable; + + cache = krb5_cc_default_name(kcontext); + ret = krb5_cc_resolve(kcontext, cache, &ccache); + ret = krb5_cc_destroy (kcontext, ccache); + + credentials_expiring_real(applet, &renewable); +} + + +static void +ka_error_dialog(int err) +{ + const char* msg = error_message(err); + GtkWidget *dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _("Couldn't acquire kerberos ticket: '%s'"), msg); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + + +/* this is done on leftclick, update the tooltip immediately */ +void +ka_grab_credentials (Krb5AuthApplet* applet) +{ + int retval; + gboolean renewable, retry; + + applet->pw_dialog_persist = TRUE; + do { + retry = TRUE; + retval = grab_credentials (applet, FALSE); + switch (retval) { + case KRB5KRB_AP_ERR_BAD_INTEGRITY: + retry = TRUE; + break; + case 0: /* success */ + case KRB5_LIBOS_CANTREADPWD: /* canceled */ + retry = FALSE; + break; + case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: + default: + ka_error_dialog(retval); + retry = FALSE; + break; + } + } while(retry); + + applet->pw_dialog_persist = FALSE; + credentials_expiring_real(applet, &renewable); +} + + int main (int argc, char *argv[]) { - GtkWidget *dialog; + Krb5AuthApplet *applet; GOptionContext *context; GError *error = NULL; DBusGConnection *session; @@ -649,7 +739,19 @@ main (int argc, char *argv[]) always_run = TRUE; } if (using_krb5 () || always_run) { + applet = ka_create_applet (); + if (!applet) + return 1; + if (!ka_gconf_init (applet, argc, argv)) + return 1; + + /* setup the pw dialog */ + applet->pw_xml = glade_xml_new (GLADEDIR "krb5-auth-dialog.glade", NULL, NULL); + applet->pw_wrong_label = glade_xml_get_widget (applet->pw_xml, "krb5_wrong_label"); + applet->pw_dialog = glade_xml_get_widget (applet->pw_xml, "krb5_dialog"); + g_set_application_name (_("Network Authentication")); + gtk_window_set_default_icon_name (applet->icons[1]); #ifdef ENABLE_NETWORK_MANAGER nm_context = libnm_glib_init (); @@ -666,12 +768,8 @@ main (int argc, char *argv[]) } #endif /* ENABLE_NETWORK_MANAGER */ - xml = glade_xml_new (GLADEDIR "krb5-auth-dialog.glade", NULL, NULL); - dialog = glade_xml_get_widget (xml, "krb5_dialog"); - gtk_window_set_default_icon_name ("gtk-dialog-authentication"); - - if (credentials_expiring (NULL)) { - g_timeout_add_seconds (CREDENTIAL_CHECK_INTERVAL * 1000, (GSourceFunc)credentials_expiring, NULL); + if (credentials_expiring ((gpointer)applet)) { + g_timeout_add_seconds (CREDENTIAL_CHECK_INTERVAL, (GSourceFunc)credentials_expiring, applet); } gtk_main (); } diff --git a/src/krb5-auth-dialog.h b/src/krb5-auth-dialog.h new file mode 100644 index 0000000..77a9891 --- /dev/null +++ b/src/krb5-auth-dialog.h @@ -0,0 +1,30 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther + * + * 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_DIALOG +#define KRB5_AUTH_DIALOG + +#include "krb5-auth-applet.h" + +void ka_destroy_cache (GtkMenuItem *menuitem, gpointer user_data); +void ka_grab_credentials(Krb5AuthApplet* applet); + +#endif + diff --git a/src/krb5-auth-gconf.c b/src/krb5-auth-gconf.c new file mode 100644 index 0000000..20d22ce --- /dev/null +++ b/src/krb5-auth-gconf.c @@ -0,0 +1,206 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther + * + * 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 + +#include "krb5-auth-applet.h" +#include "krb5-auth-gconf.h" + +#define KA_GCONF_PATH "/apps/" PACKAGE +#define KA_GCONF_KEY_PRINCIPAL KA_GCONF_PATH "/principal" +#define KA_GCONF_KEY_PROMPT_MINS KA_GCONF_PATH "/prompt_minutes" +#define KA_GCONF_KEY_SHOW_TRAYICON KA_GCONF_PATH "/show_trayicon" + +static gboolean +ka_gconf_get_string (GConfClient* client, + const char* key, + char** value) +{ + GError* error = NULL; + gboolean success = FALSE; + GConfValue* gc_value; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (*value == NULL, FALSE); + + if ((gc_value = gconf_client_get (client, key, &error))) { + if (gc_value->type == GCONF_VALUE_STRING) { + *value = g_strdup (gconf_value_get_string (gc_value)); + success = TRUE; + } else if (error) { + g_print (error->message); + g_error_free (error); + } + gconf_value_free (gc_value); + } + return success; +} + + +static gboolean +ka_gconf_get_int (GConfClient* client, + const char* key, + int* value) +{ + GError* error = NULL; + gboolean success = FALSE; + GConfValue* gc_value; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + if ((gc_value = gconf_client_get (client, key, &error))) + { + if (gc_value->type == GCONF_VALUE_INT) { + *value = gconf_value_get_int (gc_value); + success = TRUE; + } else if (error) { + g_print (error->message); + g_error_free (error); + } + gconf_value_free (gc_value); + } + return success; +} + + +static gboolean +ka_gconf_get_bool (GConfClient* client, + const char* key, + gboolean* value) +{ + GError* error = NULL; + gboolean success = FALSE; + GConfValue* gc_value; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + if ((gc_value = gconf_client_get (client, key, &error))) + { + if (gc_value->type == GCONF_VALUE_BOOL) { + *value = gconf_value_get_bool (gc_value); + success = TRUE; + } else if (error) { + g_print (error->message); + g_error_free (error); + } + gconf_value_free (gc_value); + } + return success; +} + + +static gboolean +ka_gconf_set_principal (GConfClient* client, Krb5AuthApplet* applet) +{ + g_free (applet->principal); + applet->principal = NULL; + if(!ka_gconf_get_string (client, KA_GCONF_KEY_PRINCIPAL, &applet->principal)) { + applet->principal = g_strdup (g_get_user_name()); + } + KA_DEBUG("Setting principal to %s", applet->principal); + // FIXME: need to send set-principal signal + return TRUE; +} + + +static gboolean +ka_gconf_set_prompt_mins (GConfClient* client, Krb5AuthApplet* applet) +{ + if(!ka_gconf_get_int (client, KA_GCONF_KEY_PROMPT_MINS, &applet->pw_prompt_secs)) { + applet->pw_prompt_secs = MINUTES_BEFORE_PROMPTING; + } + applet->pw_prompt_secs *= 60; + KA_DEBUG("Setting prompting timer to %d seconds", applet->pw_prompt_secs); + return TRUE; +} + + +static gboolean +ka_gconf_set_show_trayicon (GConfClient* client, Krb5AuthApplet* applet) +{ + if(!ka_gconf_get_bool(client, KA_GCONF_KEY_SHOW_TRAYICON, &applet->show_trayicon)) { + applet->show_trayicon = TRUE; + } + KA_DEBUG("Show trayicon: %s", (applet->show_trayicon ? "yes" : "no" )); + // FIXME: send show trayicon signal + ka_show_tray_icon(applet); + return TRUE; +} + + +static void +ka_gconf_key_changed_callback (GConfClient* client, + guint cnxn_id, + GConfEntry* entry, + gpointer user_data) +{ + const char* key; + + Krb5AuthApplet* applet = (Krb5AuthApplet*)user_data; + key = gconf_entry_get_key (entry); + if (!key) + return; + KA_DEBUG("Key %s changed", key); + + if (g_strcmp0 (key, KA_GCONF_KEY_PRINCIPAL) == 0) { + ka_gconf_set_principal (client, applet); + } else if (g_strcmp0 (key, KA_GCONF_KEY_PROMPT_MINS) == 0) { + ka_gconf_set_prompt_mins (client, applet); + } else if (g_strcmp0 (key, KA_GCONF_KEY_SHOW_TRAYICON) == 0) { + ka_gconf_set_show_trayicon (client, applet); + } else + g_warning("Received notification for unknown gconf key %s", key); + return; +} + + +gboolean +ka_gconf_init (Krb5AuthApplet* applet, int argc, char* argv[]) +{ + GError *error = NULL; + GConfClient* client; + gboolean success = FALSE; + + client = gconf_client_get_default (); + gconf_client_add_dir (client, KA_GCONF_PATH, GCONF_CLIENT_PRELOAD_ONELEVEL, &error); + if (error) + goto out; + + gconf_client_notify_add (client, KA_GCONF_PATH, + ka_gconf_key_changed_callback, applet, NULL, &error); + if (error) + goto out; + + /* setup defaults */ + ka_gconf_set_principal (client, applet); + ka_gconf_set_prompt_mins (client, applet); + ka_gconf_set_show_trayicon (client, applet); + + success = TRUE; +out: + if(error) { + g_print (error->message); + g_error_free (error); + } + return success; +} diff --git a/src/krb5-auth-gconf.h b/src/krb5-auth-gconf.h new file mode 100644 index 0000000..ec85704 --- /dev/null +++ b/src/krb5-auth-gconf.h @@ -0,0 +1,28 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther + * + * 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_GCONF_H +#define KRB5_AUTH_GCONF_H + +#include "krb5-auth-applet.h" + +gboolean ka_gconf_init (Krb5AuthApplet* applet, int argc, char* argv[]); + +#endif diff --git a/src/krb5-auth-notify.c b/src/krb5-auth-notify.c new file mode 100644 index 0000000..3186a47 --- /dev/null +++ b/src/krb5-auth-notify.c @@ -0,0 +1,57 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther + * + * 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" + +#ifdef HAVE_LIBNOTIFY + +#include "krb5-auth-applet.h" +#include "krb5-auth-notify.h" + +void +ka_send_event_notification (Krb5AuthApplet *applet, + NotifyUrgency urgency, + const char *summary, + const char *message, + const char *icon) +{ + const char *notify_icon; + + g_return_if_fail (applet != NULL); + g_return_if_fail (summary != NULL); + g_return_if_fail (message != NULL); + + if (!notify_is_initted ()) + notify_init (PACKAGE); + + if (applet->notification != NULL) { + notify_notification_close (applet->notification, NULL); + g_object_unref (applet->notification); + } + + notify_icon = icon ? icon : "gtk-dialog-authentication"; + + applet->notification = \ + notify_notification_new_with_status_icon(summary, message, notify_icon, applet->tray_icon); + + notify_notification_set_urgency (applet->notification, urgency); + notify_notification_show (applet->notification, NULL); +} + +#endif /* HAVE_LIBNOTIFY */ diff --git a/src/krb5-auth-notify.h b/src/krb5-auth-notify.h new file mode 100644 index 0000000..7d27b8a --- /dev/null +++ b/src/krb5-auth-notify.h @@ -0,0 +1,32 @@ +/* Krb5 Auth Applet -- Acquire and release kerberos tickets + * + * (C) 2008 Guido Guenther + * + * 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_NOTIFY_H +#define KRB5_AUTH_NOTIFY_H + +#include + +void ka_send_event_notification (Krb5AuthApplet *applet, + NotifyUrgency urgency, + const char *summary, + const char *message, + const char *icon); +#endif + -- cgit v1.2.3