Index: src/krb5-auth-dialog.c
===================================================================
--- src/krb5-auth-dialog.c	(revision 124)
+++ src/krb5-auth-dialog.c	(working copy)
@@ -36,6 +36,7 @@
 
 #include "krb5-auth-dialog.h"
 #include "krb5-auth-applet.h"
+#include "krb5-auth-keyring.h"
 #include "krb5-auth-gconf.h"
 #include "krb5-auth-dbus.h"
 
@@ -348,16 +349,32 @@
 	canceled = FALSE;
 	canceled_creds_expiry = 0;
 
+	ka_keyring_free_items (applet);
+	ka_keyring_alloc_items (applet, num_prompts);
+
 	for (i = 0; i < num_prompts; i++) {
 		const gchar *password = NULL;
 		int password_len = 0;
 		int response;
 		guint32 source_id;
+		GnomeKeyringResult rc;
 
 		GtkWidget *entry;
 
 		errcode = KRB5_LIBOS_CANTREADPWD;
 
+		/* try gnome keyring first */
+		rc = ka_keyring_find_password (applet, prompts, i);
+		if (rc == GNOME_KEYRING_RESULT_OK) {
+			prompts[i].reply->data = (char *) applet->kr.passwd[i];
+			prompts[i].reply->length = strlen (
+				applet->kr.passwd[i]);
+			errcode = 0;
+			continue;
+		} else if (applet->kr_only) { /* no popup */
+			goto cleanup;
+		}
+
 		krb5_auth_dialog_setup (applet, (gchar *) prompts[i].prompt, prompts[i].hidden);
 		entry = glade_xml_get_widget (applet->pw_xml, "krb5_entry");
 		gtk_widget_grab_focus (entry);
@@ -369,6 +386,12 @@
 			case GTK_RESPONSE_OK:
 				password = gtk_secure_entry_get_text (GTK_SECURE_ENTRY (entry));
 				password_len = strlen (password);
+
+				/* got new, store in gnome keyring */
+				ka_keyring_store_password (applet,
+				                           prompts[i].prompt,
+				                           password);
+
 				break;
 			case GTK_RESPONSE_CANCEL:
 				canceled = TRUE;
@@ -448,8 +471,17 @@
 		}
 
 		/* no popup when using a trayicon */
