policykit-gnome r94 - trunk/src



Author: davidz
Date: Sat Jan 31 01:45:48 2009
New Revision: 94
URL: http://svn.gnome.org/viewvc/policykit-gnome?rev=94&view=rev

Log:
port to new polkitagent API and clean up major portions of the code



Added:
   trunk/src/polkitgnomeauthenticationdialog.c   (contents, props changed)
      - copied, changed from r91, /trunk/src/polkit-gnome-auth-dialog.c
   trunk/src/polkitgnomeauthenticationdialog.h   (contents, props changed)
      - copied, changed from r91, /trunk/src/polkit-gnome-auth-dialog.h
   trunk/src/polkitgnomeauthenticator.c
   trunk/src/polkitgnomeauthenticator.h
   trunk/src/polkitgnomelistener.c
   trunk/src/polkitgnomelistener.h
Removed:
   trunk/src/polkit-gnome-auth-dialog.c
   trunk/src/polkit-gnome-auth-dialog.h
Modified:
   trunk/src/Makefile.am
   trunk/src/main.c

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Sat Jan 31 01:45:48 2009
@@ -9,15 +9,17 @@
 
 libexec_PROGRAMS = polkit-gnome-authentication-agent-1
 
-polkit_gnome_authentication_agent_1_SOURCES = 				\
-	polkit-gnome-auth-dialog.h	polkit-gnome-auth-dialog.c	\
-	sexy-url-label.h 		sexy-url-label.c		\
-	main.c								\
+polkit_gnome_authentication_agent_1_SOURCES = 						\
+	polkitgnomelistener.h			polkitgnomelistener.c			\
+	polkitgnomeauthenticator.h		polkitgnomeauthenticator.c		\
+	polkitgnomeauthenticationdialog.h	polkitgnomeauthenticationdialog.c	\
+	sexy-url-label.h 			sexy-url-label.c			\
+	main.c										\
 	$(BUILT_SOURCES)
 
 polkit_gnome_authentication_agent_1_CPPFLAGS = 		\
 	-I$(top_srcdir)					\
-	-DG_LOG_DOMAIN=\"PolicyKitGnome\"		\
+	-DG_LOG_DOMAIN=\"polkit-gnome-1\"		\
 	-DDATADIR=\""$(pkgdatadir)"\"			\
 	-DGNOMELOCALEDIR=\""$(datadir)/locale"\"	\
 	$(DISABLE_DEPRECATED)				\

Modified: trunk/src/main.c
==============================================================================
--- trunk/src/main.c	(original)
+++ trunk/src/main.c	Sat Jan 31 01:45:48 2009
@@ -1,460 +1,41 @@
 /*
- * Copyright (C) 2007 David Zeuthen <david fubar dk>
+ * Copyright (C) 2009 Red Hat, Inc.
  *
- * 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 library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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,
+ * This library 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser 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.
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
  *
+ * Author: David Zeuthen <davidz redhat com>
  */
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <glib-object.h>
-
-#include <gdk/gdkx.h>
 #include <gtk/gtk.h>
-
+#include <glib/gi18n.h>
 #include <polkitagent/polkitagent.h>
 
-#include "polkit-gnome-auth-dialog.h"
-
-static PolkitAuthority *authority;
-
-typedef struct
-{
-  gchar *action_id;
-  PolkitActionDescription *action_desc;
-  gchar *cookie;
-  GList *identities;
-  gpointer pending_call;
-
-  gboolean gained_authorization;
-  gboolean was_cancelled;
-  gboolean invalid_data;
-
-  GMainLoop *loop;
-  PolkitAgentAuthenticationSession *session;
-  GtkWidget *dialog;
-
-} AuthData;
-
-static AuthData *
-auth_data_new (const gchar *action_id,
-               const gchar *cookie,
-               GList *identities,
-               gpointer pending_call)
-{
-  AuthData *data;
-
-  data = g_new0 (AuthData, 1);
-  data->action_id = g_strdup (action_id);
-  data->cookie = g_strdup (cookie);
-
-  data->identities = g_list_copy (identities);
-  g_list_foreach (data->identities, (GFunc) g_object_ref, NULL);
-
-  data->pending_call = pending_call;
-
-  return data;
-}
-
-static void
-auth_data_free (AuthData *data)
-{
-  g_free (data->action_id);
-
-  if (data->action_desc != NULL)
-    g_object_unref (data->action_desc);
-
-  g_free (data->cookie);
-  g_list_foreach (data->identities, (GFunc) g_object_unref, NULL);
-  g_list_free (data->identities);
-
-  if (data->session != NULL)
-    g_object_unref (data->session);
-
-  g_main_loop_unref (data->loop);
-
-  gtk_widget_destroy (data->dialog);
-
-  g_free (data);
-}
-
-static AuthData *auth_data = NULL;
-static PolkitAgentAuthenticationAgent *agent;
-
-static void
-do_show_dialog (void)
-{
-  guint32 server_time;
-
-  gtk_widget_realize (auth_data->dialog);
-  server_time = gdk_x11_get_server_time (auth_data->dialog->window);
-  gtk_window_present_with_time (GTK_WINDOW (auth_data->dialog), server_time);
-  gtk_widget_show_all (auth_data->dialog);
-}
-
-static void
-do_cancel_auth (void)
-{
-  auth_data->was_cancelled = TRUE;
-  polkit_agent_authentication_session_cancel (auth_data->session);
-}
-
-static char *
-conversation_pam_prompt (PolkitAgentAuthenticationSession *session,
-                         const char *request,
-                         gboolean echo_on,
-                         gpointer user_data)
-{
-  gchar *password;
-  int response;
-
-  password = NULL;
-
-  g_debug ("in conversation_pam_prompt, request='%s', echo_on=%d", request, echo_on);
-
-#if 0
-  /* Fix up, and localize, password prompt if it's password auth */
-  printf ("request: '%s'\n", request);
-  if (g_ascii_strncasecmp (request, "password:", 9) == 0)
-    {
-      if (auth_data->requires_admin)
-        {
-          if (auth_data->admin_user_selected != NULL)
-            {
-              request2 = g_strdup_printf (_("_Password for %s:"), auth_data->admin_user_selected);
-            }
-          else
-            {
-              request2 = g_strdup (_("_Password for root:"));
-            }
-        }
-      else
-        {
-          request2 = g_strdup (_("_Password:"));
-        }
-    }
-  else if (g_ascii_strncasecmp (request, "password or swipe finger:", 25) == 0)
-    {
-      if (auth_data->requires_admin)
-        {
-          if (auth_data->admin_user_selected != NULL)
-            {
-              request2 = g_strdup_printf (_("_Password or swipe finger for %s:"),
-                                          auth_data->admin_user_selected);
-            }
-          else
-            {
-              request2 = g_strdup (_("_Password or swipe finger for root:"));
-            }
-        }
-      else
-        {
-          request2 = g_strdup (_("_Password or swipe finger:"));
-        }
-    }
-  else
-    {
-      request2 = g_strdup (request);
-    }
-#endif
-
-  polkit_gnome_auth_dialog_set_prompt (POLKIT_GNOME_AUTH_DIALOG (auth_data->dialog), request, echo_on);
-
-  do_show_dialog ();
-
-  response = gtk_dialog_run (GTK_DIALOG (auth_data->dialog));
-
-  /* cancel auth unless user clicked "Authenticate" */
-  if (response != GTK_RESPONSE_OK)
-    {
-      do_cancel_auth ();
-      goto out;
-    }
-
-  password = g_strdup (polkit_gnome_auth_dialog_get_password (POLKIT_GNOME_AUTH_DIALOG (auth_data->dialog)));
-
-out:
-  return password;
-}
-
-static char *
-conversation_pam_prompt_echo_off (PolkitAgentAuthenticationSession *session,
-                                  const char *request,
-                                  gpointer user_data)
-{
-  return conversation_pam_prompt (session, request, FALSE, user_data);
-}
-
-static char *
-conversation_pam_prompt_echo_on (PolkitAgentAuthenticationSession *session,
-                                 const char *request,
-                                 gpointer user_data)
-{
-  return conversation_pam_prompt (session, request, TRUE, FALSE);
-}
-
-static void
-conversation_pam_error_msg (PolkitAgentAuthenticationSession *session,
-                            const char *msg,
-                            gpointer user_data)
-{
-  g_debug ("error_msg='%s'", msg);
-}
-
-static void
-conversation_pam_text_info (PolkitAgentAuthenticationSession *session,
-                            const char *msg,
-                            gpointer user_data)
-{
-  g_debug ("text_info='%s'", msg);
-}
-
-
-static void
-conversation_done (PolkitAgentAuthenticationSession *session,
-                   gboolean                          gained_authorization,
-                   gboolean                          invalid_data,
-                   gpointer                          user_data)
-{
-  auth_data->gained_authorization = gained_authorization;
-  auth_data->invalid_data = invalid_data;;
-
-  g_debug ("in conversation_done gained=%d, invalid=%d", gained_authorization, invalid_data);
-
-  if ((auth_data->invalid_data || auth_data->was_cancelled) && auth_data->dialog != NULL)
-    {
-      gtk_widget_destroy (auth_data->dialog);
-      auth_data->dialog = NULL;
-    }
-
-  g_main_loop_quit (auth_data->loop);
-}
-
-static PolkitActionDescription *
-get_desc_for_action (const gchar *action_id)
-{
-  GList *action_descs;
-  GList *l;
-  PolkitActionDescription *result;
-
-  result = NULL;
-
-  action_descs = polkit_authority_enumerate_actions_sync (authority,
-                                                          NULL,
-                                                          NULL,
-                                                          NULL);
-  for (l = action_descs; l != NULL; l = l->next)
-    {
-      PolkitActionDescription *action_desc = POLKIT_ACTION_DESCRIPTION (l->data);
-
-      if (strcmp (polkit_action_description_get_action_id (action_desc), action_id) == 0)
-        {
-          result = g_object_ref (action_desc);
-          goto out;
-        }
-    }
-
- out:
-
-  g_list_foreach (action_descs, (GFunc) g_object_unref, NULL);
-  g_list_free (action_descs);
-
-  return result;
-}
-
-static gboolean
-do_authentication (gpointer user_data)
-{
-  gint num_tries;
-  PolkitIdentity *identity;
-  GIcon *icon;
-  gchar *icon_name;
-
-  auth_data->action_desc = get_desc_for_action (auth_data->action_id);
-
-  icon_name = NULL;
-
-  icon = polkit_action_description_get_icon (auth_data->action_desc);
-  if (icon != NULL)
-    icon_name = g_icon_to_string (icon);
-
-  auth_data->dialog = polkit_gnome_auth_dialog_new ("", /* TODO: path to exe file */
-                                                    auth_data->action_id,
-                                                    polkit_action_description_get_vendor_name (auth_data->action_desc),
-                                                    polkit_action_description_get_vendor_url (auth_data->action_desc),
-                                                    icon_name,
-                                                    polkit_action_description_get_message (auth_data->action_desc));
-
-  polkit_gnome_auth_dialog_set_options (POLKIT_GNOME_AUTH_DIALOG (auth_data->dialog),
-                                        FALSE,
-                                        FALSE,
-                                        FALSE,
-                                        NULL);
-
-  auth_data->loop = g_main_loop_new (NULL, TRUE);
-
-  num_tries = 0;
-
-  identity = POLKIT_IDENTITY (auth_data->identities->data);
-
- try_again:
-
-  /* TODO: make this work with multiple users */
-  auth_data->session = polkit_agent_authentication_session_new (identity,
-                                                                auth_data->cookie);
-
-  polkit_agent_authentication_session_set_functions (auth_data->session,
-                                                     conversation_pam_prompt_echo_off,
-                                                     conversation_pam_prompt_echo_on,
-                                                     conversation_pam_error_msg,
-                                                     conversation_pam_text_info,
-                                                     conversation_done,
-                                                     NULL);
-
-
-  if (!polkit_agent_authentication_session_initiate_auth (auth_data->session))
-    {
-      g_warning ("Failed to initiate authentication session");
-      goto done;
-    }
-  g_main_loop_run (auth_data->loop);
-
-  num_tries++;
-
-  g_debug ("gained_authorization=%d was_cancelled=%d invalid_data=%d.",
-           auth_data->gained_authorization,
-           auth_data->was_cancelled,
-           auth_data->invalid_data);
-
-  if (!auth_data->gained_authorization && !auth_data->was_cancelled && !auth_data->invalid_data)
-    {
-      if (auth_data->dialog != NULL)
-        {
-          /* shake the dialog to indicate error */
-          polkit_gnome_auth_dialog_indicate_auth_error (POLKIT_GNOME_AUTH_DIALOG (auth_data->dialog));
-
-          if (num_tries < 3)
-            {
-              g_object_unref (auth_data->session);
-              auth_data->session = NULL;
-              goto try_again;
-            }
-        }
-    }
-
- done:
-
-  polkit_agent_authentication_agent_finish (agent,
-                                            auth_data->pending_call,
-                                            NULL);
-
-  auth_data_free (auth_data);
-  auth_data = NULL;
-
-  g_free (icon_name);
-
-  return FALSE;
-}
-
-
-static void
-begin_authentication_func (PolkitAgentAuthenticationAgent *agent,
-                           const gchar                    *action_id,
-                           const gchar                    *cookie,
-                           GList                          *identities,
-                           gpointer                        pending_call)
-{
-  GList *l;
-
-  g_debug ("Begin authentication func action_id=%s cookie=%s num_identities=%d",
-           action_id,
-           cookie,
-           g_list_length (identities));
-
-  for (l = identities; l != NULL; l = l->next)
-    {
-      PolkitIdentity *identity = POLKIT_IDENTITY (l->data);
-      gchar *identity_str;
-
-      identity_str = polkit_identity_to_string (identity);
-      g_debug ("  identity %s", identity_str);
-      g_free (identity_str);
-    }
-
-  if (auth_data != NULL)
-    {
-      GError *error;
-
-      error = g_error_new (POLKIT_ERROR,
-                           POLKIT_ERROR_FAILED,
-                           "Authentication is already in progress for another action");
-
-      polkit_agent_authentication_agent_finish (agent,
-                                                auth_data->pending_call,
-                                                error);
-
-      g_error_free (error);
-      goto out;
-    }
-
-  auth_data = auth_data_new (action_id,
-                             cookie,
-                             identities,
-                             pending_call);
-
-  g_idle_add (do_authentication, NULL);
-
- out:
-  ;
-}
-
-static void
-cancel_authentication_func (PolkitAgentAuthenticationAgent *agent,
-                            const gchar                    *cookie,
-                            gpointer                        user_data)
-{
-  g_debug ("Cancel authentication func cookie=%s", cookie);
-
-  if (auth_data != NULL)
-    {
-      if (strcmp (auth_data->cookie, cookie) == 0)
-        {
-          do_cancel_auth ();
-        }
-    }
-}
+#include "polkitgnomelistener.h"
 
 int
 main (int argc, char **argv)
 {
+  gint ret;
   GMainLoop *loop;
-  int ret;
+  PolkitAgentListener *listener;
 
   g_type_init ();
   gtk_init (&argc, &argv);
@@ -467,30 +48,18 @@
 
   ret = 1;
 
-  loop = NULL;
-  authority = NULL;
-  agent = NULL;
-
-  authority = polkit_authority_get ();
-
-  agent = polkit_agent_authentication_agent_new (begin_authentication_func,
-                                                 cancel_authentication_func,
-                                                 NULL);
+  listener = polkit_gnome_listener_new ();
+
+  polkit_agent_export_listener (listener, NULL, "/org/gnome/PolicyKit1/AuthenticationAgent");
 
   loop = g_main_loop_new (NULL, FALSE);
 
   g_main_loop_run (loop);
 
-  ret = 0;
-
-  if (agent != NULL)
-    g_object_unref (agent);
+  g_object_unref (listener);
+  g_main_loop_unref (loop);
 
-  if (loop != NULL)
-    g_main_loop_unref (loop);
-
-  if (authority != NULL)
-    g_object_unref (authority);
+  ret = 0;
 
   return ret;
 }

