Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/vino/ChangeLog,v
retrieving revision 1.153
diff -u -p -r1.153 ChangeLog
--- ChangeLog	16 Oct 2006 14:21:36 -0000	1.153
+++ ChangeLog	17 Oct 2006 09:14:23 -0000
@@ -0,0 +1,37 @@
+2006-10-17  Mark McLoughlin  <mark@skynet.ie>
+
+	Add a --enable-gnome-keyring option which causes Vino
+	to store its configured password in the user's keyring.
+	Disabled by default, because it's not really a good
+	idea. See comments in bug #344839
+
+	Based on a patch from Steven Zhang <steven.zhang@sun.com>
+
+	* configure.in: add --enable-gnome-keyring
+	
+	* server/vino-server.c:
+	(vino_server_get_password_from_keyring): helper to
+	read the password from the keyring.
+	(vino_server_auth_client): if keyring support is enabled,
+	authenticate against the password stored in the keyring.
+	If there's no password in the keyring, authenticate against
+	the password in GConf.
+	
+	* capplet/vino-preferences.c:
+	(vino_preferences_dialog_get_password_from_keyring): lookup
+	the password from the user's keyring.
+	(vino_preferences_dialog_set_password_in_keyring): store
+	the password in the user's keyring.
+	(vino_preferences_dialog_password_changed): store the new
+	password in the keyring, falling back to GConf if that
+	fails.
+	(vino_preferences_dialog_setup_password_entry): read the
+	password from the keyring, falling back to GConf. Only
+	watch for changes from GConf if we actually used the
+	one from GConf in the first place.
+	(vino_preferences_dialog_init): hack to allow variable
+	number of listeners.
+
+	* server/Makefile.am, capplet/Makefile.am: build against
+	gnome-keyring
+	
Index: configure.in
===================================================================
RCS file: /cvs/gnome/vino/configure.in,v
retrieving revision 1.113
diff -u -p -r1.113 configure.in
--- configure.in	10 Oct 2006 06:58:44 -0000	1.113
+++ configure.in	17 Oct 2006 09:14:23 -0000
@@ -47,6 +47,17 @@ PKG_CHECK_MODULES(VINO_SERVER, gtk+-x11-
 	
 PKG_CHECK_MODULES(VINO_CAPPLET, gtk+-2.0 gconf-2.0 libglade-2.0 libgnomeui-2.0 >= 2.5.2)
 
+dnl --enable-gnome-keyring=(yes|no)
+AC_ARG_ENABLE(gnome-keyring,
+              AC_HELP_STRING([--enable-gnome-keyring],
+                             [use gnome keyring for storing password [default=no]]),,
+              enable_gnome_keyring=no)
+if test "x$enable_gnome_keyring" = "xyes"; then
+    PKG_CHECK_MODULES(VINO_KEYRING,
+                      gnome-keyring-1,
+                      AC_DEFINE(VINO_ENABLE_KEYRING, [], [Set if we should use gnome-keyring]))
+fi
+
 dnl --enable-session-support=(yes|no)
 AC_ARG_ENABLE(session_support,
 	      [  --enable-session-support=[no/yes] build session management utility program [default=no]],,
Index: capplet/Makefile.am
===================================================================
RCS file: /cvs/gnome/vino/capplet/Makefile.am,v
retrieving revision 1.3
diff -u -p -r1.3 Makefile.am
--- capplet/Makefile.am	9 Nov 2004 16:58:45 -0000	1.3
+++ capplet/Makefile.am	17 Oct 2006 09:14:23 -0000
@@ -5,6 +5,7 @@ INCLUDES = \
 	-DVINO_GLADEDIR=\""$(datadir)/gnome/vino"\" \
 	-DVINO_ICONDIR=\""$(datadir)/pixmaps\"" \
 	$(VINO_CAPPLET_CFLAGS) \
+	$(VINO_KEYRING_CFLAGS) \
 	$(WARN_CFLAGS) \
 	$(NULL)
 
@@ -17,6 +18,7 @@ vino_preferences_SOURCES = \
 	$(NULL)
 vino_preferences_LDADD = \
 	$(VINO_CAPPLET_LIBS) \
+	$(VINO_KEYRING_LIBS) \
 	$(X_LIBS) \
 	$(NULL)
 
Index: capplet/vino-preferences.c
===================================================================
RCS file: /cvs/gnome/vino/capplet/vino-preferences.c,v
retrieving revision 1.5
diff -u -p -r1.5 vino-preferences.c
--- capplet/vino-preferences.c	16 May 2005 13:14:57 -0000	1.5
+++ capplet/vino-preferences.c	17 Oct 2006 09:14:24 -0000
@@ -33,6 +33,10 @@
 #include <libgnomeui/libgnomeui.h>
 #include "vino-url.h"
 
+#ifdef VINO_ENABLE_KEYRING
+#include <gnome-keyring.h>
+#endif
+
 #define VINO_PREFS_DIR                    "/desktop/gnome/remote_access"
 #define VINO_PREFS_ENABLED                VINO_PREFS_DIR "/enabled"
 #define VINO_PREFS_PROMPT_ENABLED         VINO_PREFS_DIR "/prompt_enabled"
@@ -63,6 +67,7 @@ typedef struct {
 
   guint        listeners [N_LISTENERS];
   int          n_listeners;
+  int          expected_listeners;
 
   guint        use_password : 1;
 } VinoPreferencesDialog;
@@ -237,6 +242,70 @@ vino_preferences_dialog_base64_unencode 
   return retval;
 }
 
+static char *
+vino_preferences_dialog_get_password_from_keyring (VinoPreferencesDialog *dialog)
+{
+#ifdef VINO_ENABLE_KEYRING
+  GnomeKeyringNetworkPasswordData *found_item;
+  GnomeKeyringResult               result;
+  GList                           *matches;
+  char                            *password;
+  
+  matches = NULL;
+
+  result = gnome_keyring_find_network_password_sync (
+                NULL,           /* user     */
+		NULL,           /* domain   */
+		"vino.local",   /* server   */
+		NULL,           /* object   */
+		"rfb",          /* protocol */
+		"vnc-password", /* authtype */
+		5900,           /* port     */
+		&matches);
+
+  if (result != GNOME_KEYRING_RESULT_OK)
+    return NULL;
+
+  g_assert (matches != NULL && matches->data != NULL);
+
+  found_item = (GnomeKeyringNetworkPasswordData *) matches->data;
+
+  password = g_strdup (found_item->password);
+
+  gnome_keyring_network_password_list_free (matches);
+
+  return password;
+#else
+  return NULL;
+#endif
+}
+
+static gboolean
+vino_preferences_dialog_set_password_in_keyring (VinoPreferencesDialog *dialog,
+                                                 const char            *password)
+{
+#ifdef VINO_ENABLE_KEYRING
+  GnomeKeyringResult result;
+  guint32            item_id;
+
+  result = gnome_keyring_set_network_password_sync (
+                NULL,           /* default keyring */
+                NULL,           /* user            */
+                NULL,           /* domain          */
+                "vino.local",   /* server          */
+                NULL,           /* object          */
+                "rfb",          /* protocol        */
+                "vnc-password", /* authtype        */
+                5900,           /* port            */
+                password,       /* password        */
+                &item_id);
+
+  return result == GNOME_KEYRING_RESULT_OK;
+#else
+  return FALSE;
+#endif
+}
+
 static void
 vino_preferences_dialog_update_for_allowed (VinoPreferencesDialog *dialog,
 					    gboolean               allowed)
@@ -580,6 +649,10 @@ vino_preferences_dialog_password_changed
   const char *password;
 
   password = gtk_entry_get_text (entry);
+
+  if (vino_preferences_dialog_set_password_in_keyring (dialog, password))
+    return;
+
   if (!password || !password [0])
     {
       gconf_client_unset (dialog->client, VINO_PREFS_VNC_PASSWORD, NULL);
@@ -599,8 +672,8 @@ vino_preferences_dialog_password_changed
 static void
 vino_preferences_dialog_setup_password_entry (VinoPreferencesDialog *dialog)
 {
-  char *password_b64;
-  char *password;
+  char     *password;
+  gboolean  password_in_keyring;
 
   dialog->password_entry = glade_xml_get_widget (dialog->xml, "password_entry");
   g_assert (dialog->password_entry != NULL);
@@ -608,15 +681,26 @@ vino_preferences_dialog_setup_password_e
   dialog->password_box = glade_xml_get_widget (dialog->xml, "password_box");
   g_assert (dialog->password_box != NULL);
 
-  password_b64 = gconf_client_get_string (dialog->client, VINO_PREFS_VNC_PASSWORD, NULL);
-  password = vino_preferences_dialog_base64_unencode (password_b64);
+  password_in_keyring = TRUE;
+
+  if (!(password = vino_preferences_dialog_get_password_from_keyring (dialog)))
+    {
+      char *password_b64;
+
+      password_b64 = gconf_client_get_string (dialog->client, VINO_PREFS_VNC_PASSWORD, NULL);
+
+      password = vino_preferences_dialog_base64_unencode (password_b64);
+
+      g_free (password_b64);
+
+      password_in_keyring = FALSE;
+    }
 
   if (password)
     {
       gtk_entry_set_text (GTK_ENTRY (dialog->password_entry), password);
     }
 
-  g_free (password_b64);
   g_free (password);
 
   g_signal_connect (dialog->password_entry, "changed",
@@ -624,18 +708,25 @@ vino_preferences_dialog_setup_password_e
 
   gtk_widget_set_sensitive (dialog->password_box, dialog->use_password);
 
-  if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_VNC_PASSWORD, NULL))
+  if (!password_in_keyring)
     {
-      gtk_widget_set_sensitive (dialog->password_box, FALSE);
-      gtk_widget_show (dialog->writability_warning);
+      if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_VNC_PASSWORD, NULL))
+        {
+          gtk_widget_set_sensitive (dialog->password_box, FALSE);
+          gtk_widget_show (dialog->writability_warning);
+        }
+
+      dialog->listeners [dialog->n_listeners] = 
+        gconf_client_notify_add (dialog->client,
+                                 VINO_PREFS_VNC_PASSWORD,
+                                 (GConfClientNotifyFunc) vino_preferences_vnc_password_notify,
+                                 dialog, NULL, NULL);
+      dialog->n_listeners++;
+    }
+  else
+    {
+      dialog->expected_listeners--;
     }