-		if (applet->show_trayicon)
+		if (applet->show_trayicon) {
+			/* one ping only, please (gnome keyring only) */
+			if (applet->use_keyring) {
+			        KA_DEBUG("Tray icon visible, keyring only try");
+				applet->kr_only = TRUE;
+				retval = grab_credentials (applet);
+				applet->kr_only = FALSE;
+			}
+
 			goto out;
+		}
 
 		give_up = canceled && (creds_expiry == canceled_creds_expiry);
 		if (!give_up) {
@@ -599,6 +631,10 @@
 #endif
 				/* Invalid password/pin, try again. */
 				invalid_auth = TRUE;
+
+				/* get rid of old passwords, they may be bad */
+				ka_keyring_delete_passwords (applet);
+
 				goto out;
 			default:
 				KA_DEBUG("Auth failed with %d: %s", retval,
@@ -616,6 +652,8 @@
 		goto out;
 
 out:
+	ka_keyring_free_items (applet);
+
 	if (opt)
 		krb5_get_init_creds_opt_free(kcontext, opt);
 	krb5_free_cred_contents (kcontext, &my_creds);
Index: src/krb5-auth-dialog.schemas.in
===================================================================
--- src/krb5-auth-dialog.schemas.in	(revision 124)
+++ src/krb5-auth-dialog.schemas.in	(working copy)
@@ -51,5 +51,18 @@
         <long>Start prompting/displaying notifications that many minutes before expiry</long>
       </locale>
     </schema>
+
+    <schema>
+      <key>/schemas/apps/krb5-auth-dialog/use_keyring</key>
+      <applyto>/apps/krb5-auth-dialog/use_keyring</applyto>
+      <owner>krb5-auth-dialog</owner>
+      <type>bool</type>
+      <default>0</default>
+
+      <locale name="C">
+        <short>Use keyring</short>
+        <long>Use keyring to store Kerberos passwords</long>
+      </locale>
+    </schema>
   </schemalist>
 </gconfschemafile>
Index: src/krb5-auth-keyring.c
===================================================================
--- src/krb5-auth-keyring.c	(revision 0)
+++ src/krb5-auth-keyring.c	(revision 0)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2009 Bojan Smojver, Rexursive
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "krb5-auth-keyring.h"
+
+/* keyring schema */
+static const GnomeKeyringPasswordSchema krb5_schema = {
+	GNOME_KEYRING_ITEM_GENERIC_SECRET,
+	{ 
+		{ "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
+		{ "prompt", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
+		{ NULL, 0 }
+	}
+};
+
+/* allocate keyring items */
+void ka_keyring_alloc_items (Krb5AuthApplet* applet, int num_prompts)
+{
+        /* never use keyring if using pkinit */
+	if (applet->use_keyring && !(applet->pk_userid && *applet->pk_userid)) {
+		applet->kr.num = (size_t) num_prompts;
+		applet->kr.prompt = g_malloc0 (num_prompts *
+		                               sizeof(*applet->kr.prompt));
+		applet->kr.passwd = g_malloc0 (num_prompts *
+		                               sizeof(*applet->kr.passwd));
+	}
+}
+
+/* free keyring items */
+void ka_keyring_free_items (Krb5AuthApplet* applet)
+{
+	/* free this even if keyring use was turned off */
+	if (applet->kr.prompt) {
+		size_t i;
+
+		for (i = 0; i < applet->kr.num; i++) {
+			if (applet->kr.passwd[i])
+				gnome_keyring_free_password (
+					applet->kr.passwd[i]);
+			if (applet->kr.prompt[i])
+				g_free (applet->kr.prompt[i]);
+		}
+		g_free (applet->kr.passwd);
+		g_free (applet->kr.prompt);
+
+		applet->kr.prompt = applet->kr.passwd = NULL;
+		applet->kr.num = 0;
+	}
+}
+
+/* find keyring password */
+GnomeKeyringResult
+ka_keyring_find_password (Krb5AuthApplet* applet, krb5_prompt prompts[], int i)
+{
+	/* if keyring use was turned on after allocation, don't crash */
+	if (applet->use_keyring && applet->kr.prompt) {
+		GnomeKeyringResult rc;
+
+		applet->kr.prompt[i] = g_strdup (prompts[i].prompt);
+
+		rc = gnome_keyring_find_password_sync(&krb5_schema,
+		                                      &applet->kr.passwd[i],
+		                                      "application",
+		                                      "krb5-auth-dialog",
+		                                      "prompt",
+		                                      prompts[i].prompt,
+		                                      NULL);
+
+		return rc;
+	}
+	else {
+		return GNOME_KEYRING_RESULT_NO_MATCH;
+	}
+}
+
+/* store keyring password */
+void
+ka_keyring_store_password (Krb5AuthApplet* applet,
+                           const char *prompt, const gchar *password)
+{
+	if (applet->use_keyring && applet->kr.prompt) {
+		gnome_keyring_store_password_sync(&krb5_schema,
+		                                  GNOME_KEYRING_DEFAULT,
+		                                  prompt, password,
+		                                  "application",
+		                                  "krb5-auth-dialog",
+		                                  "prompt", prompt,
+		                                  NULL);
+	}
+}
+
+/* delete keyring passwords */
+void ka_keyring_delete_passwords (Krb5AuthApplet* applet)
+{
+	if (applet->kr.prompt) {
+		size_t i;
+
+		/* delete bad passwords, even if keyring use was turned off */
+		for (i = 0; i < applet->kr.num; i++)
+			gnome_keyring_delete_password_sync(&krb5_schema,
+			                                   "application",
+			                                   "krb5-auth-dialog",
+			                                   "prompt",
+			                                   applet->kr.prompt[i],
+			                                   NULL);
+	}
+}
Index: src/krb5-auth-keyring.h
===================================================================
--- src/krb5-auth-keyring.h	(revision 0)
+++ src/krb5-auth-keyring.h	(revision 0)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2009 Bojan Smojver, Rexursive
+ *
+ * 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_KEYRING
+#define KRB5_AUTH_KEYRING
+
+#include <gnome-keyring.h>
+
+#include "krb5-auth-applet.h"
+
+void ka_keyring_alloc_items (Krb5AuthApplet* applet, int num_prompts);
+void ka_keyring_free_items (Krb5AuthApplet* applet);
+GnomeKeyringResult ka_keyring_find_password (Krb5AuthApplet* applet,
+                                             krb5_prompt prompts[], int i);
+void ka_keyring_store_password (Krb5AuthApplet* applet,
+                                const char *prompt, const gchar *password);
+void ka_keyring_delete_passwords (Krb5AuthApplet* applet);
+
+#endif
+
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 124)
+++ src/Makefile.am	(working copy)
@@ -28,6 +28,8 @@
 	krb5-auth-notify.h	\
 	krb5-auth-dbus.c	\
 	krb5-auth-dbus.h	\
+	krb5-auth-keyring.c	\
+	krb5-auth-keyring.h	\
 	dummy-strings.c
 
 krb5_auth_dialog_LDADD = \
@@ -38,6 +40,7 @@
 			@LIBNOTIFY_LIBS@ \
 			@DBUS_LIBS@ \
 			@GCONF_LIBS@ \
+			@GNOME_KEYRING_LIBS@ \
 			@GLADE_LIBS@ \
 			@GTK_LIBS@
 
Index: src/krb5-auth-applet.h
===================================================================
--- src/krb5-auth-applet.h	(revision 124)
+++ src/krb5-auth-applet.h	(working copy)
@@ -51,6 +51,15 @@
 	char* principal;		/* the principal to request */
 	gboolean renewable;		/* credentials renewable? */
 	char* pk_userid;		/* "userid" for pkint */
+
+	/* Optional gnome keyring */
+	gboolean use_keyring;		/* use_keyring */
+	gboolean kr_only;		/* use gnome keyring only */
+	struct kr_items {		/* keyring items */
+		size_t num;
+		gchar **prompt;
+		gchar **passwd;
+	} kr;
 } Krb5AuthApplet;
 
 Krb5AuthApplet* ka_create_applet();
Index: src/krb5-auth-gconf.c
===================================================================
--- src/krb5-auth-gconf.c	(revision 124)
+++ src/krb5-auth-gconf.c	(working copy)
@@ -29,6 +29,7 @@
 #define KA_GCONF_KEY_PK_USERID		KA_GCONF_PATH "/pk_userid"
 #define KA_GCONF_KEY_PROMPT_MINS	KA_GCONF_PATH "/prompt_minutes"
 #define KA_GCONF_KEY_SHOW_TRAYICON	KA_GCONF_PATH "/show_trayicon"
+#define KA_GCONF_KEY_USE_KEYRING	KA_GCONF_PATH "/use_keyring"
 
 static gboolean
 ka_gconf_get_string (GConfClient* client,
@@ -161,6 +162,17 @@
 }
 
 
+static gboolean
+ka_gconf_set_use_keyring (GConfClient* client, Krb5AuthApplet* applet)
+{
+	if(!ka_gconf_get_bool(client, KA_GCONF_KEY_USE_KEYRING, &applet->use_keyring)) {
+		applet->use_keyring = FALSE;
+	}
+	KA_DEBUG("Use keyring: %s", (applet->use_keyring ? "yes" : "no" ));
+	return TRUE;
+}
+
+
 static void
 ka_gconf_key_changed_callback (GConfClient* client,
                                guint cnxn_id,
@@ -183,6 +195,8 @@
 		ka_gconf_set_show_trayicon (client, applet);
 	} else if (g_strcmp0 (key, KA_GCONF_KEY_PK_USERID) == 0) {
 		ka_gconf_set_pk_userid (client, applet);
+	} else if (g_strcmp0 (key, KA_GCONF_KEY_USE_KEYRING) == 0) {
+		ka_gconf_set_use_keyring (client, applet);
 	} else
 		g_warning("Received notification for unknown gconf key %s", key);
 	return;
@@ -211,6 +225,7 @@
 	ka_gconf_set_prompt_mins (client, applet);
 	ka_gconf_set_show_trayicon (client, applet);
 	ka_gconf_set_pk_userid(client, applet);
+	ka_gconf_set_use_keyring (client, applet);
 
 	success = TRUE;
 out:
Index: configure.ac
===================================================================
--- configure.ac	(revision 124)
+++ configure.ac	(working copy)
@@ -26,11 +26,13 @@
 DBUS_REQUIRED="0.60"
 GCONF_REQUIRED="2.8"
 LIBNOTIFY_REQUIRED="0.4"
+GNOME_KEYRING_REQUIRED="2.22.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(GNOME_KEYRING, gnome-keyring-1 >= $GNOME_KEYRING_REQUIRED)
 
 dnl --enable-debug=(yes|no)
 AC_ARG_ENABLE(debug,
@@ -197,6 +199,7 @@
 	$GLADE_CFLAGS \
 	$DBUS_CFLAGS \
 	$GCONF_CFLAGS \
+	$GNOME_KEYRING_CFLAGS \
 	$KRB5_CFLAGS \
 	$NETWORK_MANAGER_CFLAGS \
 	$LIBNOTIFY_CFLAGS \
@@ -225,6 +228,7 @@
 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([    gnome-keyring: $GNOME_KEYRING_CFLAGS $GNOME_KEYRING_LIBS])
 if test "$with_libnotify" = "yes" ; then
 AC_MSG_NOTICE([        libnotify: $LIBNOTIFY_CFLAGS $LIBNOTIFY_LIBS])
 else