Copied: trunk/src/polkitgnomeauthenticationdialog.c (from r91, /trunk/src/polkit-gnome-auth-dialog.c)
==============================================================================
--- /trunk/src/polkit-gnome-auth-dialog.c	(original)
+++ trunk/src/polkitgnomeauthenticationdialog.c	Sat Jan 31 01:45:48 2009
@@ -1,21 +1,22 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
  *
- * Copyright (C) 2007 David Zeuthen <david fubar dk>
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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 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,
+ * This library 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser 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.
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
  *
+ * Author: David Zeuthen <davidz redhat com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -38,964 +39,959 @@
 #include <gtk/gtk.h>
 
 #include "sexy-url-label.h"
-#include "polkit-gnome-auth-dialog.h"
+#include "polkitgnomeauthenticationdialog.h"
 
-struct _PolkitGnomeAuthDialogPrivate
-{
-	GtkWidget *keep_privilege_check_button;
-	GtkWidget *keep_privilege_session_only_check_button;
-	GtkWidget *message_label;
-	GtkWidget *message_label_secondary;
-	GtkWidget *user_combobox;
-	GtkWidget *app_desc_label;
-	GtkWidget *privilege_desc_label;
-	GtkWidget *privilege_vendor_label;
-	GtkWidget *prompt_label;
-        GtkWidget *password_entry;
-	GtkWidget *icon;
-	char *message;
+#define RESPONSE_USER_SELECTED 1001
 
-	char *vendor;
-	char *vendor_url;
+struct _PolkitGnomeAuthenticationDialogPrivate
+{
+  GtkWidget *user_combobox;
+  GtkWidget *prompt_label;
+  GtkWidget *password_entry;
+  GtkWidget *auth_button;
+  GtkWidget *cancel_button;
+
+  gchar *message;
+  gchar *action_id;
+  gchar *program;
+  gchar *vendor;
+  gchar *vendor_url;
+  gchar *icon_name;
+  gchar **users;
+  gchar *selected_user;
 
-	gboolean can_do_always;
-	gboolean can_do_session;
+  gboolean is_running;
 
-	GtkListStore *store;
+  GtkListStore *store;
 };
 
-G_DEFINE_TYPE (PolkitGnomeAuthDialog, polkit_gnome_auth_dialog, GTK_TYPE_DIALOG);
+G_DEFINE_TYPE (PolkitGnomeAuthenticationDialog, polkit_gnome_authentication_dialog, GTK_TYPE_DIALOG);
 
 enum {
-	USER_SELECTED,
-	LAST_SIGNAL
+  PROP_0,
+  PROP_PROGRAM,
+  PROP_ACTION_ID,
+  PROP_VENDOR,
+  PROP_VENDOR_URL,
+  PROP_ICON_NAME,
+  PROP_MESSAGE,
+  PROP_USERS,
+  PROP_SELECTED_USER,
 };
 
-static guint signals[LAST_SIGNAL] = { 0 };
-
 enum {
-	PROP_0,
-	PROP_PROGRAM,
-	PROP_ACTION_ID,
-	PROP_VENDOR,
-	PROP_VENDOR_URL,
-	PROP_ICON_NAME,
-	PROP_MESSAGE,
-};
-
-enum {
-	PIXBUF_COL,
-	TEXT_COL,
-	USERNAME_COL,
-	N_COL
+  PIXBUF_COL,
+  TEXT_COL,
+  USERNAME_COL,
+  N_COL
 };
 
 static void
 user_combobox_set_sensitive (GtkCellLayout   *cell_layout,
-			     GtkCellRenderer *cell,
-			     GtkTreeModel    *tree_model,
-			     GtkTreeIter     *iter,
-			     gpointer         user_data)
-{
-	GtkTreePath *path;
-	gint *indices;
-	gboolean sensitive;
-	
-	path = gtk_tree_model_get_path (tree_model, iter);
-	indices = gtk_tree_path_get_indices (path);
-	if (indices[0] == 0)
-		sensitive = FALSE;
-	else
-		sensitive = TRUE;
-	gtk_tree_path_free (path);
-	
-	g_object_set (cell, "sensitive", sensitive, NULL);
-}
-
+                             GtkCellRenderer *cell,
+                             GtkTreeModel    *tree_model,
+                             GtkTreeIter     *iter,
+                             gpointer         user_data)
+{
+  GtkTreePath *path;
+  gint *indices;
+  gboolean sensitive;
+
+  path = gtk_tree_model_get_path (tree_model, iter);
+  indices = gtk_tree_path_get_indices (path);
+  if (indices[0] == 0)
+    sensitive = FALSE;
+  else
+    sensitive = TRUE;
+  gtk_tree_path_free (path);
 
-void
-polkit_gnome_auth_dialog_select_admin_user (PolkitGnomeAuthDialog *auth_dialog, const char *admin_user)
-{
-	GtkTreeIter iter;
-	gboolean done;
-	gboolean valid;
-
-	/* make the password and "Keep.." widgets sensitive again */
-	gtk_widget_set_sensitive (auth_dialog->priv->prompt_label, TRUE);
-	gtk_widget_set_sensitive (auth_dialog->priv->password_entry, TRUE);
-	gtk_widget_set_sensitive (auth_dialog->priv->keep_privilege_check_button, TRUE);
-	gtk_widget_set_sensitive (auth_dialog->priv->keep_privilege_session_only_check_button, TRUE);
-
-	/* select appropriate item in combobox */
-	valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (auth_dialog->priv->store), &iter);
-	done = FALSE;
-	while (valid && !done) {
-		char *str_data;
-		gtk_tree_model_get (GTK_TREE_MODEL (auth_dialog->priv->store), 
-				    &iter, 
-				    USERNAME_COL, &str_data,
-				    -1);
-		if (str_data != NULL && strcmp (admin_user, str_data) == 0) {
-			gtk_combo_box_set_active_iter (GTK_COMBO_BOX (auth_dialog->priv->user_combobox),
-						       &iter);
-			done = TRUE;
-		}
-		g_free (str_data);
-      
-		valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (auth_dialog->priv->store), &iter);
-	}
+  g_object_set (cell, "sensitive", sensitive, NULL);
 }
 
 static void
 user_combobox_changed (GtkComboBox *widget,
-		       gpointer     user_data)
+                       gpointer     user_data)
 {
-	char *user_name;
-	PolkitGnomeAuthDialog *auth_dialog = POLKIT_GNOME_AUTH_DIALOG (user_data);
-	GtkTreeIter iter;
-
-	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)) {
-		gtk_tree_model_get (GTK_TREE_MODEL (auth_dialog->priv->store), &iter, USERNAME_COL, &user_name, -1);
-		g_signal_emit (auth_dialog, signals[USER_SELECTED], 0, user_name);
-
-		polkit_gnome_auth_dialog_select_admin_user (auth_dialog, user_name);
-
-		g_free (user_name);
-	}
-}
-
-static void
-create_user_combobox (PolkitGnomeAuthDialog *auth_dialog, char **admin_users)
-{
-	int n;
-	GtkComboBox *combo;
-	GtkTreeIter iter;
-	GtkCellRenderer *renderer;
-
-	/* if we've already built the list of admin users once, then avoid
-	 * doing it again.. (this is mainly used when the user entered the
-	 * wrong password and the dialog is recycled)
-	 */
-	if (auth_dialog->priv->store != NULL)
-		return;
-
-	combo = GTK_COMBO_BOX (auth_dialog->priv->user_combobox);
-	auth_dialog->priv->store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
-
-	gtk_list_store_append (auth_dialog->priv->store, &iter);
-	gtk_list_store_set (auth_dialog->priv->store, &iter,
-			    PIXBUF_COL, NULL,
-			    TEXT_COL, _("Select user..."),
-			    USERNAME_COL, NULL,
-			    -1);
-       	
-
-	/* For each user */
-	for (n = 0; admin_users[n] != NULL; n++) {
-		char *real_name;
-		GdkPixbuf *pixbuf;
-		struct passwd *passwd;
-
-		/* we're single threaded so this is fine */
-		errno = 0;
-		passwd = getpwnam (admin_users[n]);
-		if (passwd == NULL) {
-			g_warning ("Error doing getpwnam(\"%s\"): %s", admin_users[n], strerror (errno));
-			continue;
-		}
-
-		/* Real name */
-		if (passwd->pw_gecos != NULL && strlen (passwd->pw_gecos) > 0)
-			real_name = g_strdup_printf (_("%s (%s)"), passwd->pw_gecos, admin_users[n]);
-		else
-			real_name = g_strdup (admin_users[n]);
-
-		/* Load users face */
-		pixbuf = NULL;
-		if (passwd->pw_dir != NULL) {
-			char *path;
-			path = g_strdup_printf ("%s/.face", passwd->pw_dir);
-			/* TODO: we probably shouldn't hard-code the size to 24x24*/
-			pixbuf = gdk_pixbuf_new_from_file_at_scale (path, 24, 24, TRUE, NULL);
-			g_free (path);
-		}
-
-		/* fall back to stock_person icon */
-		if (pixbuf == NULL)
-			pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
-							   "stock_person", GTK_ICON_SIZE_MENU, 0, NULL);
-
-		gtk_list_store_append (auth_dialog->priv->store, &iter);
-		gtk_list_store_set (auth_dialog->priv->store, &iter,
-				    PIXBUF_COL, pixbuf,
-				    TEXT_COL, real_name,
-				    USERNAME_COL, admin_users[n],
-				    -1);
-
-		g_free (real_name);
-		g_object_unref (pixbuf);
-
-	}
-	
-	gtk_combo_box_set_model (combo, GTK_TREE_MODEL (auth_dialog->priv->store));
-
-	renderer = gtk_cell_renderer_pixbuf_new ();
-	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
-	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
-					"pixbuf", PIXBUF_COL,
-					NULL);
-	gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo),
-					    renderer,
-					    user_combobox_set_sensitive,
-					    NULL, NULL);
-	
-	renderer = gtk_cell_renderer_text_new ();
-	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
-	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
-					"text", TEXT_COL,
-					NULL);
-	gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo),
-					    renderer,
-					    user_combobox_set_sensitive,
-					    NULL, NULL);
-
-	/* Initially select the "Select user..." ... */
-	gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
-
-	/* Listen when a new user is selected */
-	g_signal_connect (GTK_WIDGET (combo), "changed",
-			  G_CALLBACK (user_combobox_changed), auth_dialog);
-
-	/* ... and make the password and "Keep.." widgets insensitive */
-	gtk_widget_set_sensitive (auth_dialog->priv->prompt_label, FALSE);
-	gtk_widget_set_sensitive (auth_dialog->priv->password_entry, FALSE);
-	gtk_widget_set_sensitive (auth_dialog->priv->keep_privilege_check_button, FALSE);
-	gtk_widget_set_sensitive (auth_dialog->priv->keep_privilege_session_only_check_button, FALSE);
-}
-
-void
-polkit_gnome_auth_dialog_set_options (PolkitGnomeAuthDialog *auth_dialog, 
-				      gboolean session, 
-				      gboolean always,
-				      gboolean requires_admin,
-				      char **admin_users)
-{
-	const char *message_markup_secondary;
-
-	auth_dialog->priv->can_do_always = always;
-	auth_dialog->priv->can_do_session = session;
-
-	if (auth_dialog->priv->can_do_session) {
-		gtk_button_set_label (GTK_BUTTON (auth_dialog->priv->keep_privilege_check_button), 
-				      _("_Remember authorization for this session"));
-
-		gtk_widget_set_no_show_all (auth_dialog->priv->keep_privilege_check_button, FALSE);
-		gtk_widget_set_no_show_all (auth_dialog->priv->keep_privilege_session_only_check_button, TRUE);
-	} else if (auth_dialog->priv->can_do_always) {
-		gtk_button_set_label (GTK_BUTTON (auth_dialog->priv->keep_privilege_check_button), 
-				      _("_Remember authorization"));
-
-		gtk_widget_set_no_show_all (auth_dialog->priv->keep_privilege_check_button, FALSE);
-		gtk_widget_set_no_show_all (auth_dialog->priv->keep_privilege_session_only_check_button, FALSE);
-
-	} else {
-		gtk_widget_set_no_show_all (auth_dialog->priv->keep_privilege_check_button, TRUE);
-		gtk_widget_set_no_show_all (auth_dialog->priv->keep_privilege_session_only_check_button, TRUE);
-	}
-
-	gtk_widget_set_no_show_all (auth_dialog->priv->user_combobox, TRUE);
-		
-	if (requires_admin) {
-		if (admin_users != NULL) {
-			message_markup_secondary =
-				_("An application is attempting to perform an action that requires privileges. Authentication as one of the users below is required to perform this action.");
-
-			create_user_combobox (auth_dialog, admin_users);
-			gtk_widget_set_no_show_all (auth_dialog->priv->user_combobox, FALSE);
-
-		} else {
-			message_markup_secondary =
-				_("An application is attempting to perform an action that requires privileges. Authentication as the super user is required to perform this action.");
-		}
-	} else {
-		message_markup_secondary =
-			_("An application is attempting to perform an action that requires privileges. Authentication is required to perform this action.");
-	}
-	gtk_label_set_markup (GTK_LABEL (auth_dialog->priv->message_label_secondary), message_markup_secondary);
-}
-
-static void
-polkit_gnome_auth_dialog_set_message (PolkitGnomeAuthDialog *auth_dialog, const char *markup)
-{
-	char *str;
-	str = g_strdup_printf ("<big><b>%s</b></big>", markup);
-        gtk_label_set_markup (GTK_LABEL (auth_dialog->priv->message_label), str);
-	g_free (str);
-}
-
-static void
-retain_checkbox_set_defaults (PolkitGnomeAuthDialog *auth_dialog, const char *action_id)
-{
-	gboolean retain_authorization;
-        GConfClient *client;
-	GError *error;
-	GSList *action_list, *l;
-
-        client = gconf_client_get_default ();
-	retain_authorization = TRUE;
-
-	if (client == NULL) {
-		g_warning ("Error getting GConfClient");
-		goto out;
-	}
-
-	error = NULL;
-	retain_authorization = gconf_client_get_bool (client, KEY_AUTH_DIALOG_RETAIN_AUTHORIZATION, &error);
-	if (error != NULL) {
-		g_warning ("Error getting key %s: %s",
-			   KEY_AUTH_DIALOG_RETAIN_AUTHORIZATION,
-			   error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* check the blacklist */
-	if (!retain_authorization)
-		goto out;
-
-	action_list = gconf_client_get_list (client,
-					     KEY_AUTH_DIALOG_RETAIN_AUTHORIZATION_BLACKLIST,
-					     GCONF_VALUE_STRING,
-					     &error);
-	if (error != NULL) {
-		g_warning ("Error getting key %s: %s",
-			   KEY_AUTH_DIALOG_RETAIN_AUTHORIZATION_BLACKLIST,
-			   error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	for (l = action_list; l != NULL; l = l->next) {
-		const char *str = l->data;
-		if (strcmp (str, action_id) == 0) {
-			retain_authorization = FALSE;
-			break;
-		}
-	}
-	g_slist_foreach (action_list, (GFunc) g_free, NULL);
-	g_slist_free (action_list);
-
-out:
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (auth_dialog->priv->keep_privilege_check_button),
-				      retain_authorization);
-}
+  PolkitGnomeAuthenticationDialog *dialog = POLKIT_GNOME_AUTHENTICATION_DIALOG (user_data);
+  GtkTreeIter iter;
+  gchar *user_name;
+
+  if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter))
+    {
+      gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->store), &iter, USERNAME_COL, &user_name, -1);
+
+      g_free (dialog->priv->selected_user);
+      dialog->priv->selected_user = user_name;
+
+      g_object_notify (G_OBJECT (dialog), "selected-user");
+
+      gtk_dialog_response (GTK_DIALOG (dialog), RESPONSE_USER_SELECTED);
+
+      /* make the password entry and Authenticate button sensitive again */
+      gtk_widget_set_sensitive (dialog->priv->prompt_label, TRUE);
+      gtk_widget_set_sensitive (dialog->priv->password_entry, TRUE);
+      gtk_widget_set_sensitive (dialog->priv->auth_button, TRUE);
+    }
+}
+
+static void
+create_user_combobox (PolkitGnomeAuthenticationDialog *dialog)
+{
+  int n;
+  GtkComboBox *combo;
+  GtkTreeIter iter;
+  GtkCellRenderer *renderer;
+
+  /* if we've already built the list of admin users once, then avoid
+   * doing it again.. (this is mainly used when the user entered the
+   * wrong password and the dialog is recycled)
+   */
+  if (dialog->priv->store != NULL)
+    return;
+
+  combo = GTK_COMBO_BOX (dialog->priv->user_combobox);
+  dialog->priv->store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
+
+  gtk_list_store_append (dialog->priv->store, &iter);
+  gtk_list_store_set (dialog->priv->store, &iter,
+                      PIXBUF_COL, NULL,
+                      TEXT_COL, _("Select user..."),
+                      USERNAME_COL, NULL,
+                      -1);
+
+
+  /* For each user */
+  for (n = 0; dialog->priv->users[n] != NULL; n++)
+    {
+      gchar *real_name;
+      GdkPixbuf *pixbuf;
+      struct passwd *passwd;
+
+      /* we're single threaded so this is fine */
+      errno = 0;
+      passwd = getpwnam (dialog->priv->users[n]);
+      if (passwd == NULL)
+        {
+          g_warning ("Error doing getpwnam(\"%s\"): %s", dialog->priv->users[n], strerror (errno));
+          continue;
+        }
 
-static void
-polkit_gnome_auth_dialog_set_action_id (PolkitGnomeAuthDialog *auth_dialog, const char *action_id)
-{
-	char *str;
-	str = g_strdup_printf ("<small><a href=\"%s\">%s</a></small>", 
-			       action_id, 
-			       action_id);
-	sexy_url_label_set_markup (SEXY_URL_LABEL (auth_dialog->priv->privilege_desc_label), str);
-	g_free (str);
+      /* Real name */
+      if (passwd->pw_gecos != NULL && strlen (passwd->pw_gecos) > 0)
+        real_name = g_strdup_printf (_("%s (%s)"), passwd->pw_gecos, dialog->priv->users[n]);
+      else
+        real_name = g_strdup (dialog->priv->users[n]);
+
+      /* Load users face */
+      pixbuf = NULL;
+      if (passwd->pw_dir != NULL)
+        {
+          gchar *path;
+          path = g_strdup_printf ("%s/.face", passwd->pw_dir);
+          /* TODO: we probably shouldn't hard-code the size to 24x24*/
+          pixbuf = gdk_pixbuf_new_from_file_at_scale (path, 24, 24, TRUE, NULL);
+          g_free (path);
+        }
 
-	str = g_strdup_printf (_("Click to edit %s"), action_id);
-	gtk_widget_set_tooltip_markup (auth_dialog->priv->privilege_desc_label, str);
-	g_free (str);
+      /* fall back to stock_person icon */
+      if (pixbuf == NULL)
+        {
+          pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+                                             "stock_person",
+                                             GTK_ICON_SIZE_MENU,
+                                             0,
+                                             NULL);
+        }
 
-	retain_checkbox_set_defaults (auth_dialog, action_id);
+      gtk_list_store_append (dialog->priv->store, &iter);
+      gtk_list_store_set (dialog->priv->store, &iter,
+                          PIXBUF_COL, pixbuf,
+                          TEXT_COL, real_name,
+                          USERNAME_COL, dialog->priv->users[n],
+                          -1);
+
+      g_free (real_name);
+      g_object_unref (pixbuf);
+    }
+
+  gtk_combo_box_set_model (combo, GTK_TREE_MODEL (dialog->priv->store));
+
+  renderer = gtk_cell_renderer_pixbuf_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo),
+                                  renderer,
+                                  "pixbuf", PIXBUF_COL,
+                                  NULL);
+  gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo),
+                                      renderer,
+                                      user_combobox_set_sensitive,
+                                      NULL, NULL);
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo),
+                                  renderer,
+                                  "text", TEXT_COL,
+                                  NULL);
+  gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo),
+                                      renderer,
+                                      user_combobox_set_sensitive,
+                                      NULL, NULL);
+
+  /* Initially select the "Select user..." ... */
+  gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+
+  /* Listen when a new user is selected */
+  g_signal_connect (GTK_WIDGET (combo),
+                    "changed",
+                    G_CALLBACK (user_combobox_changed),
+                    dialog);
 }
 
