gnome-keyring r1198 - in trunk: . common daemon daemon/pkcs11 daemon/ssh daemon/ui
- From: nnielsen svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-keyring r1198 - in trunk: . common daemon daemon/pkcs11 daemon/ssh daemon/ui
- Date: Thu, 24 Jul 2008 04:07:27 +0000 (UTC)
Author: nnielsen
Date: Thu Jul 24 04:07:27 2008
New Revision: 1198
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1198&view=rev
Log:
* common/gkr-async.c:
* common/gkr-async.h:
* common/gkr-daemon-util.c:
* common/gkr-daemon-util.h:
* daemon/gkr-daemon-io.c:
* daemon/pkcs11/gkr-pkcs11-daemon-session.c:
* daemon/ssh/gkr-ssh-daemon-io.c:
* daemon/ui/gkr-ask-daemon.c:
* daemon/ui/gkr-ask-request.c:
* daemon/ui/gkr-ask-request.h: Don't prompt for the same prompt twice
while servicing the same client connection. Fixes bug #544373
Modified:
trunk/ChangeLog
trunk/common/gkr-async.c
trunk/common/gkr-async.h
trunk/common/gkr-daemon-util.c
trunk/common/gkr-daemon-util.h
trunk/daemon/gkr-daemon-io.c
trunk/daemon/pkcs11/gkr-pkcs11-daemon-session.c
trunk/daemon/ssh/gkr-ssh-daemon-io.c
trunk/daemon/ui/gkr-ask-daemon.c
trunk/daemon/ui/gkr-ask-request.c
trunk/daemon/ui/gkr-ask-request.h
Modified: trunk/common/gkr-async.c
==============================================================================
--- trunk/common/gkr-async.c (original)
+++ trunk/common/gkr-async.c Thu Jul 24 04:07:27 2008
@@ -373,6 +373,10 @@
worker->cancelled = 0;
worker->stopped = 0;
+ /*
+ * Don't change this to a thread pool too lightly. Assumptions are made
+ * that worker threads are not shared throughout the code.
+ */
worker->thread = g_thread_create (async_worker_thread, worker, TRUE, &err);
if (!worker->thread) {
g_warning ("couldn't create new worker thread: %s", err->message);
Modified: trunk/common/gkr-async.h
==============================================================================
--- trunk/common/gkr-async.h (original)
+++ trunk/common/gkr-async.h Thu Jul 24 04:07:27 2008
@@ -34,7 +34,7 @@
typedef struct _GkrAsyncWait GkrAsyncWait;
/*
- * Create a new wait condition
+ * Create a new wait condition. Use instead of GCond.
*/
GkrAsyncWait* gkr_async_wait_new (void);
@@ -53,6 +53,18 @@
*/
void gkr_async_notify (GkrAsyncWait *wait);
+/*
+ * Per Async Worker Storage. This is currently exactly the same
+ * as GPrivate, however that may change in the future, so use this
+ * API instead.
+ */
+
+typedef GPrivate GkrAsyncPrivate;
+#define gkr_async_private_new(x) g_private_new (x)
+#define gkr_async_private_get(x) g_private_get (x)
+#define gkr_async_private_set(x, y) g_private_set (x, y)
+#define gkr_async_private_free(x)
+
/* -----------------------------------------------------------------------------
* GENERAL ASYNC CALLS
*/
Modified: trunk/common/gkr-daemon-util.c
==============================================================================
--- trunk/common/gkr-daemon-util.c (original)
+++ trunk/common/gkr-daemon-util.c Thu Jul 24 04:07:27 2008
@@ -23,15 +23,230 @@
#include "config.h"
-#include "common/gkr-daemon-util.h"
-#include "common/gkr-cleanup.h"
+#include "gkr-async.h"
+#include "gkr-daemon-util.h"
+#include "gkr-cleanup.h"
#include <glib.h>
#include <sys/stat.h>
+
#include <errno.h>
+#include <string.h>
#include <unistd.h>
+enum {
+ PROP_0,
+ PROP_PID,
+ PROP_APP_PATH,
+ PROP_APP_DISPLAY
+};
+
+enum {
+ DISCONNECTED,
+ LAST_SIGNAL
+};
+
+G_DEFINE_TYPE (GkrDaemonClient, gkr_daemon_client, G_TYPE_OBJECT);
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static GkrAsyncPrivate *current_client = NULL;
+
+/* -----------------------------------------------------------------------------
+ * HELPERS
+ */
+
+static void
+unregister_client (gpointer data)
+{
+ g_assert (GKR_IS_DAEMON_CLIENT (data));
+ g_signal_emit (data, signals[DISCONNECTED], 0);
+ g_object_unref (data);
+}
+
+static void
+register_client (GkrDaemonClient *client)
+{
+ g_assert (GKR_IS_DAEMON_CLIENT (client));
+ g_assert (current_client);
+ gkr_async_private_set (current_client, client);
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static void
+gkr_daemon_client_init (GkrDaemonClient *obj)
+{
+
+}
+
+static void
+gkr_daemon_client_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GkrDaemonClient *client = GKR_DAEMON_CLIENT (obj);
+
+ switch (prop_id) {
+ case PROP_PID:
+ g_value_set_uint (value, client->pid);
+ break;
+ case PROP_APP_PATH:
+ g_value_set_string (value, client->app_path);
+ break;
+ case PROP_APP_DISPLAY:
+ g_value_set_string (value, client->app_display);
+ break;
+ }
+}
+
+static void
+gkr_daemon_client_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GkrDaemonClient *client = GKR_DAEMON_CLIENT (obj);
+
+ switch (prop_id) {
+ case PROP_PID:
+ g_return_if_fail (!client->pid);
+ client->pid = g_value_get_uint (value);
+ break;
+ case PROP_APP_PATH:
+ g_return_if_fail (!client->app_path);
+ client->app_path = g_value_dup_string (value);
+ break;
+ case PROP_APP_DISPLAY:
+ g_free (client->app_display);
+ client->app_display = g_value_dup_string (value);
+ break;
+ }
+}
+
+static void
+gkr_daemon_client_finalize (GObject *obj)
+{
+ GkrDaemonClient *client = GKR_DAEMON_CLIENT (obj);
+
+ if (client->app_path)
+ g_free (client->app_path);
+ if (client->app_display)
+ g_free (client->app_display);
+
+ G_OBJECT_CLASS (gkr_daemon_client_parent_class)->finalize (obj);
+}
+
+static void
+gkr_daemon_client_class_init (GkrDaemonClientClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass*) klass;
+ gkr_daemon_client_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->get_property = gkr_daemon_client_get_property;
+ gobject_class->set_property = gkr_daemon_client_set_property;
+ gobject_class->finalize = gkr_daemon_client_finalize;
+
+ g_object_class_install_property (gobject_class, PROP_PID,
+ g_param_spec_uint ("pid", "Process ID", "Process ID of client",
+ 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class, PROP_APP_PATH,
+ g_param_spec_string ("app-path", "Application Path", "Client application path",
+ NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class, PROP_APP_DISPLAY,
+ g_param_spec_string ("app-display", "Application Display Name", "Client application display name",
+ NULL, G_PARAM_READWRITE));
+
+ signals[DISCONNECTED] = g_signal_new ("disconnected", GKR_TYPE_DAEMON_CLIENT,
+ G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GkrDaemonClientClass, disconnected),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ current_client = gkr_async_private_new (unregister_client);
+}
+
+/* -------------------------------------------------------------------------------------
+ * PUBLIC STUFF
+ */
+
+GkrDaemonClient*
+gkr_daemon_client_set_current (pid_t pid, const gchar *app_path, const gchar *app_display)
+{
+ GkrDaemonClient *client;
+ gchar *path = NULL;
+
+ /* Try and figure out the path from the pid */
+#if defined(__linux__) || defined(__FreeBSD__)
+ if (pid > 0 && !app_path) {
+ char *buffer;
+ int len;
+ char *path = NULL;
+
+#if defined(__linux__)
+ path = g_strdup_printf ("/proc/%d/exe", (gint)pid);
+#elif defined(__FreeBSD__)
+ path = g_strdup_printf ("/proc/%d/file", (gint)pid);
+#endif
+ buffer = g_file_read_link (path, NULL);
+ g_free (path);
+
+ len = (buffer != NULL) ? strlen (buffer) : 0;
+ if (len > 0) {
+ path = g_strndup (buffer, len);
+ app_path = path;
+ }
+
+ g_free (buffer);
+ }
+#endif
+
+ client = g_object_new (GKR_TYPE_DAEMON_CLIENT, "pid", pid, "app-path", app_path,
+ "app-display", app_display, NULL);
+
+ register_client (client);
+ g_free (path);
+
+ return client;
+}
+
+GkrDaemonClient*
+gkr_daemon_client_get_current (void)
+{
+ if (!current_client)
+ return NULL;
+ return gkr_async_private_get (current_client);
+}
+
+pid_t
+gkr_daemon_client_get_app_pid (GkrDaemonClient* client)
+{
+ if (!client)
+ client = gkr_daemon_client_get_current ();
+ g_return_val_if_fail (GKR_IS_DAEMON_CLIENT (client), 0);
+ return client->pid;
+}
+
+const gchar*
+gkr_daemon_client_get_app_display (GkrDaemonClient* client)
+{
+ if (!client)
+ client = gkr_daemon_client_get_current ();
+ g_return_val_if_fail (GKR_IS_DAEMON_CLIENT (client), 0);
+ return client->app_display;
+}
+
+const gchar*
+gkr_daemon_client_get_app_path (GkrDaemonClient* client)
+{
+ if (!client)
+ client = gkr_daemon_client_get_current ();
+ g_return_val_if_fail (GKR_IS_DAEMON_CLIENT (client), 0);
+ return client->app_path;
+}
+
+/* -------------------------------------------------------------------------------------- */
+
static gchar* master_directory = NULL;
static GArray* published_environ = NULL;
@@ -325,3 +540,4 @@
else
return template;
}
+
Modified: trunk/common/gkr-daemon-util.h
==============================================================================
--- trunk/common/gkr-daemon-util.h (original)
+++ trunk/common/gkr-daemon-util.h Thu Jul 24 04:07:27 2008
@@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* gkr-daemon-util.h - Helper utilities for the daemon
- Copyright (C) 2007, Stefan Walter
+ Copyright (C) 2008, Stefan Walter
The Gnome Keyring Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -24,7 +24,10 @@
#ifndef GKRMASTERDIRECTORY_H_
#define GKRMASTERDIRECTORY_H_
+G_BEGIN_DECLS
+
#include <glib.h>
+#include <glib-object.h>
const gchar* gkr_daemon_util_get_master_directory (void);
@@ -32,4 +35,40 @@
const gchar** gkr_daemon_util_get_environment (void);
+#define GKR_TYPE_DAEMON_CLIENT (gkr_daemon_client_get_type ())
+#define GKR_DAEMON_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKR_TYPE_DAEMON_CLIENT, GkrDaemonClient))
+#define GKR_DAEMON_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKR_TYPE_DAEMON_CLIENT, GkrDaemonClientClass))
+#define GKR_IS_DAEMON_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKR_TYPE_DAEMON_CLIENT))
+#define GKR_IS_DAEMON_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GKR_TYPE_DAEMON_CLIENT))
+#define GKR_DAEMON_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKR_TYPE_DAEMON_CLIENT, GkrDaemonClientClass))
+
+typedef struct _GkrDaemonClient GkrDaemonClient;
+typedef struct _GkrDaemonClientClass GkrDaemonClientClass;
+
+struct _GkrDaemonClient {
+ GObject parent;
+ pid_t pid;
+ gchar *app_path;
+ gchar *app_display;
+};
+
+struct _GkrDaemonClientClass {
+ GObjectClass parent_class;
+ void (*disconnected) (GkrDaemonClient *client);
+};
+
+GType gkr_daemon_client_get_type (void);
+
+GkrDaemonClient* gkr_daemon_client_set_current (pid_t pid, const gchar *app_path, const gchar *app_display);
+
+GkrDaemonClient* gkr_daemon_client_get_current (void);
+
+pid_t gkr_daemon_client_get_app_pid (GkrDaemonClient* client);
+
+const gchar* gkr_daemon_client_get_app_display (GkrDaemonClient* client);
+
+const gchar* gkr_daemon_client_get_app_path (GkrDaemonClient* client);
+
+G_END_DECLS
+
#endif /*GKRMASTERDIRECTORY_H_*/
Modified: trunk/daemon/gkr-daemon-io.c
==============================================================================
--- trunk/daemon/gkr-daemon-io.c (original)
+++ trunk/daemon/gkr-daemon-io.c Thu Jul 24 04:07:27 2008
@@ -99,37 +99,14 @@
}
static GnomeKeyringApplicationRef*
-application_ref_new_from_pid (pid_t pid)
+application_ref_new_from_client ()
{
GnomeKeyringApplicationRef *app_ref;
-
+
app_ref = g_new0 (GnomeKeyringApplicationRef, 1);
-
-#if defined(__linux__) || defined(__FreeBSD__)
- g_assert (pid > 0);
- {
- char *buffer;
- int len;
- char *path = NULL;
-
-#if defined(__linux__)
- path = g_strdup_printf ("/proc/%d/exe", (gint)pid);
-#elif defined(__FreeBSD__)
- path = g_strdup_printf ("/proc/%d/file", (gint)pid);
-#endif
- buffer = g_file_read_link (path, NULL);
- g_free (path);
-
- len = (buffer != NULL) ? strlen (buffer) : 0;
- if (len > 0) {
- app_ref->pathname = g_malloc (len + 1);
- memcpy (app_ref->pathname, buffer, len);
- app_ref->pathname[len] = 0;
- }
- g_free (buffer);
- }
-#endif
-
+ app_ref->pathname = g_strdup (gkr_daemon_client_get_app_path (NULL));
+ app_ref->display_name = g_strdup (gkr_daemon_client_get_app_display (NULL));
+
return app_ref;
}
@@ -273,7 +250,9 @@
g_warning ("uid mismatch: %u, should be %u\n", (guint)uid, (guint)getuid());
return NULL;
}
- client->app_ref = application_ref_new_from_pid (pid);
+
+ gkr_daemon_client_set_current (pid, NULL, NULL);
+ client->app_ref = application_ref_new_from_client ();
/* 2. Read the connecting application display name */
@@ -286,6 +265,7 @@
if (!str)
return NULL;
debug_print (("got name: %s\n", str));
+ g_free (client->app_ref->display_name);
client->app_ref->display_name = str;
Modified: trunk/daemon/pkcs11/gkr-pkcs11-daemon-session.c
==============================================================================
--- trunk/daemon/pkcs11/gkr-pkcs11-daemon-session.c (original)
+++ trunk/daemon/pkcs11/gkr-pkcs11-daemon-session.c Thu Jul 24 04:07:27 2008
@@ -32,6 +32,7 @@
#include "common/gkr-async.h"
#include "common/gkr-buffer.h"
#include "common/gkr-crypto.h"
+#include "common/gkr-daemon-util.h"
#include "common/gkr-unix-credentials.h"
#include "keyrings/gkr-keyring-login.h"
@@ -1572,6 +1573,9 @@
return NULL;
}
+ /* Note the current client application */
+ gkr_daemon_client_set_current (pid, NULL, NULL);
+
/* Setup our buffers */
/* TODO: Do these need to be secure buffers? */
req = gkr_pkcs11_message_new ((GkrBufferAllocator)g_realloc);
Modified: trunk/daemon/ssh/gkr-ssh-daemon-io.c
==============================================================================
--- trunk/daemon/ssh/gkr-ssh-daemon-io.c (original)
+++ trunk/daemon/ssh/gkr-ssh-daemon-io.c Thu Jul 24 04:07:27 2008
@@ -168,6 +168,14 @@
SshClient *client = (SshClient*)user_data;
guchar op;
+ /*
+ * Note the current client application. We actually don't know
+ * the pid, so this is just an empty application object, useful
+ * for other parts of the code to track the lifecycle of the
+ * connection.
+ */
+ gkr_daemon_client_set_current (0, NULL, NULL);
+
/* This array needs to be laid out properly */
g_assert ((sizeof (gkr_ssh_operations) / sizeof (gkr_ssh_operations[0])) == GKR_SSH_OP_MAX);
Modified: trunk/daemon/ui/gkr-ask-daemon.c
==============================================================================
--- trunk/daemon/ui/gkr-ask-daemon.c (original)
+++ trunk/daemon/ui/gkr-ask-daemon.c Thu Jul 24 04:07:27 2008
@@ -28,6 +28,7 @@
#include "common/gkr-async.h"
#include "common/gkr-cleanup.h"
+#include "common/gkr-daemon-util.h"
#include <glib.h>
@@ -66,6 +67,52 @@
gkr_cleanup_register (ask_daemon_cleanup, NULL);
}
+static gboolean
+check_previously_denied (GkrAskRequest *ask)
+{
+ GkrDaemonClient *client;
+ GHashTable *denied;
+ gchar *unique;
+ gboolean ret;
+
+ client = gkr_daemon_client_get_current ();
+ g_return_val_if_fail (client, FALSE);
+
+ denied = g_object_get_data (G_OBJECT (client), "gkr-ask-daemon.denied");
+ if (!denied)
+ return FALSE;
+
+ unique = gkr_ask_request_make_unique (ask);
+ g_return_val_if_fail (unique, FALSE);
+ ret = g_hash_table_lookup (denied, unique) ? TRUE : FALSE;
+ g_free (unique);
+ return ret;
+}
+
+static void
+note_previously_denied (GkrAskRequest *ask)
+{
+ GkrDaemonClient *client;
+ GHashTable *denied;
+ gchar *unique;
+
+ unique = gkr_ask_request_make_unique (ask);
+ g_return_if_fail (unique);
+
+ client = gkr_daemon_client_get_current ();
+ g_return_if_fail (client);
+
+ /* Associate the denied table with the current client */
+ denied = g_object_get_data (G_OBJECT (client), "gkr-ask-daemon.denied");
+ if (!denied) {
+ denied = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ g_object_set_data_full (G_OBJECT (client), "gkr-ask-daemon.denied",
+ denied, (GDestroyNotify)g_hash_table_unref);
+ }
+
+ g_hash_table_insert (denied, unique, unique);
+}
+
void
gkr_ask_daemon_process (GkrAskRequest* ask)
{
@@ -73,7 +120,9 @@
g_assert (GKR_IS_ASK_REQUEST (ask));
g_assert (!gkr_ask_request_is_complete (ask));
-
+
+ g_object_ref (ask);
+
/*
* Hand it off to the hook. This is used in the test harnesses
* to verify that a prompt or no prompt was run.
@@ -93,23 +142,44 @@
/* Wait until no other asks are prompting */
while (current_ask)
gkr_async_wait (wait_condition);
+
+ /*
+ * See if the user already denied this request.
+ *
+ * The logic here is, that if the user denied the request,
+ * then we won't prompt them again for the same string.
+ * They'll probably deny it again.
+ *
+ * We only keep this cache for the current client connection.
+ */
+ if (check_previously_denied (ask)) {
+ gkr_ask_request_deny (ask);
+ goto done;
+ }
g_assert (ask_daemon_inited);
-
- g_object_ref (ask);
current_ask = ask;
- if (!gkr_ask_request_check (ask))
+ if (!gkr_ask_request_check (ask)) {
gkr_ask_request_prompt (ask);
+
+ /*
+ * Note that this prompt was explicitly denied, so we
+ * can prevent prompting again on the same client
+ * connection. See above.
+ */
+ if (ask->response == GKR_ASK_RESPONSE_DENY)
+ note_previously_denied (ask);
+ }
current_ask = NULL;
- g_object_unref (ask);
g_assert (wait_condition);
gkr_async_notify (wait_condition);
done:
g_assert (gkr_ask_request_is_complete (ask));
+ g_object_unref (ask);
}
void
Modified: trunk/daemon/ui/gkr-ask-request.c
==============================================================================
--- trunk/daemon/ui/gkr-ask-request.c (original)
+++ trunk/daemon/ui/gkr-ask-request.c Thu Jul 24 04:07:27 2008
@@ -260,7 +260,7 @@
}
static void
-cancel_ask_if_active (GkrAskRequest *ask)
+kill_ask_if_active (GkrAskRequest *ask)
{
GkrAskRequestPrivate *pv = GKR_ASK_REQUEST_GET_PRIVATE (ask);
if (pv->ask_pid) {
@@ -268,8 +268,6 @@
kill_ask_process (ask);
g_assert (pv->ask_pid == 0);
}
-
- mark_completed (ask, GKR_ASK_RESPONSE_FAILURE);
}
static void
@@ -643,7 +641,8 @@
pv->object = NULL;
/* Cancel any goings on */
- cancel_ask_if_active (ask);
+ kill_ask_if_active (ask);
+ mark_completed (ask, GKR_ASK_RESPONSE_FAILURE);
}
static gboolean
@@ -699,7 +698,8 @@
GkrAskRequest *ask = GKR_ASK_REQUEST (obj);
GkrAskRequestPrivate *pv = GKR_ASK_REQUEST_GET_PRIVATE (ask);
- cancel_ask_if_active (ask);
+ kill_ask_if_active (ask);
+ mark_completed (ask, GKR_ASK_RESPONSE_FAILURE);
g_assert (pv->ask_pid == 0);
gkr_secure_strfree (ask->original_password);
@@ -906,14 +906,19 @@
}
void
+gkr_ask_request_deny (GkrAskRequest *ask)
+{
+ g_assert (GKR_IS_ASK_REQUEST (ask));
+ kill_ask_if_active (ask);
+ mark_completed (ask, GKR_ASK_RESPONSE_DENY);
+}
+
+void
gkr_ask_request_cancel (GkrAskRequest *ask)
{
- GkrAskRequestPrivate *pv = GKR_ASK_REQUEST_GET_PRIVATE (ask);
g_assert (GKR_IS_ASK_REQUEST (ask));
-
- cancel_ask_if_active (ask);
- if (!pv->completed)
- mark_completed (ask, GKR_ASK_RESPONSE_FAILURE);
+ kill_ask_if_active (ask);
+ mark_completed (ask, GKR_ASK_RESPONSE_FAILURE);
}
gboolean
@@ -939,3 +944,21 @@
g_assert (GKR_IS_ASK_REQUEST (ask));
pv->location = loc;
}
+
+gchar*
+gkr_ask_request_make_unique (GkrAskRequest *ask)
+{
+ GkrAskRequestPrivate *pv = GKR_ASK_REQUEST_GET_PRIVATE (ask);
+ g_assert (GKR_IS_ASK_REQUEST (ask));
+
+ /*
+ * This string is used to uniquely identify another
+ * prompt with the same text as this one. Usually used
+ * so we can be intelligent about prompting the user.
+ */
+
+ return g_strconcat (pv->title ? pv->title : "", "|",
+ pv->primary ? pv->primary : "", "|",
+ pv->secondary ? pv->secondary : "", "|",
+ NULL);
+}
Modified: trunk/daemon/ui/gkr-ask-request.h
==============================================================================
--- trunk/daemon/ui/gkr-ask-request.h (original)
+++ trunk/daemon/ui/gkr-ask-request.h Thu Jul 24 04:07:27 2008
@@ -123,10 +123,14 @@
void gkr_ask_request_prompt (GkrAskRequest *ask);
+void gkr_ask_request_deny (GkrAskRequest *ask);
+
void gkr_ask_request_cancel (GkrAskRequest *ask);
gboolean gkr_ask_request_is_complete (GkrAskRequest *ask);
+gchar* gkr_ask_request_make_unique (GkrAskRequest *ask);
+
G_END_DECLS
#endif /* __GKR_ASK_REQUEST_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]