-
-  dialog->listeners [dialog->n_listeners] = 
-    gconf_client_notify_add (dialog->client,
-			     VINO_PREFS_VNC_PASSWORD,
-			     (GConfClientNotifyFunc) vino_preferences_vnc_password_notify,
-			     dialog, NULL, NULL);
-  dialog->n_listeners++;
 }
 
 static void
@@ -870,6 +961,8 @@ vino_preferences_dialog_init (VinoPrefer
   const char *glade_file;
   gboolean    allowed;
 
+  dialog->expected_listeners = N_LISTENERS;
+
   if (g_file_test (VINO_GLADE_FILE, G_FILE_TEST_EXISTS))
     glade_file = VINO_GLADE_FILE;
   else
@@ -909,7 +1002,7 @@ vino_preferences_dialog_init (VinoPrefer
   vino_preferences_dialog_setup_password_toggle       (dialog);
   vino_preferences_dialog_setup_password_entry        (dialog);
 
-  g_assert (dialog->n_listeners == N_LISTENERS);
+  g_assert (dialog->n_listeners == dialog->expected_listeners);
 
   vino_preferences_dialog_update_for_allowed (dialog, allowed);
 
Index: server/Makefile.am
===================================================================
RCS file: /cvs/gnome/vino/server/Makefile.am,v
retrieving revision 1.6
diff -u -p -r1.6 Makefile.am
--- server/Makefile.am	13 Jan 2006 12:12:54 -0000	1.6
+++ server/Makefile.am	17 Oct 2006 09:14:24 -0000
@@ -6,6 +6,7 @@ INCLUDES = \
 	-I$(top_srcdir)/server/libvncserver \
 	$(VINO_SERVER_CFLAGS) \
 	$(VINO_DEBUG_CFLAGS) \
+	$(VINO_KEYRING_CFLAGS) \
 	$(VINO_HTTP_CFLAGS) \
 	$(AVAHI_CFLAGS) \
 	$(LIBGNUTLS_CFLAGS) \
@@ -21,6 +22,7 @@ libexec_PROGRAMS = vino-server
 
 vino_server_LDADD = \
 	$(VINO_SERVER_LIBS) \
+	$(VINO_KEYRING_LIBS) \
 	$(AVAHI_LIBS) \
 	$(LIBGNUTLS_LIBS) \
 	$(LIBGCRYPT_LIBS) \
Index: server/vino-server.c
===================================================================
RCS file: /cvs/gnome/vino/server/vino-server.c,v
retrieving revision 1.16
diff -u -p -r1.16 vino-server.c
--- server/vino-server.c	13 Oct 2006 08:48:29 -0000	1.16
+++ server/vino-server.c	17 Oct 2006 09:14:24 -0000
@@ -37,6 +37,10 @@
 #include "vino-enums.h"
 #include <sys/poll.h>
 
+#ifdef VINO_ENABLE_KEYRING
+#include <gnome-keyring.h>
+#endif
+
 /* If an authentication attempt failes, delay the next
  * authentication attempt for 5 seconds.
  */
@@ -447,6 +451,44 @@ vino_server_defer_client_auth (VinoServe
 					client);
 }
 
+static char *
+vino_server_get_password_from_keyring (VinoServer *server)
+{
+#ifdef VINO_ENABLE_KEYRING
+  GnomeKeyringNetworkPasswordData *found_item;
+  GnomeKeyringResult               result;
+  GList                           *matches;
+  char                            *password;
+  
+  matches = NULL;
+
+  result = gnome_keyring_find_network_password_sync (
+                NULL,           /* user     */
+		NULL,           /* domain   */
+		"vino.local",   /* server   */
+		NULL,           /* object   */
+		"rfb",          /* protocol */
+		"vnc-password", /* authtype */
+		5900,           /* port     */
+		&matches);
+
+  if (result != GNOME_KEYRING_RESULT_OK)
+    return NULL;
+
+  g_assert (matches != NULL && matches->data != NULL);
+
+  found_item = (GnomeKeyringNetworkPasswordData *) matches->data;
+
+  password = g_strdup (found_item->password);
+
+  gnome_keyring_network_password_list_free (matches);
+
+  return password;
+#else
+  return NULL;
+#endif
+}
+
 static enum rfbNewClientAction
 vino_server_auth_client (VinoServer           *server,
 			 VinoServerClientInfo *client,
@@ -459,13 +501,16 @@ vino_server_auth_client (VinoServer     
   if (!(server->priv->auth_methods & VINO_AUTH_VNC))
     goto auth_failed;
 
-  if (!server->priv->vnc_password)
-    goto auth_failed;
-
-  if (!(password = vino_base64_unencode (server->priv->vnc_password)))
+  if (!(password = vino_server_get_password_from_keyring (server)))
     {
-      g_warning ("Failed to base64 unencode VNC password\n");
-      goto auth_failed;
+      if (!server->priv->vnc_password)
+        goto auth_failed;
+
+      if (!(password = vino_base64_unencode (server->priv->vnc_password)))
+        {
+          g_warning ("Failed to base64 unencode VNC password\n");
+          goto auth_failed;
+        }
     }
 
   rfb_client = client->rfb_client;