-static void
-update_vendor (PolkitGnomeAuthDialog *auth_dialog)
+static GtkWidget *
+get_image (PolkitGnomeAuthenticationDialog *dialog)
 {
-	char *str;
+  GdkPixbuf *pixbuf;
+  GdkPixbuf *copy_pixbuf;
+  GdkPixbuf *vendor_pixbuf;
+  GtkWidget *image;
+
+  pixbuf = NULL;
+  copy_pixbuf = NULL;
+  vendor_pixbuf = NULL;
+
+  if (dialog->priv->icon_name == NULL)
+    {
+      image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);
+      goto out;
+    }
+
+  vendor_pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+                                            dialog->priv->icon_name,
+                                            48,
+                                            0,
+                                            NULL);
+  if (vendor_pixbuf == NULL)
+    {
+      g_warning ("No icon for themed icon with name %s", dialog->priv->icon_name);
+      image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);
+      goto out;
+    }
+
+
+  pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+                                     GTK_STOCK_DIALOG_AUTHENTICATION,
+                                     48,
+                                     0,
+                                     NULL);
+  if (pixbuf == NULL)
+    goto out;
+
+  /* need to copy the pixbuf since we're modifying it */
+  copy_pixbuf = gdk_pixbuf_copy (pixbuf);
+  if (copy_pixbuf == NULL)
+    goto out;
+
+  /* blend the vendor icon in the bottom right quarter */
+  gdk_pixbuf_composite (vendor_pixbuf,
+                        copy_pixbuf,
+                        24, 24, 24, 24,
+                        24, 24, 0.5, 0.5,
+                        GDK_INTERP_BILINEAR,
+                        255);
+
+  image = gtk_image_new_from_pixbuf (copy_pixbuf);
 
-	if (auth_dialog->priv->vendor == NULL)
-		return;
+out:
+  if (pixbuf != NULL)
+    g_object_unref (pixbuf);
 
-	if (auth_dialog->priv->vendor_url == NULL) {
-		str = g_strdup_printf ("<small>%s</small>", auth_dialog->priv->vendor);
-		gtk_widget_set_tooltip_markup (auth_dialog->priv->privilege_vendor_label, NULL);
-	} else {
-		char *s2;
+  if (copy_pixbuf != NULL)
+    g_object_unref (copy_pixbuf);
 
-		str = g_strdup_printf ("<small><a href=\"%s\">%s</a></small>", 
-				       auth_dialog->priv->vendor_url, 
-				       auth_dialog->priv->vendor);
+  if (vendor_pixbuf != NULL)
+    g_object_unref (vendor_pixbuf);
 
-		s2 = g_strdup_printf (_("Click to open %s"), auth_dialog->priv->vendor_url);
-		gtk_widget_set_tooltip_markup (auth_dialog->priv->privilege_vendor_label, s2);
-		g_free (s2);
-	}
-	sexy_url_label_set_markup (SEXY_URL_LABEL (auth_dialog->priv->privilege_vendor_label), str);
-	g_free (str);
+  return image;
 }
 
 static void
-polkit_gnome_auth_dialog_set_icon_name (PolkitGnomeAuthDialog *auth_dialog, const char *icon_name)
+polkit_gnome_authentication_dialog_set_property (GObject      *object,
+                                                 guint         prop_id,
+                                                 const GValue *value,
+                                                 GParamSpec   *pspec)
 {
-	GdkPixbuf *pixbuf;
-	GdkPixbuf *copy_pixbuf;
-	GdkPixbuf *vendor_pixbuf;
+  PolkitGnomeAuthenticationDialog *dialog = POLKIT_GNOME_AUTHENTICATION_DIALOG (object);
 
-	pixbuf = NULL;
-	copy_pixbuf = NULL;
-	vendor_pixbuf = NULL;
+  switch (prop_id)
+    {
+    case PROP_PROGRAM:
+      dialog->priv->program = g_value_dup_string (value);
+      break;
 
-	vendor_pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
-						  icon_name,
-						  48,
-						  0,
-						  NULL);
-	if (vendor_pixbuf == NULL)
-		goto out;
+    case PROP_ACTION_ID:
+      dialog->priv->action_id = g_value_dup_string (value);
+      break;
 
-	pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
-					   GTK_STOCK_DIALOG_AUTHENTICATION,
-					   48,
-					   0,
-					   NULL);
-	if (pixbuf == NULL)
-		goto out;
+    case PROP_VENDOR:
+      dialog->priv->vendor = g_value_dup_string (value);
+      break;
 
-	/* need to copy the pixbuf since we're modifying it */
-	copy_pixbuf = gdk_pixbuf_copy (pixbuf);
-	if (copy_pixbuf == NULL)
-		goto out;
+    case PROP_VENDOR_URL:
+      dialog->priv->vendor_url = g_value_dup_string (value);
+      break;
 
-	/* blend the vendor icon in the bottom right quarter */
-	gdk_pixbuf_composite (vendor_pixbuf,
-			      copy_pixbuf,
-			      24, 24, 24, 24,
-			      24, 24, 0.5, 0.5,
-			      GDK_INTERP_BILINEAR,
-			      255);
+    case PROP_ICON_NAME:
+      dialog->priv->icon_name = g_value_dup_string (value);
+      break;
 
-	gtk_image_set_from_pixbuf (GTK_IMAGE (auth_dialog->priv->icon),
-				   copy_pixbuf);
+    case PROP_MESSAGE:
+      dialog->priv->message = g_value_dup_string (value);
+      break;
 
