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 + + 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 + + * 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 #include "vino-url.h" +#ifdef VINO_ENABLE_KEYRING +#include +#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 +#ifdef VINO_ENABLE_KEYRING +#include +#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;