Index: gksu/gksu.c =================================================================== --- gksu/gksu.c (revision 172) +++ gksu/gksu.c (working copy) @@ -17,6 +17,10 @@ #include #include +#ifdef ENABLE_GNOME_KEYRING + #include +#endif + #include "defines.h" #include "../config.h" @@ -30,6 +34,9 @@ gboolean message_changed = FALSE; gboolean prompt = FALSE; +/* FIXME: bad code... */ +static GMainLoop *keyring_loop = NULL; + struct option long_opts[] = { /* * { name has_arg *flag val } @@ -650,7 +657,17 @@ } g_io_channel_shutdown (channel, TRUE, NULL); } - + +#ifdef ENABLE_GNOME_KEYRING +static void +keyring_create_item_cb (GnomeKeyringResult result, + guint32 id, + gpointer data) +{ + g_main_loop_quit (keyring_loop); +} +#endif + int main (int argc, char **argv) { @@ -986,28 +1003,91 @@ g_free (msg); } - int lock = 0; - if (grab) - lock = grab_keyboard_and_mouse (dialog); - retvalue = gtk_dialog_run (GTK_DIALOG(dialog)); - gtk_widget_hide (dialog); - if (grab) - ungrab_keyboard_and_mouse (lock); +#ifdef ENABLE_GNOME_KEYRING + /* get password from keyring */ + GnomeKeyringAttributeList *attributes; + GnomeKeyringAttribute attribute; + GnomeKeyringResult result; + GList *list; + gboolean keyring_has_password; + gchar *keyring_password; + gchar *keyring_command; - while (gtk_events_pending ()) - gtk_main_iteration (); + attributes = gnome_keyring_attribute_list_new (); - if (retvalue != GTK_RESPONSE_OK) - return 2; + attribute.name = g_strdup ("user"); + attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING; + attribute.value.string = g_strdup (gksu_context_get_user (context)); + g_array_append_val (attributes, attribute); + attribute.name = g_strdup ("type"); + attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING; + attribute.value.string = g_strdup ("local"); + g_array_append_val (attributes, attribute); + + attribute.name = g_strdup ("creator"); + attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING; + attribute.value.string = g_strdup ("gksu"); + g_array_append_val (attributes, attribute); + + list = g_list_alloc(); + keyring_has_password = FALSE; + + result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET, /* type */ + attributes, /* attribute list */ + &list); + gnome_keyring_attribute_list_free (attributes); + if ( + (result == GNOME_KEYRING_RESULT_OK) && + (g_list_length(list) == 1) + ) { - gchar *tmp; - tmp = gksuui_dialog_get_password (GKSUUI_DIALOG(dialog)); - password = g_locale_from_utf8 (tmp, strlen (tmp), NULL, NULL, NULL); - g_free (tmp); + GnomeKeyringFound *found = list->data; + keyring_password = g_strdup(found->secret); + /* check the password */ + + keyring_command = g_strdup (gksu_context_get_command (context)); + gksu_context_set_command (context, "/bin/echo test > /dev/null"); + gksu_context_set_password (context, keyring_password); + gksu_context_run (context, &error); + + if (!error) + keyring_has_password = TRUE; + gksu_context_set_command (context, keyring_command); } + + if (keyring_has_password) + { + password = g_locale_from_utf8 (keyring_password, strlen (keyring_password), NULL, NULL, NULL); + } + else +#endif + { + int lock = 0; + if (grab) + lock = grab_keyboard_and_mouse (dialog); + retvalue = gtk_dialog_run (GTK_DIALOG(dialog)); + gtk_widget_hide (dialog); + if (grab) + ungrab_keyboard_and_mouse (lock); + while (gtk_events_pending ()) + gtk_main_iteration (); + + if (retvalue != GTK_RESPONSE_OK) + return 2; + + { + gchar *tmp; + tmp = gksuui_dialog_get_password (GKSUUI_DIALOG(dialog)); + password = g_locale_from_utf8 (tmp, strlen (tmp), NULL, NULL, NULL); + g_free (tmp); + } + } + gksu_context_set_password (context, password); + + error = 0; gksu_context_run (context, &error); if (error) { @@ -1018,6 +1098,45 @@ error->message); return 3; } +#ifdef ENABLE_GNOME_KEYRING + { + /* save the password for the default keyring */ + /* FIXME: keyring should be specified in the config file */ + + gchar *key_name; + + attributes = gnome_keyring_attribute_list_new (); + + attribute.name = g_strdup ("user"); + attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING; + attribute.value.string = g_strdup (gksu_context_get_user (context)); + g_array_append_val (attributes, attribute); + + attribute.name = g_strdup ("type"); + attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING; + attribute.value.string = g_strdup ("local"); + g_array_append_val (attributes, attribute); + + attribute.name = g_strdup ("creator"); + attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING; + attribute.value.string = g_strdup ("gksu"); + g_array_append_val (attributes, attribute); + + key_name = g_strdup_printf ("Local password for user %s", gksu_context_get_user (context)); + + keyring_loop = g_main_loop_new (NULL, FALSE); + + gnome_keyring_item_create (NULL, /* Use default keyring */ + GNOME_KEYRING_ITEM_GENERIC_SECRET, /* type */ + key_name, /* name */ + attributes, /* attribute list */ + password, /* password */ + TRUE, /* Update if already exists */ + keyring_create_item_cb, NULL, NULL); + gnome_keyring_attribute_list_free (attributes); + g_main_loop_run (keyring_loop); + } +#endif } return 0; Index: configure.ac =================================================================== --- configure.ac (revision 172) +++ configure.ac (working copy) @@ -58,7 +58,29 @@ AM_CONDITIONAL(GTK_DOC_USE_LIBTOOL, test x$use_libtool = xyes) # end of gtk-doc check +dnl gnome-keyring support +gnome_keyring_defs= +AC_ARG_ENABLE(gnome-keyring, [ --enable-gnome-keyring Use gnome-keyring to remember passwords [default=no]], enable_gnome_keyring="$enableval", enable_gnome_keyring=no) +AM_CONDITIONAL(ENABLE_GNOME_KEYRING, test x$enable_gnome_keyring = xyes) +if test x$enable_gnome_keyring != xyes ; then + PDEPS="gtk+-2.0 libgksu1.2 libgksuui1.0" +else + AC_MSG_CHECKING([gnome-keyring]) + keyring_libs=`pkg-config --libs gnome-keyring-1` + if test "x$keyring_libs" != x ; then + AC_MSG_RESULT(yes) + gnome_keyring_defs=-DENABLE_GNOME_KEYRING + PDEPS="gtk+-2.0 libgksu1.2 libgksuui1.0 gnome-keyring-1" + else + AC_MSG_RESULT(no) + exit + fi +fi +AC_SUBST(PDEPS) +AC_SUBST(gnome_keyring_defs) +#end of gnome-keyring support + AC_CONFIG_FILES([ Makefile m4/Makefile Index: gksu/Makefile.am =================================================================== --- gksu/Makefile.am (revision 172) +++ gksu/Makefile.am (working copy) @@ -1,15 +1,15 @@ AM_CFLAGS = -g -O2 -Wall -INCLUDES = `pkg-config --cflags gtk+-2.0 libgksu1.2 libgksuui1.0` -AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\" -DDATA_DIR=\"$(datadir)\" -DPREFIX=\"$(prefix)\" +INCLUDES = `pkg-config --cflags $(PDEPS)` +AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\" -DDATA_DIR=\"$(datadir)\" -DPREFIX=\"$(prefix)\" $(gnome_keyring_defs) bin_PROGRAMS = gksu gksuexec noinst_HEADERS = defines.h util.h -gksu_LDFLAGS = `pkg-config --libs gtk+-2.0 libgksu1.2 libgksuui1.0` -lutil +gksu_LDFLAGS = `pkg-config --libs $(PDEPS)` -lutil gksu_SOURCES = gksu.c util.c -gksuexec_LDFLAGS = `pkg-config --libs gtk+-2.0 libgksu1.2 libgksuui1.0` +gksuexec_LDFLAGS = `pkg-config --libs $(PDEPS)` gksuexec_SOURCES = gksuexec.c util.c configdir = /etc