-out:
-	if (pixbuf != NULL)
-		g_object_unref (pixbuf);
-	if (copy_pixbuf != NULL)
-		g_object_unref (copy_pixbuf);
-	if (vendor_pixbuf != NULL)
-		g_object_unref (vendor_pixbuf);
+    case PROP_USERS:
+      dialog->priv->users = g_value_dup_boxed (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
 }
 
 static void
-polkit_gnome_auth_dialog_set_program (PolkitGnomeAuthDialog *auth_dialog, const char *program)
+polkit_gnome_authentication_dialog_get_property (GObject    *object,
+                                                 guint       prop_id,
+                                                 GValue     *value,
+                                                 GParamSpec *pspec)
 {
-	char *str;
-	str = g_strdup_printf ("<small>%s</small>", program);
-	gtk_label_set_markup (GTK_LABEL (auth_dialog->priv->app_desc_label), str);
-	g_free (str);
-}
+  PolkitGnomeAuthenticationDialog *dialog = POLKIT_GNOME_AUTHENTICATION_DIALOG (object);
 
+  switch (prop_id)
+    {
+    case PROP_MESSAGE:
+      g_value_set_string (value, dialog->priv->message);
+      break;
 
-void
-polkit_gnome_auth_dialog_set_prompt (PolkitGnomeAuthDialog *auth_dialog, 
-					const char *prompt, 
-					gboolean show_chars)
-{
-	gtk_label_set_text_with_mnemonic (GTK_LABEL (auth_dialog->priv->prompt_label), prompt);
-	gtk_entry_set_visibility (GTK_ENTRY (auth_dialog->priv->password_entry), show_chars);
-	gtk_entry_set_text (GTK_ENTRY (auth_dialog->priv->password_entry), "");
-	gtk_widget_grab_focus (auth_dialog->priv->password_entry);
-}
-
-static void
-polkit_gnome_auth_dialog_set_property (GObject *object,
-					  guint prop_id,
-					  const GValue *value,
-					  GParamSpec *pspec)
-{
-	PolkitGnomeAuthDialog *auth_dialog = POLKIT_GNOME_AUTH_DIALOG (object);
-	switch (prop_id)
-	{
-	case PROP_PROGRAM:
-		polkit_gnome_auth_dialog_set_program (auth_dialog, g_value_get_string (value));
-		break;
-
-	case PROP_ACTION_ID:
-		polkit_gnome_auth_dialog_set_action_id (auth_dialog, g_value_get_string (value));
-		break;
-
-	case PROP_VENDOR:
-		g_free (auth_dialog->priv->vendor);
-		auth_dialog->priv->vendor = g_strdup (g_value_get_string (value));
-		update_vendor (auth_dialog);
-		break;
-
-	case PROP_VENDOR_URL:
-		g_free (auth_dialog->priv->vendor_url);
-		auth_dialog->priv->vendor_url = g_strdup (g_value_get_string (value));
-		update_vendor (auth_dialog);
-		break;
-
-	case PROP_ICON_NAME:
-		polkit_gnome_auth_dialog_set_icon_name (auth_dialog, g_value_get_string (value));
-		break;
-
-	case PROP_MESSAGE:
-		if (auth_dialog->priv->message)
-			g_free (auth_dialog->priv->message);
-		auth_dialog->priv->message = g_strdup (g_value_get_string (value));
-		polkit_gnome_auth_dialog_set_message (auth_dialog, auth_dialog->priv->message);
-		break;
-
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-polkit_gnome_auth_dialog_get_property (GObject *object,
-					  guint prop_id,
-					  GValue *value,
-					  GParamSpec *pspec)
-{
-	PolkitGnomeAuthDialog *auth_dialog = POLKIT_GNOME_AUTH_DIALOG (object);
-
-	switch (prop_id)
-	{
-	case PROP_MESSAGE:
-		g_value_set_string (value, auth_dialog->priv->message);
-		break;
-		
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
+    /* TODO: rest of the properties */
 
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
 }
 
 static GtkWidget *
 add_row (GtkWidget *table, int row, const char *label_text, GtkWidget *entry)
 {
-	GtkWidget *label;
-
-	label = gtk_label_new_with_mnemonic (label_text);
-	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
-
-	gtk_table_attach (GTK_TABLE (table), label,
-			  0, 1, row, row + 1,
-			  GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-	gtk_table_attach_defaults (GTK_TABLE (table), entry,
-				   1, 2, row, row + 1);
-	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
-
-	return label;
-}
+  GtkWidget *label;
 
-static void
-remember_check_button_toggled (GtkWidget *widget, PolkitGnomeAuthDialog *auth_dialog)
-{
-	gboolean toggled;
+  label = gtk_label_new_with_mnemonic (label_text);
+  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+
+  gtk_table_attach (GTK_TABLE (table), label,
+                    0, 1, row, row + 1,
+                    GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+  gtk_table_attach_defaults (GTK_TABLE (table), entry,
+                                   1, 2, row, row + 1);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
 
-	toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
-	if (auth_dialog->priv->keep_privilege_session_only_check_button != NULL) {
-		gtk_widget_set_sensitive (auth_dialog->priv->keep_privilege_session_only_check_button, toggled);
-	}
+  return label;
 }
 
 static void
 vendor_url_activated (SexyUrlLabel *url_label, char *url, gpointer user_data)
 {
-        if (url != NULL) {
-                gtk_show_uri (NULL, url, GDK_CURRENT_TIME, NULL);
-        }
+  if (url != NULL)
+    gtk_show_uri (NULL, url, GDK_CURRENT_TIME, NULL);
 }
 
 static void
 action_id_activated (SexyUrlLabel *url_label, char *url, gpointer user_data)
 {
 #if 0
-        GError *error;
-        DBusGConnection *bus;
-        DBusGProxy *manager_proxy;
-
-        error = NULL;
-        bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-        if (bus == NULL) {
-                g_warning ("Couldn't connect to session bus: %s", error->message);
-                g_error_free (error);
-                goto out;
+  GError *error;
+  DBusGConnection *bus;
+  DBusGProxy *manager_proxy;
+
+  error = NULL;
+  bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+  if (bus == NULL)
+    {
+      g_warning ("Couldn't connect to session bus: %s", error->message);
+      g_error_free (error);
+      goto out;
+    }
+
+  manager_proxy = dbus_g_proxy_new_for_name (bus,
+                                             "org.gnome.PolicyKit.AuthorizationManager",
+                                             "/",
+                                             "org.gnome.PolicyKit.AuthorizationManager.SingleInstance");
+  if (manager_proxy == NULL)
+    {
+      g_warning ("Could not construct manager_proxy object; bailing out");
+      goto out;
+    }
+
+  if (!dbus_g_proxy_call (manager_proxy,
+                          "ShowAction",
+                          &error,
+                          G_TYPE_STRING, url,
+                          G_TYPE_INVALID,
+                          G_TYPE_INVALID))
+    {
+      if (error != NULL)
+        {
+          g_warning ("Failed to call into manager: %s", error->message);
+          g_error_free (error);
         }
-
-	manager_proxy = dbus_g_proxy_new_for_name (bus,
-                                               "org.gnome.PolicyKit.AuthorizationManager",
-                                               "/",
-                                               "org.gnome.PolicyKit.AuthorizationManager.SingleInstance");
-        if (manager_proxy == NULL) {
-                g_warning ("Could not construct manager_proxy object; bailing out");
-                goto out;
+      else
+        {
+          g_warning ("Failed to call into manager");
         }
+      goto out;
+    }
 
-	if (!dbus_g_proxy_call (manager_proxy,
-                                "ShowAction",
-                                &error,
-                                G_TYPE_STRING, url,
-                                G_TYPE_INVALID,
-                                G_TYPE_INVALID)) {
-                if (error != NULL) {
-                        g_warning ("Failed to call into manager: %s", error->message);
-                        g_error_free (error);
-                } else {
-                        g_warning ("Failed to call into manager");
-                }
-                goto out;
-	}
 out:
-	;
+        ;
 #endif
 }
 
 static void
-polkit_gnome_auth_dialog_init (PolkitGnomeAuthDialog *auth_dialog)
+polkit_gnome_authentication_dialog_init (PolkitGnomeAuthenticationDialog *dialog)
 {
-	GtkDialog *dialog = GTK_DIALOG (auth_dialog);
-	PolkitGnomeAuthDialogPrivate *priv;
-
-	priv = auth_dialog->priv = g_new0 (PolkitGnomeAuthDialogPrivate, 1);
-
-        gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
-        gtk_dialog_add_button (dialog, _("_Authenticate"), GTK_RESPONSE_OK);
-	gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
-
-	gtk_dialog_set_has_separator (dialog, FALSE);
-	gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
-	gtk_box_set_spacing (GTK_BOX (dialog->vbox), 2); /* 2 * 5 + 2 = 12 */
-	gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 5);
-	gtk_box_set_spacing (GTK_BOX (dialog->action_area), 6);
-	gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
-	gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DIALOG_AUTHENTICATION);
-
-	GtkWidget *hbox, *main_vbox, *vbox;
-
-	hbox = gtk_hbox_new (FALSE, 12);
-	gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
-	gtk_box_pack_start (GTK_BOX (dialog->vbox), hbox, TRUE, TRUE, 0);
-
-	priv->icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);
-	gtk_misc_set_alignment (GTK_MISC (priv->icon), 0.5, 0.0);
-	gtk_box_pack_start (GTK_BOX (hbox), priv->icon, FALSE, FALSE, 0);
-
-	main_vbox = gtk_vbox_new (FALSE, 10);
-	gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0);
-
-	/* main message */
-	priv->message_label = gtk_label_new (NULL);
-	polkit_gnome_auth_dialog_set_message (auth_dialog, "");
-	gtk_misc_set_alignment (GTK_MISC (priv->message_label), 0.0, 0.5);
-	gtk_label_set_line_wrap (GTK_LABEL (priv->message_label), TRUE);
-	gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (priv->message_label),
-			    FALSE, FALSE, 0);
-
-
-	/* secondary message */
-	priv->message_label_secondary = gtk_label_new (NULL);
-        gtk_label_set_markup (GTK_LABEL (priv->message_label_secondary), "");
-	gtk_misc_set_alignment (GTK_MISC (priv->message_label_secondary), 0.0, 0.5);
-	gtk_label_set_line_wrap (GTK_LABEL (priv->message_label_secondary), TRUE);
-	gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (priv->message_label_secondary),
-			    FALSE, FALSE, 0);
-
-	/* user combobox */
-	priv->user_combobox = gtk_combo_box_new ();
-	gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (priv->user_combobox), FALSE, FALSE, 0);
-
-	/* password entry */
-	vbox = gtk_vbox_new (FALSE, 6);
-	gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
-
-        GtkWidget *table_alignment;
-        GtkWidget *table;
-	table_alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
-	gtk_box_pack_start (GTK_BOX (vbox), table_alignment, FALSE, FALSE, 0);
-	table = gtk_table_new (1, 2, FALSE);
-	gtk_table_set_col_spacings (GTK_TABLE (table), 12);
-	gtk_table_set_row_spacings (GTK_TABLE (table), 6);
-	gtk_container_add (GTK_CONTAINER (table_alignment), table);
-	priv->password_entry = gtk_entry_new ();
-	gtk_entry_set_visibility (GTK_ENTRY (priv->password_entry), FALSE);
-        priv->prompt_label = add_row (table, 0, _("_Password:"), priv->password_entry);
-
-	g_signal_connect_swapped (priv->password_entry, "activate",
-				  G_CALLBACK (gtk_window_activate_default),
-				  dialog);
-
-	priv->keep_privilege_check_button = gtk_check_button_new_with_mnemonic ("");
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->keep_privilege_check_button), TRUE);
-	gtk_box_pack_start (GTK_BOX (vbox), priv->keep_privilege_check_button, FALSE, FALSE, 0);
-	g_signal_connect (priv->keep_privilege_check_button, "toggled",
-			  G_CALLBACK (remember_check_button_toggled), auth_dialog);
-
-	GtkWidget *keep_alignment;
-	keep_alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
-	gtk_alignment_set_padding (GTK_ALIGNMENT (keep_alignment), 0, 0, 10, 0);
-	
-	gtk_box_pack_start (GTK_BOX (vbox), keep_alignment, FALSE, FALSE, 0);
-	GtkWidget *vbox3;
-	vbox3 = gtk_vbox_new (FALSE, 6);
-	gtk_container_add (GTK_CONTAINER (keep_alignment), vbox3);
-	
-	priv->keep_privilege_session_only_check_button = 
-		gtk_check_button_new_with_mnemonic (_("For this _session only"));
-	gtk_box_pack_start (GTK_BOX (vbox3), priv->keep_privilege_session_only_check_button, FALSE, FALSE, 0);
-
-	gtk_widget_set_no_show_all (auth_dialog->priv->keep_privilege_check_button, TRUE);
-	gtk_widget_set_no_show_all (auth_dialog->priv->keep_privilege_session_only_check_button, TRUE);
-
-
-	GtkWidget *details_expander;
-	details_expander = gtk_expander_new_with_mnemonic (_("<small><b>_Details</b></small>"));
-	gtk_expander_set_use_markup (GTK_EXPANDER (details_expander), TRUE);
-	gtk_box_pack_start (GTK_BOX (dialog->vbox), details_expander, FALSE, FALSE, 0);
-	//gtk_box_pack_start (GTK_BOX (vbox), details_expander, FALSE, FALSE, 0);
-
-	GtkWidget *details_vbox;
-	details_vbox = gtk_vbox_new (FALSE, 10);
-	gtk_container_add (GTK_CONTAINER (details_expander), details_vbox);
-
-        //GtkWidget *table_alignment;
-        //GtkWidget *table;
-	table_alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
-	gtk_box_pack_start (GTK_BOX (details_vbox), table_alignment, FALSE, FALSE, 0);
-	table = gtk_table_new (1, 3, FALSE);
-	gtk_table_set_col_spacings (GTK_TABLE (table), 12);
-	gtk_table_set_row_spacings (GTK_TABLE (table), 6);
-	gtk_container_add (GTK_CONTAINER (table_alignment), table);
-
-
-	priv->app_desc_label = gtk_label_new (NULL);
-	gtk_misc_set_alignment (GTK_MISC (priv->app_desc_label), 0, 1.0);
-        add_row (table, 0, _("<small><b>Application:</b></small>"), priv->app_desc_label);
-
-	priv->privilege_desc_label = sexy_url_label_new ();
-	gtk_misc_set_alignment (GTK_MISC (priv->privilege_desc_label), 0, 1.0);
-        add_row (table, 1, _("<small><b>Action:</b></small>"), priv->privilege_desc_label);
-        g_signal_connect (priv->privilege_desc_label, "url-activated", (GCallback) action_id_activated, NULL);
-
-	priv->privilege_vendor_label = sexy_url_label_new ();
-	gtk_misc_set_alignment (GTK_MISC (priv->privilege_vendor_label), 0, 1.0);
-        add_row (table, 2, _("<small><b>Vendor:</b></small>"), priv->privilege_vendor_label);
-        g_signal_connect (priv->privilege_vendor_label, "url-activated", (GCallback) vendor_url_activated, NULL);
-}
-
-static void
-polkit_gnome_auth_dialog_finalize (GObject *object)
-{
-	PolkitGnomeAuthDialog *auth_dialog = POLKIT_GNOME_AUTH_DIALOG (object);
-
-	g_free (auth_dialog->priv);
-
-	G_OBJECT_CLASS (polkit_gnome_auth_dialog_parent_class)->finalize (object);
-}
-
-#define PARAM_STATIC G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
-
-static void
-polkit_gnome_auth_dialog_class_init (PolkitGnomeAuthDialogClass * klass)
-{
-	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
-	polkit_gnome_auth_dialog_parent_class = (GObjectClass *) g_type_class_peek_parent (klass);
-
-	gobject_class->finalize = polkit_gnome_auth_dialog_finalize;
-	gobject_class->get_property = polkit_gnome_auth_dialog_get_property;
-	gobject_class->set_property = polkit_gnome_auth_dialog_set_property;
-
-	g_object_class_install_property
-		(gobject_class,
-		 PROP_PROGRAM,
-		 g_param_spec_string ("program",
-				      "program",
-				      "program",
-				      NULL,
-				      G_PARAM_READWRITE | PARAM_STATIC));
-
-	g_object_class_install_property
-		(gobject_class,
-		 PROP_ACTION_ID,
-		 g_param_spec_string ("action-id",
-				      "action-id",
-				      "action-id",
-				      NULL,
-				      G_PARAM_READWRITE | PARAM_STATIC));
-
-	g_object_class_install_property
-		(gobject_class,
-		 PROP_VENDOR,
-		 g_param_spec_string ("vendor",
-				      "vendor",
-				      "vendor",
-				      NULL,
-				      G_PARAM_READWRITE | PARAM_STATIC));
-
-	g_object_class_install_property
-		(gobject_class,
-		 PROP_VENDOR_URL,
-		 g_param_spec_string ("vendor-url",
-				      "vendor-url",
-				      "vendor-url",
-				      NULL,
-				      G_PARAM_READWRITE | PARAM_STATIC));
-
-	g_object_class_install_property
-		(gobject_class,
-		 PROP_ICON_NAME,
-		 g_param_spec_string ("icon-name",
-				      "icon-name",
-				      "icon-name",
-				      NULL,
-				      G_PARAM_READWRITE | PARAM_STATIC));
-
-
-	g_object_class_install_property
-		(gobject_class,
-		 PROP_MESSAGE,
-		 g_param_spec_string ("message",
-				      "message",
-				      "message",
-				      NULL,
-				      G_PARAM_READWRITE | PARAM_STATIC));
-
-
-	signals[USER_SELECTED] =
-		g_signal_new ("user-selected",
-			      G_TYPE_FROM_CLASS (klass),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (PolkitGnomeAuthDialogClass,
-					       user_selected),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__STRING,
-			      G_TYPE_NONE, 1,
-			      G_TYPE_STRING);
-
+  dialog->priv = G_TYPE_INSTANCE_GET_PRIVATE (dialog,
+                                                   POLKIT_GNOME_TYPE_AUTHENTICATION_DIALOG,
+                                                   PolkitGnomeAuthenticationDialogPrivate);
+}
+
+static void
+polkit_gnome_authentication_dialog_finalize (GObject *object)
+{
+  PolkitGnomeAuthenticationDialog *dialog;
+
+  dialog = POLKIT_GNOME_AUTHENTICATION_DIALOG (object);
+
+  g_free (dialog->priv->message);
+  g_free (dialog->priv->action_id);
+  g_free (dialog->priv->program);
+  g_free (dialog->priv->vendor);
+  g_free (dialog->priv->vendor_url);
+  g_free (dialog->priv->icon_name);
+  g_strfreev (dialog->priv->users);
+  g_free (dialog->priv->selected_user);
+
+  if (dialog->priv->store != NULL)
+    g_object_unref (dialog->priv->store);
+
+  if (G_OBJECT_CLASS (polkit_gnome_authentication_dialog_parent_class)->finalize != NULL)
+    G_OBJECT_CLASS (polkit_gnome_authentication_dialog_parent_class)->finalize (object);
+}
+
+static void
+polkit_gnome_authentication_dialog_constructed (GObject *object)
+{
+  PolkitGnomeAuthenticationDialog *dialog;
+  GtkWidget *hbox;
+  GtkWidget *main_vbox;
+  GtkWidget *vbox;
+  GtkWidget *table_alignment;
+  GtkWidget *table;
+  GtkWidget *details_expander;
+  GtkWidget *details_vbox;
+  GtkWidget *label;
+  GtkWidget *image;
+  gboolean have_user_combobox;
+  gchar *s;
+
+  dialog = POLKIT_GNOME_AUTHENTICATION_DIALOG (object);
+
+  if (G_OBJECT_CLASS (polkit_gnome_authentication_dialog_parent_class)->constructed != NULL)
+    G_OBJECT_CLASS (polkit_gnome_authentication_dialog_parent_class)->constructed (object);
+
+  have_user_combobox = FALSE;
+
+  dialog->priv->cancel_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+                                                            GTK_STOCK_CANCEL,
+                                                            GTK_RESPONSE_CANCEL);
+  dialog->priv->auth_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+                                                          _("_Authenticate"),
+                                                          GTK_RESPONSE_OK);
+  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+  gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); /* 2 * 5 + 2 = 12 */
+  gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5);
+  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6);
+  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+  gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DIALOG_AUTHENTICATION);
+
+  hbox = gtk_hbox_new (FALSE, 12);
+  gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0);
+
+  image = get_image (dialog);
+  gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+  gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+
+  main_vbox = gtk_vbox_new (FALSE, 10);
+  gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0);
+
+  /* main message */
+  label = gtk_label_new (NULL);
+  s = g_strdup_printf ("<big><b>%s</b></big>", dialog->priv->message);
+  gtk_label_set_markup (GTK_LABEL (label), s);
+  g_free (s);
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+  gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
+
+  /* secondary message */
+  label = gtk_label_new (NULL);
+  if (g_strv_length (dialog->priv->users) > 1)
+    {
+          gtk_label_set_markup (GTK_LABEL (label),
+                                _("An application is attempting to perform an action that requires privileges. "
+                                  "Authentication as one of the users below is required to perform this action."));
+    }
+  else
+    {
+      if (strcmp (g_get_user_name (), dialog->priv->users[0]) == 0)
+        {
+          gtk_label_set_markup (GTK_LABEL (label),
+                                _("An application is attempting to perform an action that requires privileges. "
+                                  "Authentication is required to perform this action."));
+        }
+      else
+        {
+          gtk_label_set_markup (GTK_LABEL (label),
+                                _("An application is attempting to perform an action that requires privileges. "
+                                  "Authentication as the super user is required to perform this action."));
+        }
+    }
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+  gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
+
+  /* user combobox */
+  if (g_strv_length (dialog->priv->users) > 1)
+    {
+      dialog->priv->user_combobox = gtk_combo_box_new ();
+      gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (dialog->priv->user_combobox), FALSE, FALSE, 0);
+
+      create_user_combobox (dialog);
+
+      have_user_combobox = TRUE;
+    }
+  else
+    {
+      dialog->priv->selected_user = g_strdup (dialog->priv->users[0]);
+    }
+
+  /* password entry */
+  vbox = gtk_vbox_new (FALSE, 6);
+  gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
+
+  table_alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+  gtk_box_pack_start (GTK_BOX (vbox), table_alignment, FALSE, FALSE, 0);
+  table = gtk_table_new (1, 2, FALSE);
+  gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+  gtk_container_add (GTK_CONTAINER (table_alignment), table);
+  dialog->priv->password_entry = gtk_entry_new ();
+  gtk_entry_set_visibility (GTK_ENTRY (dialog->priv->password_entry), FALSE);
+  dialog->priv->prompt_label = add_row (table, 0, _("_Password:"), dialog->priv->password_entry);
+
+  g_signal_connect_swapped (dialog->priv->password_entry, "activate",
+                            G_CALLBACK (gtk_window_activate_default),
+                            dialog);
+
+  details_expander = gtk_expander_new_with_mnemonic (_("<small><b>_Details</b></small>"));
+  gtk_expander_set_use_markup (GTK_EXPANDER (details_expander), TRUE);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), details_expander, FALSE, FALSE, 0);
+
+  details_vbox = gtk_vbox_new (FALSE, 10);
+  gtk_container_add (GTK_CONTAINER (details_expander), details_vbox);
+
+  table_alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+  gtk_box_pack_start (GTK_BOX (details_vbox), table_alignment, FALSE, FALSE, 0);
+  table = gtk_table_new (1, 3, FALSE);
+  gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+  gtk_container_add (GTK_CONTAINER (table_alignment), table);
+
+  label = gtk_label_new (NULL);
+  s = g_strdup_printf ("<small>%s</small>", dialog->priv->program);
+  gtk_label_set_markup (GTK_LABEL (label), s);
+  g_free (s);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 1.0);
+  add_row (table, 0, _("<small><b>Application:</b></small>"), label);
+
+  /* --- */
+
+  label = sexy_url_label_new ();
+  s = g_strdup_printf ("<small><a href=\"%s\">%s</a></small>",
+                       dialog->priv->action_id,
+                       dialog->priv->action_id);
+  sexy_url_label_set_markup (SEXY_URL_LABEL (label), s);
+  g_free (s);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 1.0);
+  add_row (table, 1, _("<small><b>Action:</b></small>"), label);
+  g_signal_connect (label, "url-activated", G_CALLBACK (action_id_activated), NULL);
+
+  s = g_strdup_printf (_("Click to edit %s"), dialog->priv->action_id);
+  gtk_widget_set_tooltip_markup (label, s);
+  g_free (s);
+
+  /* --- */
+
+  label = sexy_url_label_new ();
+  s = g_strdup_printf ("<small><a href=\"%s\">%s</a></small>",
+                       dialog->priv->vendor_url,
+                       dialog->priv->vendor);
+  sexy_url_label_set_markup (SEXY_URL_LABEL (label), s);
+  g_free (s);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 1.0);
+  add_row (table, 2, _("<small><b>Vendor:</b></small>"), label);
+  g_signal_connect (label, "url-activated", G_CALLBACK (vendor_url_activated), NULL);
+
+  s = g_strdup_printf (_("Click to open %s"), dialog->priv->vendor_url);
+  gtk_widget_set_tooltip_markup (label, s);
+  g_free (s);
+
+  if (have_user_combobox)
+    {
+      /* ... and make the password entry and "Authenticate" button insensitive */
+      gtk_widget_set_sensitive (dialog->priv->prompt_label, FALSE);
+      gtk_widget_set_sensitive (dialog->priv->password_entry, FALSE);
+      gtk_widget_set_sensitive (dialog->priv->auth_button, FALSE);
+    }
+  else
+    {
+    }
+
+}
+
+static void
+polkit_gnome_authentication_dialog_class_init (PolkitGnomeAuthenticationDialogClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (PolkitGnomeAuthenticationDialogPrivate));
+
+  gobject_class->finalize = polkit_gnome_authentication_dialog_finalize;
+  gobject_class->get_property = polkit_gnome_authentication_dialog_get_property;
+  gobject_class->set_property = polkit_gnome_authentication_dialog_set_property;
+  gobject_class->constructed  = polkit_gnome_authentication_dialog_constructed;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_PROGRAM,
+                                   g_param_spec_string ("program",
+                                                        NULL,
+                                                        NULL,
+                                                        NULL,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_ACTION_ID,
+                                   g_param_spec_string ("action-id",
+                                                        NULL,
+                                                        NULL,
+                                                        NULL,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_VENDOR,
+                                   g_param_spec_string ("vendor",
+                                                        NULL,
+                                                        NULL,
+                                                        NULL,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_VENDOR_URL,
+                                   g_param_spec_string ("vendor-url",
+                                                        NULL,
+                                                        NULL,
+                                                        NULL,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_ICON_NAME,
+                                   g_param_spec_string ("icon-name",
+                                                        NULL,
+                                                        NULL,
+                                                        NULL,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_BLURB));
+
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MESSAGE,
+                                   g_param_spec_string ("message",
+                                                        NULL,
+                                                        NULL,
+                                                        NULL,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_USERS,
+                                   g_param_spec_boxed ("users",
+                                                       NULL,
+                                                       NULL,
+                                                       G_TYPE_STRV,
+                                                       G_PARAM_READWRITE |
+                                                       G_PARAM_CONSTRUCT_ONLY |
+                                                       G_PARAM_STATIC_NAME |
+                                                       G_PARAM_STATIC_NICK |
+                                                       G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_SELECTED_USER,
+                                   g_param_spec_string ("selected-user",
+                                                        NULL,
+                                                        NULL,
+                                                        NULL,
+                                                        G_PARAM_READABLE |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_BLURB));
 }
 
 /**
- * polkit_gnome_auth_dialog_new:
- * 
+ * polkit_gnome_authentication_dialog_new:
+ *
  * Yada yada yada...
- * 
+ *
  * Returns: A new password dialog.
  **/
 GtkWidget *
-polkit_gnome_auth_dialog_new (const char *path_to_program,
-			      const char *action_id,
-			      const char *vendor,
-			      const char *vendor_url,
-			      const char *icon_name,
-			      const char *message_markup)
-{
-	PolkitGnomeAuthDialog *auth_dialog;
-	GtkWindow *window;
-
-	auth_dialog = g_object_new (POLKIT_GNOME_TYPE_AUTH_DIALOG, 
-				    "program", path_to_program,
-				    "action-id", action_id,
-				    "vendor", vendor,
-				    "vendor-url", vendor_url,
-				    "icon-name", icon_name,
-				    "message", message_markup,
-				    NULL);
-
-	window = GTK_WINDOW (auth_dialog);
-
- 	gtk_window_set_position (window, GTK_WIN_POS_CENTER);
-	gtk_window_set_modal (window, TRUE);
-	gtk_window_set_resizable (window, FALSE);
-	gtk_window_set_keep_above (window, TRUE);
-	gtk_window_set_title (window, _("Authenticate"));
-	g_signal_connect (auth_dialog, "close",
-			  G_CALLBACK (gtk_widget_hide), NULL);
-	
-	return GTK_WIDGET (auth_dialog);
+polkit_gnome_authentication_dialog_new (const gchar *path_to_program,
+                                        const gchar *action_id,
+                                        const gchar *vendor,
+                                        const gchar *vendor_url,
+                                        const gchar *icon_name,
+                                        const gchar *message_markup,
+                                        gchar      **users)
+{
+  PolkitGnomeAuthenticationDialog *dialog;
+  GtkWindow *window;
+
+  dialog = g_object_new (POLKIT_GNOME_TYPE_AUTHENTICATION_DIALOG,
+                              "program", path_to_program,
+                              "action-id", action_id,
+                              "vendor", vendor,
+                              "vendor-url", vendor_url,
+                              "icon-name", icon_name,
+                              "message", message_markup,
+                              "users", users,
+                              NULL);
+
+  window = GTK_WINDOW (dialog);
+
+  gtk_window_set_position (window, GTK_WIN_POS_CENTER);
+  gtk_window_set_modal (window, TRUE);
+  gtk_window_set_resizable (window, FALSE);
+  gtk_window_set_keep_above (window, TRUE);
+  gtk_window_set_title (window, _("Authenticate"));
+  g_signal_connect (dialog, "close", G_CALLBACK (gtk_widget_hide), NULL);
+
+  return GTK_WIDGET (dialog);
 }
 
-const char *
-polkit_gnome_auth_dialog_get_password (PolkitGnomeAuthDialog *auth_dialog)
+/**
+ * polkit_gnome_authentication_dialog_indicate_error:
+ * @dialog: the auth dialog
+ *
+ * Call this function to indicate an authentication error; typically shakes the window
+ **/
+void
+polkit_gnome_authentication_dialog_indicate_error (PolkitGnomeAuthenticationDialog *dialog)
 {
-	return gtk_entry_get_text (GTK_ENTRY (auth_dialog->priv->password_entry));
+  int x, y;
+  int n;
+  int diff;
+
+  /* TODO: detect compositing manager and do fancy stuff here */
+
+  gtk_window_get_position (GTK_WINDOW (dialog), &x, &y);
+
+  for (n = 0; n < 10; n++)
+    {
+      if (n % 2 == 0)
+        diff = -15;
+      else
+        diff = 15;
+
+      gtk_window_move (GTK_WINDOW (dialog), x + diff, y);
+
+      while (gtk_events_pending ())
+        {
+          gtk_main_iteration ();
+        }
+
+      g_usleep (10000);
+    }
+
+  gtk_window_move (GTK_WINDOW (dialog), x, y);
 }
 
+/**
+ * polkit_gnome_authentication_dialog_run_until_user_is_selected:
+ * @dialog: A #PolkitGnomeAuthenticationDialog.
+ *
+ * Runs @dialog in a recursive main loop until a user have been selected.
+ *
+ * If there is only one element in the the users array (which is set upon construction) or
+ * an user has already been selected, this function returns immediately with the return
+ * value %TRUE.
+ *
+ * Returns: %TRUE if a user is selected (use polkit_gnome_dialog_get_selected_user() to obtain the user) or
+ *          %FALSE if the dialog was cancelled.
+ **/
 gboolean
-polkit_gnome_auth_dialog_get_remember_session (PolkitGnomeAuthDialog *auth_dialog)
+polkit_gnome_authentication_dialog_run_until_user_is_selected (PolkitGnomeAuthenticationDialog *dialog)
 {
-	gboolean ret;
-	gboolean remember;
+  gboolean ret;
+  gint response;
+
+  ret = FALSE;
+
+  if (dialog->priv->selected_user != NULL)
+    {
+      ret = TRUE;
+      goto out;
+    }
 
-	remember = gtk_toggle_button_get_active (
-		GTK_TOGGLE_BUTTON (auth_dialog->priv->keep_privilege_check_button));
+  dialog->priv->is_running = TRUE;
 
-	if (auth_dialog->priv->can_do_always) {
-		gboolean session_only;
-		session_only = gtk_toggle_button_get_active (
-			GTK_TOGGLE_BUTTON (auth_dialog->priv->keep_privilege_session_only_check_button));
-
-		ret = remember && session_only;
-	} else {
-		ret = remember;
-	}
-	return ret;
+  gtk_widget_show_all (GTK_WIDGET (dialog));
+  response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+  dialog->priv->is_running = FALSE;
+
+  if (response == RESPONSE_USER_SELECTED)
+    ret = TRUE;
+
+ out:
+  return ret;
 }
 
-gboolean
-polkit_gnome_auth_dialog_get_remember_always (PolkitGnomeAuthDialog *auth_dialog)
-{
-	gboolean ret;
-	gboolean remember;
+/**
+ * polkit_gnome_authentication_dialog_run_until_response_for_prompt:
+ * @dialog: A #PolkitGnomeAuthenticationDialog.
+ * @prompt: The prompt to present the user with.
+ * @echo_chars: Whether characters should be echoed in the password entry box.
+ * @was_cancelled: Set to %TRUE if the dialog was cancelled.
+ * @new_user_selected: Set to %TRUE if another user was selected.
+ *
+ * Runs @dialog in a recursive main loop until a response to @prompt have been obtained from the user.
+ *
+ * Returns: The response (free with g_free()) or %NULL if one of @was_cancelled or @new_user_selected
+ *          has been set to %TRUE.
+ **/
+gchar *
+polkit_gnome_authentication_dialog_run_until_response_for_prompt (PolkitGnomeAuthenticationDialog *dialog,
+                                                                  const gchar           *prompt,
+                                                                  gboolean               echo_chars,
+                                                                  gboolean              *was_cancelled,
+                                                                  gboolean              *new_user_selected)
+{
+  gint response;
+  gchar *ret;
+
+  gtk_label_set_text_with_mnemonic (GTK_LABEL (dialog->priv->prompt_label), prompt);
+  gtk_entry_set_visibility (GTK_ENTRY (dialog->priv->password_entry), echo_chars);
+  gtk_entry_set_text (GTK_ENTRY (dialog->priv->password_entry), "");
+  gtk_widget_grab_focus (dialog->priv->password_entry);
+
+  ret = NULL;
+
+  if (was_cancelled != NULL)
+    *was_cancelled = FALSE;
+
+  if (new_user_selected != NULL)
+    *new_user_selected = FALSE;
+
+  dialog->priv->is_running = TRUE;
+
+  gtk_widget_show_all (GTK_WIDGET (dialog));
+  response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+  dialog->priv->is_running = FALSE;
+
+  if (response == GTK_RESPONSE_OK)
+    {
+      ret = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->priv->password_entry)));
+    }
+  else if (response == RESPONSE_USER_SELECTED)
+    {
+      if (new_user_selected != NULL)
+        *new_user_selected = TRUE;
+    }
+  else
+    {
+      if (was_cancelled != NULL)
+        *was_cancelled = TRUE;
+    }
 
-	remember = gtk_toggle_button_get_active (
-		GTK_TOGGLE_BUTTON (auth_dialog->priv->keep_privilege_check_button));
+  return ret;
+}
 
-	if (auth_dialog->priv->can_do_always) {
-		gboolean session_only;
-		session_only = gtk_toggle_button_get_active (
-			GTK_TOGGLE_BUTTON (auth_dialog->priv->keep_privilege_session_only_check_button));
-
-		ret = remember && (!session_only);
-	} else {
-		ret = FALSE;
-	}
-	return ret;
+/**
+ * polkit_gnome_authentication_dialog_get_selected_user:
+ * @dialog: A #PolkitGnomeAuthenticationDialog.
+ *
+ * Gets the currently selected user.
+ *
+ * Returns: The currently selected user (free with g_free()) or %NULL if no user is currently selected.
+ **/
+gchar *
+polkit_gnome_authentication_dialog_get_selected_user (PolkitGnomeAuthenticationDialog *dialog)
+{
+  return g_strdup (dialog->priv->selected_user);
 }
 
 /**
- * polkit_gnome_auth_dialog_indicate_auth_error:
- * @auth_dialog: the auth dialog
- * 
- * Call this function to indicate an authentication error; typically shakes the window
+ * polkit_gnome_authentication_dialog_cancel:
+ * @dialog: A #PolkitGnomeAuthenticationDialog.
+ *
+ * Cancels the dialog if it is currenlty running.
+ *
+ * Returns: %TRUE if the dialog was running.
  **/
-void
-polkit_gnome_auth_dialog_indicate_auth_error (PolkitGnomeAuthDialog *auth_dialog)
+gboolean
+polkit_gnome_authentication_dialog_cancel (PolkitGnomeAuthenticationDialog *dialog)
 {
-	int x, y;
-	int n;
-	int diff;
-
-	/* TODO: detect compositing manager and do fancy stuff here */
-
-	gtk_window_get_position (GTK_WINDOW (auth_dialog), &x, &y);
-	for (n = 0; n < 10; n++) {
-		if (n % 2 == 0)
-			diff = -15;
-		else
-			diff = 15;
-
-		gtk_window_move (GTK_WINDOW (auth_dialog), x + diff, y);
-
-                while (gtk_events_pending ()) {
-                        gtk_main_iteration ();
-                }
-
-                g_usleep (10000);
-	}
-	gtk_window_move (GTK_WINDOW (auth_dialog), x, y);
+  if (!dialog->priv->is_running)
+    return FALSE;
+
+  gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
+
+  return TRUE;
 }

Copied: trunk/src/polkitgnomeauthenticationdialog.h (from r91, /trunk/src/polkit-gnome-auth-dialog.h)
==============================================================================
--- /trunk/src/polkit-gnome-auth-dialog.h	(original)
+++ trunk/src/polkitgnomeauthenticationdialog.h	Sat Jan 31 01:45:48 2009
@@ -1,86 +1,70 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
  *
- * Copyright (C) 2007 David Zeuthen <david fubar dk>
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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 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,
+ * This library 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser 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.
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
  *
+ * Author: David Zeuthen <davidz redhat com>
  */
 
-#ifndef POLKIT_GNOME_AUTH_DIALOG_H
-#define POLKIT_GNOME_AUTH_DIALOG_H
+#ifndef __POLKIT_GNOME_AUTHENTICATION_DIALOG_H
+#define __POLKIT_GNOME_AUTHENTICATION_DIALOG_H
 
-#include <gtk/gtkdialog.h>
+#include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 
-#define KEY_AUTH_DIALOG_RETAIN_AUTHORIZATION "/desktop/gnome/policykit/auth_dialog_retain_authorization"
-#define KEY_AUTH_DIALOG_RETAIN_AUTHORIZATION_BLACKLIST "/desktop/gnome/policykit/auth_dialog_retain_authorization_blacklist"
-
-#define POLKIT_GNOME_TYPE_AUTH_DIALOG            (polkit_gnome_auth_dialog_get_type ())
-#define POLKIT_GNOME_AUTH_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), POLKIT_GNOME_TYPE_AUTH_DIALOG, PolkitGnomeAuthDialog))
-#define POLKIT_GNOME_AUTH_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), POLKIT_GNOME_TYPE_AUTH_DIALOG, PolkitGnomeAuthDialogClass))
-#define POLKIT_GNOME_IS_AUTH_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POLKIT_GNOME_TYPE_AUTH_DIALOG))
-#define POLKIT_GNOME_IS_AUTH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), POLKIT_GNOME_TYPE_AUTH_DIALOG))
-
-typedef struct _PolkitGnomeAuthDialog        PolkitGnomeAuthDialog;
-typedef struct _PolkitGnomeAuthDialogClass   PolkitGnomeAuthDialogClass;
-typedef struct _PolkitGnomeAuthDialogPrivate PolkitGnomeAuthDialogPrivate;
+#define POLKIT_GNOME_TYPE_AUTHENTICATION_DIALOG            (polkit_gnome_authentication_dialog_get_type ())
+#define POLKIT_GNOME_AUTHENTICATION_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), POLKIT_GNOME_TYPE_AUTHENTICATION_DIALOG, PolkitGnomeAuthenticationDialog))
+#define POLKIT_GNOME_AUTHENTICATION_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), POLKIT_GNOME_TYPE_AUTHENTICATION_DIALOG, PolkitGnomeAuthenticationDialogClass))
+#define POLKIT_GNOME_IS_AUTHENTICATION_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POLKIT_GNOME_TYPE_AUTHENTICATION_DIALOG))
+#define POLKIT_GNOME_IS_AUTHENTICATION_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), POLKIT_GNOME_TYPE_AUTHENTICATION_DIALOG))
+
+typedef struct _PolkitGnomeAuthenticationDialog        PolkitGnomeAuthenticationDialog;
+typedef struct _PolkitGnomeAuthenticationDialogClass   PolkitGnomeAuthenticationDialogClass;
+typedef struct _PolkitGnomeAuthenticationDialogPrivate PolkitGnomeAuthenticationDialogPrivate;
 
-struct _PolkitGnomeAuthDialog
+struct _PolkitGnomeAuthenticationDialog
 {
-	GtkDialog gtk_dialog;
-	PolkitGnomeAuthDialogPrivate *priv;
+  GtkDialog parent_instance;
+  PolkitGnomeAuthenticationDialogPrivate *priv;
 };
 
-struct _PolkitGnomeAuthDialogClass
+struct _PolkitGnomeAuthenticationDialogClass
 {
-	GtkDialogClass parent_class;
-
-	/* Signals: */
-
-	void (*user_selected) (PolkitGnomeAuthDialog *auth_dialog, const char *user_name);
+  GtkDialogClass parent_class;
 };
 
-GType    polkit_gnome_auth_dialog_get_type      (void);
-GtkWidget *polkit_gnome_auth_dialog_new (const char *path_to_program,
-					 const char *action_id,
-					 const char *vendor,
-					 const char *vendor_url,
-					 const char *icon_name,
-					 const char *message_markup);
-
-void        polkit_gnome_auth_dialog_set_prompt (PolkitGnomeAuthDialog *auth_dialog,
-						 const char *prompt,
-						 gboolean show_chars);
-
-const char *polkit_gnome_auth_dialog_get_password (PolkitGnomeAuthDialog *auth_dialog);
-
-void        polkit_gnome_auth_dialog_set_options (PolkitGnomeAuthDialog *auth_dialog, 
-						  gboolean session, 
-						  gboolean always,
-						  gboolean requires_admin,
-						  char **admin_users);
-
-gboolean    polkit_gnome_auth_dialog_get_remember_session (PolkitGnomeAuthDialog *auth_dialog);
-gboolean    polkit_gnome_auth_dialog_get_remember_always  (PolkitGnomeAuthDialog *auth_dialog);
-gboolean    polkit_gnome_auth_dialog_get_apply_all        (PolkitGnomeAuthDialog *auth_dialog);
-
-void        polkit_gnome_auth_dialog_select_admin_user (PolkitGnomeAuthDialog *auth_dialog, const char *admin_user);
-
-void        polkit_gnome_auth_dialog_indicate_auth_error (PolkitGnomeAuthDialog *auth_dialog);
+GType      polkit_gnome_authentication_dialog_get_type                      (void);
+GtkWidget *polkit_gnome_authentication_dialog_new                           (const gchar *path_to_program,
+                                                                             const gchar *action_id,
+                                                                             const gchar *vendor,
+                                                                             const gchar *vendor_url,
+                                                                             const gchar *icon_name,
+                                                                             const gchar *message_markup,
+                                                                             gchar      **users);
+gchar     *polkit_gnome_authentication_dialog_get_selected_user             (PolkitGnomeAuthenticationDialog *dialog);
+gboolean   polkit_gnome_authentication_dialog_run_until_user_is_selected    (PolkitGnomeAuthenticationDialog *dialog);
+gchar     *polkit_gnome_authentication_dialog_run_until_response_for_prompt (PolkitGnomeAuthenticationDialog *dialog,
+                                                                             const gchar                     *prompt,
+                                                                             gboolean                         echo_chars,
+                                                                             gboolean                        *was_cancelled,
+                                                                             gboolean                        *new_user_selected);
+gboolean   polkit_gnome_authentication_dialog_cancel                        (PolkitGnomeAuthenticationDialog *dialog);
+void       polkit_gnome_authentication_dialog_indicate_error                (PolkitGnomeAuthenticationDialog *dialog);
 
 G_END_DECLS
 
-#endif /* POLKIT_GNOME_AUTH_DIALOG_H */
+#endif /* __POLKIT_GNOME_AUTHENTICATION_DIALOG_H */

Added: trunk/src/polkitgnomeauthenticator.c
==============================================================================
--- (empty file)
+++ trunk/src/polkitgnomeauthenticator.c	Sat Jan 31 01:45:48 2009
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+
+#include "config.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <glib/gi18n.h>
+
+#include <polkit/polkit.h>
+#include <polkitagent/polkitagent.h>
+
+#include "polkitgnomeauthenticator.h"
+#include "polkitgnomeauthenticationdialog.h"
+
+struct _PolkitGnomeAuthenticator
+{
+  GObject parent_instance;
+
+  PolkitAuthority *authority;
+  gchar *action_id;
+  gchar *cookie;
+  GList *identities;
+
+  PolkitActionDescription *action_desc;
+  gchar *icon_name;
+  gchar **users;
+
+  gboolean gained_authorization;
+  gboolean was_cancelled;
+  gboolean new_user_selected;
+  gchar *selected_user;
+
+  PolkitAgentSession *session;
+  GtkWidget *dialog;
+  GMainLoop *loop;
+};
+
+struct _PolkitGnomeAuthenticatorClass
+{
+  GObjectClass parent_class;
+
+};
+
+enum
+{
+  COMPLETED_SIGNAL,
+  LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+G_DEFINE_TYPE (PolkitGnomeAuthenticator, polkit_gnome_authenticator, G_TYPE_OBJECT);
+
+static void
+polkit_gnome_authenticator_init (PolkitGnomeAuthenticator *authenticator)
+{
+}
+
+static void
+polkit_gnome_authenticator_finalize (GObject *object)
+{
+  PolkitGnomeAuthenticator *authenticator;
+
+  authenticator = POLKIT_GNOME_AUTHENTICATOR (object);
+
+  if (authenticator->authority != NULL)
+    g_object_unref (authenticator->authority);
+  g_free (authenticator->action_id);
+  g_free (authenticator->cookie);
+  g_list_foreach (authenticator->identities, (GFunc) g_object_unref, NULL);
+  g_list_free (authenticator->identities);
+
+  if (authenticator->action_desc != NULL)
+    g_object_unref (authenticator->action_desc);
+  g_free (authenticator->icon_name);
+  g_strfreev (authenticator->users);
+
+  g_free (authenticator->selected_user);
+  if (authenticator->session != NULL)
+    g_object_unref (authenticator->session);
+  if (authenticator->dialog != NULL)
+    gtk_widget_destroy (authenticator->dialog);
+  if (authenticator->loop != NULL)
+    g_main_loop_unref (authenticator->loop);
+
+  if (G_OBJECT_CLASS (polkit_gnome_authenticator_parent_class)->finalize != NULL)
+    G_OBJECT_CLASS (polkit_gnome_authenticator_parent_class)->finalize (object);
+}
+
+static void
+polkit_gnome_authenticator_class_init (PolkitGnomeAuthenticatorClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->finalize = polkit_gnome_authenticator_finalize;
+
+  /**
+   * PolkitGnomeAuthenticator::completed:
+   * @authenticator: A #PolkitGnomeAuthenticator.
+   * @gained_authorization: Whether the authorization was gained.
+   *
+   * Emitted when the authentication is completed. The user is supposed to dispose of @authenticator
+   * upon receiving this signal.
+   **/
+  signals[COMPLETED_SIGNAL] = g_signal_new ("completed",
+                                            POLKIT_GNOME_TYPE_AUTHENTICATOR,
+                                            G_SIGNAL_RUN_LAST,
+                                            0,                      /* class offset     */
+                                            NULL,                   /* accumulator      */
+                                            NULL,                   /* accumulator data */
+                                            g_cclosure_marshal_VOID__BOOLEAN,
+                                            G_TYPE_NONE,
+                                            1,
+                                            G_TYPE_BOOLEAN);
+}
+
+static PolkitActionDescription *
+get_desc_for_action (PolkitAuthority *authority,
+                     const gchar     *action_id)
+{
+  GList *action_descs;
+  GList *l;
+  PolkitActionDescription *result;
+
+  result = NULL;
+
+  action_descs = polkit_authority_enumerate_actions_sync (authority,
+                                                          NULL,
+                                                          NULL,
+                                                          NULL);
+  for (l = action_descs; l != NULL; l = l->next)
+    {
+      PolkitActionDescription *action_desc = POLKIT_ACTION_DESCRIPTION (l->data);
+
+      if (strcmp (polkit_action_description_get_action_id (action_desc), action_id) == 0)
+        {
+          result = g_object_ref (action_desc);
+          goto out;
+        }
+    }
+
+ out:
+
+  g_list_foreach (action_descs, (GFunc) g_object_unref, NULL);
+  g_list_free (action_descs);
+
+  return result;
+}
+
+PolkitGnomeAuthenticator *
+polkit_gnome_authenticator_new (const gchar *action_id,
+                                const gchar *cookie,
+                                GList       *identities)
+{
+  PolkitGnomeAuthenticator *authenticator;
+  GIcon *icon;
+  GList *l;
+  guint n;
+
+  authenticator = POLKIT_GNOME_AUTHENTICATOR (g_object_new (POLKIT_GNOME_TYPE_AUTHENTICATOR, NULL));
+
+  authenticator->authority = polkit_authority_get ();
+  authenticator->action_id = g_strdup (action_id);
+  authenticator->cookie = g_strdup (cookie);
+  authenticator->identities = g_list_copy (identities);
+  g_list_foreach (authenticator->identities, (GFunc) g_object_ref, NULL);
+
+  authenticator->action_desc = get_desc_for_action (authenticator->authority,
+                                                    authenticator->action_id);
+  if (authenticator->action_desc == NULL)
+    goto error;
+
+  icon = polkit_action_description_get_icon (authenticator->action_desc);
+  if (icon != NULL)
+    authenticator->icon_name = g_icon_to_string (icon);
+
+  authenticator->users = g_new0 (gchar *, g_list_length (authenticator->identities) + 1);
+  for (l = authenticator->identities, n = 0; l != NULL; l = l->next, n++)
+    {
+      PolkitUnixUser *user = POLKIT_UNIX_USER (l->data);
+      uid_t uid;
+      struct passwd *passwd;
+
+      uid = polkit_unix_user_get_uid (user);
+      passwd = getpwuid (uid);
+      authenticator->users[n] = g_strdup (passwd->pw_name);
+    }
+
+  authenticator->dialog = polkit_gnome_authentication_dialog_new
+                            ("/todo/path/to/program/requesting/auth",
+                             authenticator->action_id,
+                             polkit_action_description_get_vendor_name (authenticator->action_desc),
+                             polkit_action_description_get_vendor_url (authenticator->action_desc),
+                             authenticator->icon_name,
+                             polkit_action_description_get_message (authenticator->action_desc),
+                             authenticator->users);
+
+  return authenticator;
+
+ error:
+  g_object_unref (authenticator);
+  return NULL;
+}
+
+static void
+session_request (PolkitAgentSession *session,
+                 const char         *request,
+                 gboolean            echo_on,
+                 gpointer            user_data)
+{
+  PolkitGnomeAuthenticator *authenticator = POLKIT_GNOME_AUTHENTICATOR (user_data);
+  gchar *password;
+  gchar *modified_request;
+
+  password = NULL;
+
+  g_debug ("in conversation_pam_prompt, request='%s', echo_on=%d", request, echo_on);
+
+  /* Fix up, and localize, password prompt if it's password auth */
+  if (g_ascii_strncasecmp (request, "password:", 9) == 0)
+    {
+      if (strcmp (g_get_user_name (), authenticator->selected_user) != 0)
+        {
+          modified_request = g_strdup_printf (_("_Password for %s:"), authenticator->selected_user);
+        }
+      else
+        {
+          modified_request = g_strdup (_("_Password:"));
+        }
+    }
+  else
+    {
+      modified_request = g_strdup (request);
+    }
+
+  password = polkit_gnome_authentication_dialog_run_until_response_for_prompt (POLKIT_GNOME_AUTHENTICATION_DIALOG (authenticator->dialog),
+                                                                               modified_request,
+                                                                               echo_on,
+                                                                               &authenticator->was_cancelled,
+                                                                               &authenticator->new_user_selected);
+
+  /* cancel auth unless user provided a password */
+  if (password == NULL)
+    {
+      polkit_gnome_authenticator_cancel (authenticator);
+      goto out;
+    }
+  else
+    {
+      polkit_agent_session_response (authenticator->session, password);
+      g_free (password);
+    }
+
+out:
+  g_free (modified_request);
+}
+
+static void
+session_request_echo_off (PolkitAgentSession *session,
+                          const gchar        *request,
+                          gpointer            user_data)
+{
+  session_request (session, request, FALSE, user_data);
+}
+
+static void
+session_request_echo_on (PolkitAgentSession *session,
+                         const gchar        *request,
+                         gpointer            user_data)
+{
+  session_request (session, request, TRUE, user_data);
+}
+
+static void
+session_show_error (PolkitAgentSession *session,
+                    const gchar        *msg,
+                    gpointer            user_data)
+{
+  g_debug ("error_msg='%s'", msg);
+}
+
+static void
+session_show_info (PolkitAgentSession *session,
+                   const gchar        *msg,
+                   gpointer            user_data)
+{
+  g_debug ("text_info='%s'", msg);
+}
+
+
+static void
+session_completed (PolkitAgentSession *session,
+                   gboolean            gained_authorization,
+                   gpointer            user_data)
+{
+  PolkitGnomeAuthenticator *authenticator = POLKIT_GNOME_AUTHENTICATOR (user_data);
+
+  authenticator->gained_authorization = gained_authorization;
+
+  g_debug ("in conversation_done gained=%d", gained_authorization);
+
+  g_main_loop_quit (authenticator->loop);
+}
+
+
+static gboolean
+do_initiate (gpointer user_data)
+{
+  PolkitGnomeAuthenticator *authenticator = POLKIT_GNOME_AUTHENTICATOR (user_data);
+  PolkitIdentity *identity;
+  gint num_tries;
+
+  if (!polkit_gnome_authentication_dialog_run_until_user_is_selected (POLKIT_GNOME_AUTHENTICATION_DIALOG (authenticator->dialog)))
+    {
+      /* user cancelled the dialog */
+      g_debug ("User cancelled before selecting a user");
+      authenticator->was_cancelled = TRUE;
+      goto out;
+    }
+
+  authenticator->loop = g_main_loop_new (NULL, TRUE);
+
+  num_tries = 0;
+
+ try_again:
+
+  g_free (authenticator->selected_user);
+  authenticator->selected_user = polkit_gnome_authentication_dialog_get_selected_user (POLKIT_GNOME_AUTHENTICATION_DIALOG (authenticator->dialog));
+
+  g_debug ("Authenticating user %s", authenticator->selected_user);
+  identity = polkit_unix_user_new_for_name (authenticator->selected_user, NULL);
+
+  authenticator->session = polkit_agent_session_new (identity, authenticator->cookie);
+
+  g_object_unref (identity);
+
+  g_signal_connect (authenticator->session,
+                    "request-echo-on",
+                    G_CALLBACK (session_request_echo_on),
+                    authenticator);
+
+  g_signal_connect (authenticator->session,
+                    "request-echo-off",
+                    G_CALLBACK (session_request_echo_off),
+                    authenticator);
+
+  g_signal_connect (authenticator->session,
+                    "show-info",
+                    G_CALLBACK (session_show_info),
+                    authenticator);
+
+  g_signal_connect (authenticator->session,
+                    "show-error",
+                    G_CALLBACK (session_show_error),
+                    authenticator);
+
+  g_signal_connect (authenticator->session,
+                    "completed",
+                    G_CALLBACK (session_completed),
+                    authenticator);
+
+  polkit_agent_session_initiate (authenticator->session);
+
+  g_main_loop_run (authenticator->loop);
+
+  g_debug ("gained_authorization=%d was_cancelled=%d new_user_selected=%d.",
+           authenticator->gained_authorization,
+           authenticator->was_cancelled,
+           authenticator->new_user_selected);
+
+  if (authenticator->new_user_selected)
+    {
+      g_debug ("New user selected");
+      authenticator->new_user_selected = FALSE;
+      g_object_unref (authenticator->session);
+      authenticator->session = NULL;
+      goto try_again;
+    }
+
+  num_tries++;
+
+  if (!authenticator->gained_authorization && !authenticator->was_cancelled)
+    {
+      if (authenticator->dialog != NULL)
+        {
+          /* shake the dialog to indicate error */
+          polkit_gnome_authentication_dialog_indicate_error (POLKIT_GNOME_AUTHENTICATION_DIALOG (authenticator->dialog));
+
+          if (num_tries < 3)
+            {
+              g_object_unref (authenticator->session);
+              authenticator->session = NULL;
+              goto try_again;
+            }
+        }
+    }
+
+ out:
+  g_signal_emit_by_name (authenticator, "completed", authenticator->gained_authorization);
+
+  g_object_unref (authenticator);
+
+  return FALSE;
+}
+
+void
+polkit_gnome_authenticator_initiate (PolkitGnomeAuthenticator *authenticator)
+{
+  /* run from idle since we're going to block the main loop in the dialog (which has a recursive mainloop) */
+  g_idle_add (do_initiate, g_object_ref (authenticator));
+}
+
+void
+polkit_gnome_authenticator_cancel (PolkitGnomeAuthenticator *authenticator)
+{
+  if (authenticator->dialog != NULL)
+    polkit_gnome_authentication_dialog_cancel (POLKIT_GNOME_AUTHENTICATION_DIALOG (authenticator->dialog));
+
+  authenticator->was_cancelled = TRUE;
+
+  if (authenticator->session != NULL)
+    polkit_agent_session_cancel (authenticator->session);
+}
+
+const gchar *
+polkit_gnome_authenticator_get_cookie (PolkitGnomeAuthenticator *authenticator)
+{
+  return authenticator->cookie;
+}
+
+

Added: trunk/src/polkitgnomeauthenticator.h
==============================================================================
--- (empty file)
+++ trunk/src/polkitgnomeauthenticator.h	Sat Jan 31 01:45:48 2009
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#ifndef __POLKIT_GNOME_AUTHENTICATOR_H
+#define __POLKIT_GNOME_AUTHENTICATOR_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define POLKIT_GNOME_TYPE_AUTHENTICATOR          (polkit_gnome_authenticator_get_type())
+#define POLKIT_GNOME_AUTHENTICATOR(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_GNOME_TYPE_AUTHENTICATOR, PolkitGnomeAuthenticator))
+#define POLKIT_GNOME_AUTHENTICATOR_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_GNOME_TYPE_AUTHENTICATOR, PolkitGnomeAuthenticatorClass))
+#define POLKIT_GNOME_AUTHENTICATOR_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_GNOME_TYPE_AUTHENTICATOR, PolkitGnomeAuthenticatorClass))
+#define POLKIT_GNOME_IS_AUTHENTICATOR(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_GNOME_TYPE_AUTHENTICATOR))
+#define POLKIT_GNOME_IS_AUTHENTICATOR_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_GNOME_TYPE_AUTHENTICATOR))
+
+typedef struct _PolkitGnomeAuthenticator PolkitGnomeAuthenticator;
+typedef struct _PolkitGnomeAuthenticatorClass PolkitGnomeAuthenticatorClass;
+
+GType                      polkit_gnome_authenticator_get_type   (void) G_GNUC_CONST;
+PolkitGnomeAuthenticator  *polkit_gnome_authenticator_new        (const gchar *action_id,
+                                                                  const gchar *cookie,
+                                                                  GList       *identities);
+void                       polkit_gnome_authenticator_initiate   (PolkitGnomeAuthenticator *authenticator);
+void                       polkit_gnome_authenticator_cancel     (PolkitGnomeAuthenticator *authenticator);
+const gchar               *polkit_gnome_authenticator_get_cookie (PolkitGnomeAuthenticator *authenticator);
+
+G_END_DECLS
+
+#endif /* __POLKIT_GNOME_AUTHENTICATOR_H */

Added: trunk/src/polkitgnomelistener.c
==============================================================================
--- (empty file)
+++ trunk/src/polkitgnomelistener.c	Sat Jan 31 01:45:48 2009
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+
+#include "config.h"
+
+#include <string.h>
+
+#include "polkitgnomelistener.h"
+#include "polkitgnomeauthenticator.h"
+
+struct _PolkitGnomeListener
+{
+  PolkitAgentListener parent_instance;
+
+  /* we only support a single active authenticator right now */
+  PolkitGnomeAuthenticator *the_authenticator;
+};
+
+struct _PolkitGnomeListenerClass
+{
+  PolkitAgentListenerClass parent_class;
+};
+
+static void polkit_gnome_listener_initiate_authentication (PolkitAgentListener  *listener,
+                                                           const gchar          *action_id,
+                                                           const gchar          *cookie,
+                                                           GList                *identities,
+                                                           GCancellable         *cancellable,
+                                                           GAsyncReadyCallback   callback,
+                                                           gpointer              user_data);
+
+static gboolean polkit_gnome_listener_initiate_authentication_finish (PolkitAgentListener  *listener,
+                                                                      GAsyncResult         *res,
+                                                                      GError              **error);
+
+G_DEFINE_TYPE (PolkitGnomeListener, polkit_gnome_listener, POLKIT_AGENT_TYPE_LISTENER);
+
+static void
+polkit_gnome_listener_init (PolkitGnomeListener *listener)
+{
+}
+
+static void
+polkit_gnome_listener_finalize (GObject *object)
+{
+  PolkitGnomeListener *listener;
+
+  listener = POLKIT_GNOME_LISTENER (object);
+
+  if (G_OBJECT_CLASS (polkit_gnome_listener_parent_class)->finalize != NULL)
+    G_OBJECT_CLASS (polkit_gnome_listener_parent_class)->finalize (object);
+}
+
+static void
+polkit_gnome_listener_class_init (PolkitGnomeListenerClass *klass)
+{
+  GObjectClass *gobject_class;
+  PolkitAgentListenerClass *listener_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  listener_class = POLKIT_AGENT_LISTENER_CLASS (klass);
+
+  gobject_class->finalize = polkit_gnome_listener_finalize;
+
+  listener_class->initiate_authentication          = polkit_gnome_listener_initiate_authentication;
+  listener_class->initiate_authentication_finish   = polkit_gnome_listener_initiate_authentication_finish;
+}
+
+PolkitAgentListener *
+polkit_gnome_listener_new (void)
+{
+  return POLKIT_AGENT_LISTENER (g_object_new (POLKIT_GNOME_TYPE_LISTENER, NULL));
+}
+
+typedef struct
+{
+  PolkitGnomeListener *listener;
+  GSimpleAsyncResult *simple;
+  GCancellable *cancellable;
+
+  gulong cancel_id;
+} AuthData;
+
+static AuthData *
+auth_data_new (PolkitGnomeListener *listener,
+               GSimpleAsyncResult *simple,
+               GCancellable *cancellable)
+{
+  AuthData *data;
+
+  data = g_new0 (AuthData, 1);
+  data->listener = g_object_ref (listener);
+  data->simple = g_object_ref (simple);
+  data->cancellable = g_object_ref (cancellable);
+  return data;
+}
+
+static void
+auth_data_free (AuthData *data)
+{
+  g_object_unref (data->listener);
+  g_object_unref (data->simple);
+  if (data->cancellable != NULL && data->cancel_id > 0)
+    g_signal_handler_disconnect (data->cancellable, data->cancel_id);
+  g_object_unref (data->cancellable);
+  g_free (data);
+}
+
+static void
+authenticator_completed (PolkitGnomeAuthenticator *authenticator,
+                         gboolean                  gained_authorization,
+                         gpointer                  user_data)
+{
+  AuthData *data = user_data;
+
+  g_warn_if_fail (authenticator == data->listener->the_authenticator);
+
+  g_object_unref (data->listener->the_authenticator);
+  data->listener->the_authenticator = NULL;
+
+  g_simple_async_result_complete (data->simple);
+  g_object_unref (data->simple);
+
+  auth_data_free (data);
+}
+
+static void
+cancelled_cb (GCancellable *cancellable,
+              gpointer user_data)
+{
+  AuthData *data = user_data;
+
+  polkit_gnome_authenticator_cancel (data->listener->the_authenticator);
+}
+
+static void
+polkit_gnome_listener_initiate_authentication (PolkitAgentListener  *agent_listener,
+                                               const gchar          *action_id,
+                                               const gchar          *cookie,
+                                               GList                *identities,
+                                               GCancellable         *cancellable,
+                                               GAsyncReadyCallback   callback,
+                                               gpointer              user_data)
+{
+  PolkitGnomeListener *listener = POLKIT_GNOME_LISTENER (agent_listener);
+  GSimpleAsyncResult *simple;
+  AuthData *data;
+
+  simple = g_simple_async_result_new (G_OBJECT (listener),
+                                      callback,
+                                      user_data,
+                                      polkit_gnome_listener_initiate_authentication);
+
+  if (listener->the_authenticator != NULL)
+    {
+      g_simple_async_result_set_error (simple,
+                                       POLKIT_ERROR,
+                                       POLKIT_ERROR_FAILED,
+                                       "Authentication is already in progress for another action");
+      g_simple_async_result_complete (simple);
+      goto out;
+    }
+
+  listener->the_authenticator = polkit_gnome_authenticator_new (action_id,
+                                                                cookie,
+                                                                identities);
+  if (listener->the_authenticator == NULL)
+    {
+      g_simple_async_result_set_error (simple,
+                                       POLKIT_ERROR,
+                                       POLKIT_ERROR_FAILED,
+                                       "Authentication is already in progress for another action");
+      g_simple_async_result_complete (simple);
+      goto out;
+    }
+
+  data = auth_data_new (listener, simple, cancellable);
+
+  g_signal_connect (listener->the_authenticator,
+                    "completed",
+                    G_CALLBACK (authenticator_completed),
+                    data);
+
+  if (cancellable != NULL)
+    {
+      data->cancel_id = g_signal_connect (cancellable,
+                                          "cancelled",
+                                          G_CALLBACK (cancelled_cb),
+                                          data);
+    }
+
+  polkit_gnome_authenticator_initiate (listener->the_authenticator);
+
+ out:
+  ;
+}
+
+static gboolean
+polkit_gnome_listener_initiate_authentication_finish (PolkitAgentListener  *listener,
+                                                      GAsyncResult         *res,
+                                                      GError              **error)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_gnome_listener_initiate_authentication);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
+
+  return TRUE;
+}
+

Added: trunk/src/polkitgnomelistener.h
==============================================================================
--- (empty file)
+++ trunk/src/polkitgnomelistener.h	Sat Jan 31 01:45:48 2009
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#ifndef __POLKIT_GNOME_LISTENER_H
+#define __POLKIT_GNOME_LISTENER_H
+
+#include <polkitagent/polkitagent.h>
+
+G_BEGIN_DECLS
+
+#define POLKIT_GNOME_TYPE_LISTENER          (polkit_gnome_listener_get_type())
+#define POLKIT_GNOME_LISTENER(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_GNOME_TYPE_LISTENER, PolkitGnomeListener))
+#define POLKIT_GNOME_LISTENER_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_GNOME_TYPE_LISTENER, PolkitGnomeListenerClass))
+#define POLKIT_GNOME_LISTENER_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_GNOME_TYPE_LISTENER, PolkitGnomeListenerClass))
+#define POLKIT_GNOME_IS_LISTENER(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_GNOME_TYPE_LISTENER))
+#define POLKIT_GNOME_IS_LISTENER_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_GNOME_TYPE_LISTENER))
+
+typedef struct _PolkitGnomeListener PolkitGnomeListener;
+typedef struct _PolkitGnomeListenerClass PolkitGnomeListenerClass;
+
+GType                 polkit_gnome_listener_get_type   (void) G_GNUC_CONST;
+PolkitAgentListener  *polkit_gnome_listener_new        (void);
+
+G_END_DECLS
+
+#endif /* __POLKIT_GNOME_LISTENER_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]