summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
Diffstat (limited to 'library')
-rw-r--r--library/Makefile.am73
-rw-r--r--library/gnome-keyring-1-uninstalled.pc.in11
-rw-r--r--library/gnome-keyring-1.pc.in11
-rw-r--r--library/gnome-keyring-private.h69
-rw-r--r--library/gnome-keyring-proto.c1704
-rw-r--r--library/gnome-keyring-proto.h247
-rw-r--r--library/gnome-keyring-utils.c270
-rw-r--r--library/gnome-keyring.c2825
-rw-r--r--library/gnome-keyring.h459
-rw-r--r--library/list-keyrings.c225
-rw-r--r--library/test.c502
11 files changed, 6396 insertions, 0 deletions
diff --git a/library/Makefile.am b/library/Makefile.am
new file mode 100644
index 00000000..96eee60a
--- /dev/null
+++ b/library/Makefile.am
@@ -0,0 +1,73 @@
+libgnomekeyringincludedir = $(includedir)/gnome-keyring-1/
+
+noinst_PROGRAMS= \
+ list-keyrings \
+ test-keyring \
+ test-keyring-two
+
+lib_LTLIBRARIES=libgnome-keyring.la
+
+noinst_LTLIBRARIES=libgnome-keyring-common.la
+
+INCLUDES= \
+ -DPREFIX=\""$(prefix)"\" \
+ -DBINDIR=\""$(bindir)"\" \
+ -DLIBEXECDIR=\""$(libexecdir)"\" \
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GTK_CFLAGS) \
+ $(GLIB_CFLAGS)
+
+libgnome_keyring_common_la_SOURCES = \
+ gnome-keyring-private.h \
+ gnome-keyring-proto.c \
+ gnome-keyring-proto.h \
+ gnome-keyring-utils.c
+
+libgnome_keyring_common_la_LIBADD = \
+ $(GLIB_LIBS)
+
+libgnome_keyring_la_SOURCES = \
+ gnome-keyring.c \
+ gnome-keyring.h
+
+libgnomekeyringinclude_HEADERS = \
+ gnome-keyring.h
+
+
+libgnome_keyring_la_LIBADD = \
+ libgnome-keyring-common.la \
+ $(GLIB_LIBS)
+
+libgnome_keyring_la_LDFLAGS = \
+ -version-info $(LIB_GNOME_KEYRING_LT_VERSION) \
+ -no-undefined
+
+list_keyrings_SOURCES = \
+ list-keyrings.c
+
+list_keyrings_LDADD = \
+ libgnome-keyring.la \
+ $(GTK_LIBS)
+
+test_keyring_SOURCES = \
+ test.c
+
+test_keyring_LDADD = \
+ libgnome-keyring.la \
+ $(GTK_LIBS)
+
+test_keyring_two_SOURCES = \
+ test.c
+
+test_keyring_two_LDADD = \
+ libgnome-keyring.la \
+ $(GTK_LIBS)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = gnome-keyring-1.pc
+
+EXTRA_DIST = \
+ gnome-keyring-1-uninstalled.pc.in
+
diff --git a/library/gnome-keyring-1-uninstalled.pc.in b/library/gnome-keyring-1-uninstalled.pc.in
new file mode 100644
index 00000000..d5293b03
--- /dev/null
+++ b/library/gnome-keyring-1-uninstalled.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnome-keyring
+Description: The GNOME keyring libraries
+Version: @VERSION@
+Requires: glib-2.0
+Libs: ${pc_top_builddir}/${pcfiledir}/libgnome-keyring-common.la ${pc_top_builddir}/${pcfiledir}/libgnome-keyring.la
+Cflags: -I${pc_top_builddir}/${pcfiledir}
diff --git a/library/gnome-keyring-1.pc.in b/library/gnome-keyring-1.pc.in
new file mode 100644
index 00000000..cc053bec
--- /dev/null
+++ b/library/gnome-keyring-1.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnome-keyring
+Description: The GNOME keyring libraries
+Version: @VERSION@
+Requires: glib-2.0
+Libs: -L${libdir} -lgnome-keyring
+Cflags: -I${includedir}/gnome-keyring-1
diff --git a/library/gnome-keyring-private.h b/library/gnome-keyring-private.h
new file mode 100644
index 00000000..f1c17a76
--- /dev/null
+++ b/library/gnome-keyring-private.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-keyring-private.h - private header for keyring
+
+ Copyright (C) 2003 Red Hat, Inc
+
+ 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
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Alexander Larsson <alexl@redhat.com>
+*/
+
+#ifndef GNOME_KEYRING_PRIVATE_H
+#define GNOME_KEYRING_PRIVATE_H
+
+#include "gnome-keyring.h"
+
+struct GnomeKeyringApplicationRef {
+ char *display_name;
+ char *pathname;
+};
+
+struct GnomeKeyringAccessControl {
+ GnomeKeyringApplicationRef *application; /* null for all */
+ GnomeKeyringAccessType types_allowed;
+};
+
+struct GnomeKeyringInfo {
+ gboolean lock_on_idle;
+ guint32 lock_timeout;
+ time_t mtime;
+ time_t ctime;
+ gboolean is_locked;
+};
+
+struct GnomeKeyringItemInfo {
+ GnomeKeyringItemType type;
+ char *display_name;
+ char *secret;
+ time_t mtime;
+ time_t ctime;
+};
+
+typedef enum {
+ GNOME_KEYRING_ASK_RESPONSE_FAILURE,
+ GNOME_KEYRING_ASK_RESPONSE_DENY,
+ GNOME_KEYRING_ASK_RESPONSE_ALLOW_ONCE,
+ GNOME_KEYRING_ASK_RESPONSE_ALLOW_FOREVER
+} GnomeKeyringAskResponse;
+
+#ifdef WITH_DBUS
+#define GNOME_KEYRING_DAEMON_SERVICE "org.gnome.keyring"
+#define GNOME_KEYRING_DAEMON_PATH "/org/gnome/keyring/daemon"
+#define GNOME_KEYRING_DAEMON_INTERFACE "org.gnome.keyring.Daemon"
+#endif
+
+#endif /* GNOME_KEYRING_PRIVATE_H */
+
diff --git a/library/gnome-keyring-proto.c b/library/gnome-keyring-proto.c
new file mode 100644
index 00000000..aee7c39b
--- /dev/null
+++ b/library/gnome-keyring-proto.c
@@ -0,0 +1,1704 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-keyring-proto.c - helper code for the keyring daemon protocol
+
+ Copyright (C) 2003 Red Hat, Inc
+
+ 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
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Alexander Larsson <alexl@redhat.com>
+*/
+#include "config.h"
+
+#include <string.h>
+#include <stdarg.h>
+
+#include "gnome-keyring-proto.h"
+#include "gnome-keyring-private.h"
+
+gboolean
+gnome_keyring_proto_set_uint32 (GString *buffer, gsize offset, guint32 val)
+{
+ unsigned char *ptr;
+
+ if (buffer->len < 4 ||
+ offset > buffer->len - 4) {
+ return FALSE;
+ }
+
+ ptr = (unsigned char *)buffer->str + offset;
+ ptr[0] = (val >> 24) & 0xff;
+ ptr[1] = (val >> 16) & 0xff;
+ ptr[2] = (val >> 8) & 0xff;
+ ptr[3] = (val >> 0) & 0xff;
+
+ return TRUE;
+}
+
+void
+gnome_keyring_proto_add_uint32 (GString *buffer, guint32 val)
+{
+ g_string_append_c (buffer, (val >> 24) & 0xff);
+ g_string_append_c (buffer, (val >> 16) & 0xff);
+ g_string_append_c (buffer, (val >> 8) & 0xff);
+ g_string_append_c (buffer, (val >> 0) & 0xff);
+}
+
+void
+gnome_keyring_proto_add_time (GString *buffer, time_t time)
+{
+ guint64 val;
+
+ val = time;
+ gnome_keyring_proto_add_uint32 (buffer, ((val >> 32) & 0xffffffff));
+ gnome_keyring_proto_add_uint32 (buffer, (val & 0xffffffff));
+}
+
+gboolean
+gnome_keyring_proto_get_uint32 (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ guint32 *val)
+{
+ unsigned char *ptr;
+
+ if (buffer->len < 4 ||
+ offset > buffer->len - 4) {
+ return FALSE;
+ }
+
+ ptr = (unsigned char *)buffer->str + offset;
+ if (val != NULL) {
+ *val = ptr[0] << 24 |
+ ptr[1] << 16 |
+ ptr[2] << 8 |
+ ptr[3];
+ }
+
+ if (next_offset != NULL) {
+ *next_offset = offset + 4;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_get_time (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ time_t *time)
+{
+ guint32 a, b;
+ guint64 val;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer,
+ offset, &offset, &a)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer,
+ offset, &offset, &b)) {
+ return FALSE;
+ }
+
+ val = ((guint64)a) << 32 | b;
+
+ *next_offset = offset;
+ *time = (time_t) val;
+
+ return TRUE;
+}
+
+
+static gboolean
+gnome_keyring_proto_add_string (GString *buffer, const char *str, gsize len)
+{
+ if (len >= 0x7fffffff) {
+ return FALSE;
+ }
+
+ if (str != NULL && memchr(str, 0, len) != NULL) {
+ return FALSE;
+ }
+
+ if (str == NULL) {
+ gnome_keyring_proto_add_uint32 (buffer, 0xffffffff);
+ } else {
+ gnome_keyring_proto_add_uint32 (buffer, len);
+ g_string_append_len (buffer, str, len);
+ }
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_add_utf8_string (GString *buffer, const char *str)
+{
+ gsize len;
+
+ if (str != NULL) {
+ len = strlen (str);
+
+ if (!g_utf8_validate (str, len, NULL)) {
+ return FALSE;
+ }
+ } else {
+ len = 0;
+ }
+
+ return gnome_keyring_proto_add_string (buffer, str, len);
+}
+
+gboolean
+gnome_keyring_proto_get_bytes (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ guchar *out, gsize n_bytes)
+{
+ if (buffer->len < n_bytes ||
+ offset > buffer->len - n_bytes) {
+ return FALSE;
+ }
+
+ memcpy (out, buffer->str + offset, n_bytes);
+ *next_offset = offset + n_bytes;
+
+ return TRUE;
+}
+
+
+static gboolean
+gnome_keyring_proto_get_string (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ char **str_ret, gsize *len_ret)
+{
+ guint32 len;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &len)) {
+ return FALSE;
+ }
+ if (len == 0xffffffff) {
+ *next_offset = offset;
+ *len_ret = 0;
+ *str_ret = NULL;
+ return TRUE;
+ } else if (len >= 0x7fffffff) {
+ return FALSE;
+ }
+
+ if (buffer->len < len ||
+ offset > buffer->len - len) {
+ return FALSE;
+ }
+
+ *str_ret = g_memdup (buffer->str + offset, len+1);
+ /* Always zero terminate */
+ (*str_ret)[len] = 0;
+ *len_ret = len;
+ *next_offset = offset + len;
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_get_utf8_string (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ char **str_ret)
+{
+ gsize len;
+ char *str;
+
+ if (!gnome_keyring_proto_get_string (buffer,
+ offset,
+ &offset,
+ &str,
+ &len)) {
+ return FALSE;
+ }
+
+ if (str != NULL) {
+ if (memchr (str, 0, len) != NULL) {
+ g_free (str);
+ return FALSE;
+ }
+
+ if (!g_utf8_validate (str, len, NULL)) {
+ g_free (str);
+ return FALSE;
+ }
+ }
+
+ if (next_offset != NULL) {
+ *next_offset = offset;
+ }
+ if (str_ret != NULL) {
+ *str_ret = str;
+ } else {
+ g_free (str);
+ }
+ return TRUE;
+}
+
+static gboolean
+gnome_keyring_proto_start_operation (GString *buffer,
+ GnomeKeyringOpCode op,
+ gsize *op_start)
+{
+ gsize appname_pos;
+ const char *name;
+
+ appname_pos = buffer->len;
+ gnome_keyring_proto_add_uint32 (buffer, 0);
+
+ name = g_get_application_name ();
+ if (name != NULL && !g_utf8_validate (name, -1, NULL)) {
+ g_warning ("g_application_name not utf8 encoded");
+ name = NULL;
+ } else if (name == NULL) {
+ g_warning ("g_set_application_name not set.");
+ }
+ if (name == NULL) {
+ /* General name if none set */
+ name = "Application";
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer, name)) {
+ return FALSE;
+ }
+
+ /* backpatch application name size */
+ if (!gnome_keyring_proto_set_uint32 (buffer, appname_pos, buffer->len)) {
+ return FALSE;
+ }
+
+
+ /* Make space for packet size */
+ *op_start = buffer->len;
+ gnome_keyring_proto_add_uint32 (buffer, 0);
+ gnome_keyring_proto_add_uint32 (buffer, op);
+
+ return TRUE;
+}
+
+static gboolean
+gnome_keyring_proto_end_operation (GString *buffer,
+ gsize op_start)
+{
+ if (!gnome_keyring_proto_set_uint32 (buffer, op_start, buffer->len - op_start)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_decode_packet_size (GString *buffer,
+ guint32 *size)
+{
+ return gnome_keyring_proto_get_uint32 (buffer, 0, NULL, size);
+}
+
+gboolean
+gnome_keyring_proto_decode_packet_operation (GString *buffer,
+ GnomeKeyringOpCode *op)
+{
+ guint32 op_nr;
+ gboolean res;
+
+ res = gnome_keyring_proto_get_uint32 (buffer, 4, NULL, &op_nr);
+ *op = op_nr;
+ return res;
+}
+
+gboolean
+gnome_keyring_proto_encode_op_only (GString *buffer,
+ GnomeKeyringOpCode op)
+{
+ gsize op_start;
+
+ if (!gnome_keyring_proto_start_operation (buffer, op, &op_start)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_encode_op_string (GString *buffer,
+ GnomeKeyringOpCode op,
+ const char *str)
+{
+ gsize op_start;
+
+ if (!gnome_keyring_proto_start_operation (buffer, op, &op_start)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ str)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_encode_op_string_int (GString *buffer,
+ GnomeKeyringOpCode op,
+ const char *str,
+ guint32 val)
+{
+ gsize op_start;
+
+ if (!gnome_keyring_proto_start_operation (buffer, op, &op_start)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ str)) {
+ return FALSE;
+ }
+ gnome_keyring_proto_add_uint32 (buffer, val);
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_encode_op_string_int_int (GString *buffer,
+ GnomeKeyringOpCode op,
+ const char *str,
+ guint32 integer1,
+ guint32 integer2)
+{
+ gsize op_start;
+ if (!gnome_keyring_proto_start_operation (buffer, op, &op_start))
+ return FALSE;
+ if (!gnome_keyring_proto_add_utf8_string (buffer, str))
+ return FALSE;
+ gnome_keyring_proto_add_uint32 (buffer, integer1);
+ gnome_keyring_proto_add_uint32 (buffer, integer2);
+ if (!gnome_keyring_proto_end_operation (buffer, op_start))
+ return FALSE;
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_encode_op_string_string (GString *buffer,
+ GnomeKeyringOpCode op,
+ const char *str1,
+ const char *str2)
+{
+ gsize op_start;
+
+ if (!gnome_keyring_proto_start_operation (buffer, op, &op_start)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ str1)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ str2)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_encode_op_string_string_string (GString *buffer,
+ GnomeKeyringOpCode op,
+ const char *str1,
+ const char *str2,
+ const char *str3)
+{
+ gsize op_start;
+
+ if (!gnome_keyring_proto_start_operation (buffer, op, &op_start)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ str1)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ str2)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ str3)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_encode_find (GString *buffer,
+ GnomeKeyringItemType type,
+ GnomeKeyringAttributeList *attributes)
+{
+ gsize op_start;
+
+ gnome_keyring_proto_start_operation (buffer,
+ GNOME_KEYRING_OP_FIND,
+ &op_start);
+
+ gnome_keyring_proto_add_uint32 (buffer, type);
+
+ if (!gnome_keyring_proto_add_attribute_list (buffer, attributes)) {
+ goto bail;
+ }
+
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ goto bail;
+ }
+
+ return TRUE;
+
+ bail:
+ g_string_set_size (buffer, op_start);
+ return FALSE;
+}
+
+gboolean
+gnome_keyring_proto_encode_create_item (GString *buffer,
+ const char *keyring,
+ const char *display_name,
+ GnomeKeyringAttributeList *attributes,
+ const char *secret,
+ GnomeKeyringItemType type,
+ gboolean update_if_exists)
+{
+ gsize op_start;
+
+ if (!gnome_keyring_proto_start_operation (buffer,
+ GNOME_KEYRING_OP_CREATE_ITEM,
+ &op_start)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ keyring)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ display_name)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ secret)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_attribute_list (buffer,
+ attributes)) {
+ return FALSE;
+ }
+ gnome_keyring_proto_add_uint32 (buffer, type);
+ gnome_keyring_proto_add_uint32 (buffer, update_if_exists);
+
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_decode_create_item (GString *buffer,
+ char **keyring,
+ char **display_name,
+ GnomeKeyringAttributeList **attributes,
+ char **secret,
+ GnomeKeyringItemType *type,
+ gboolean *update_if_exists)
+{
+ gsize offset;
+ GnomeKeyringOpCode op;
+ guint val;
+
+ if (keyring != NULL) {
+ *keyring = NULL;
+ }
+ if (display_name != NULL) {
+ *display_name = NULL;
+ }
+ if (secret != NULL) {
+ *secret = NULL;
+ }
+ if (attributes != NULL) {
+ *attributes = NULL;
+ }
+
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, &op)) {
+ return FALSE;
+ }
+ if (op != GNOME_KEYRING_OP_CREATE_ITEM) {
+ return FALSE;
+ }
+ offset = 8;
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ keyring)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ display_name)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ secret)) {
+ goto bail;
+ }
+
+ if (!gnome_keyring_proto_decode_attribute_list (buffer,
+ offset, &offset,
+ attributes)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &val)) {
+ goto bail;
+ }
+ if (type != NULL) {
+ *type = val;
+ }
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &val)) {
+ goto bail;
+ }
+ if (update_if_exists != NULL) {
+ *update_if_exists = val;
+ }
+
+ return TRUE;
+
+ bail:
+ if (attributes != NULL) {
+ gnome_keyring_attribute_list_free (*attributes);
+ }
+ if (keyring != NULL) {
+ g_free (*keyring);
+ }
+ if (display_name != NULL) {
+ g_free (*display_name);
+ }
+ if (secret != NULL) {
+ gnome_keyring_free_password (*secret);
+ }
+ return FALSE;
+
+}
+
+
+gboolean
+gnome_keyring_proto_encode_set_attributes (GString *buffer,
+ const char *keyring,
+ guint32 id,
+ GnomeKeyringAttributeList *attributes)
+{
+ gsize op_start;
+
+ if (!gnome_keyring_proto_start_operation (buffer,
+ GNOME_KEYRING_OP_SET_ITEM_ATTRIBUTES,
+ &op_start)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ keyring)) {
+ return FALSE;
+ }
+ gnome_keyring_proto_add_uint32 (buffer, id);
+
+ if (!gnome_keyring_proto_add_attribute_list (buffer, attributes)) {
+ return FALSE;
+ }
+
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_encode_set_acl (GString *buffer,
+ const char *keyring,
+ guint32 id,
+ GList *acl)
+{
+ gsize op_start;
+
+ if (!gnome_keyring_proto_start_operation (buffer,
+ GNOME_KEYRING_OP_SET_ITEM_ACL,
+ &op_start)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ keyring)) {
+ return FALSE;
+ }
+ gnome_keyring_proto_add_uint32 (buffer, id);
+
+ if (!gnome_keyring_proto_add_acl (buffer, acl)) {
+ return FALSE;
+ }
+
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+gboolean
+gnome_keyring_proto_encode_set_item_info (GString *buffer,
+ const char *keyring,
+ guint32 id,
+ GnomeKeyringItemInfo *info)
+{
+ gsize op_start;
+
+ if (!gnome_keyring_proto_start_operation (buffer,
+ GNOME_KEYRING_OP_SET_ITEM_INFO,
+ &op_start)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ keyring)) {
+ return FALSE;
+ }
+ gnome_keyring_proto_add_uint32 (buffer, id);
+
+ gnome_keyring_proto_add_uint32 (buffer, info->type);
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ info->display_name)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ info->secret)) {
+ return FALSE;
+ }
+
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_encode_set_keyring_info (GString *buffer,
+ const char *keyring,
+ GnomeKeyringInfo *info)
+{
+ gsize op_start;
+
+ if (!gnome_keyring_proto_start_operation (buffer,
+ GNOME_KEYRING_OP_SET_KEYRING_INFO,
+ &op_start)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ keyring)) {
+ return FALSE;
+ }
+
+ gnome_keyring_proto_add_uint32 (buffer, info->lock_on_idle);
+ gnome_keyring_proto_add_uint32 (buffer, info->lock_timeout);
+
+ if (!gnome_keyring_proto_end_operation (buffer, op_start)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+gboolean
+gnome_keyring_proto_decode_attribute_list (GString *buffer,
+ gsize offset, gsize *next_offset,
+ GnomeKeyringAttributeList **attributes_out)
+{
+ guint32 list_size;
+ GnomeKeyringAttributeList *attributes;
+ GnomeKeyringAttribute attribute;
+ char *name;
+ guint32 type;
+ char *str;
+ guint32 val;
+ int i;
+
+ attributes = NULL;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &list_size)) {
+ goto bail;
+ }
+
+ attributes = gnome_keyring_attribute_list_new ();
+ for (i = 0; i < list_size; i++) {
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ &name)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &type)) {
+ g_free (name);
+ goto bail;
+ }
+ switch (type) {
+ case GNOME_KEYRING_ATTRIBUTE_TYPE_STRING:
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ &str)) {
+ g_free (name);
+ goto bail;
+ }
+ attribute.name = name;
+ attribute.type = type;
+ attribute.value.string = str;
+ g_array_append_val (attributes, attribute);
+ break;
+ case GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32:
+ if (!gnome_keyring_proto_get_uint32 (buffer,
+ offset, &offset,
+ &val)) {
+ g_free (name);
+ goto bail;
+ }
+ attribute.name = name;
+ attribute.type = type;
+ attribute.value.integer = val;
+ g_array_append_val (attributes, attribute);
+ break;
+ default:
+ g_free (name);
+ goto bail;
+ }
+ }
+
+ if (attributes_out != NULL) {
+ *attributes_out = attributes;
+ } else {
+ gnome_keyring_attribute_list_free (attributes);
+ }
+ *next_offset = offset;
+ return TRUE;
+
+ bail:
+ gnome_keyring_attribute_list_free (attributes);
+ return FALSE;
+}
+
+gboolean
+gnome_keyring_proto_decode_acl (GString *buffer,
+ gsize offset, gsize *next_offset,
+ GList **acl_out)
+{
+ guint32 list_size;
+ GList *acl;
+ GnomeKeyringAccessControl *ac;
+ GnomeKeyringApplicationRef *ref;
+ char *display_name;
+ char *pathname;
+ guint32 types_allowed;
+ int i;
+
+ acl = NULL;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &list_size)) {
+ goto bail;
+ }
+
+ for (i = 0; i < list_size; i++) {
+ ac = g_new0 (GnomeKeyringAccessControl, 1);
+ ref = g_new0 (GnomeKeyringApplicationRef, 1);
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ &display_name)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ &pathname)) {
+ g_free (display_name);
+ goto bail;
+ }
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &types_allowed)) {
+ g_free (display_name);
+ g_free (pathname);
+ goto bail;
+ }
+ ref->display_name = display_name;
+ ref->pathname = pathname;
+ ac->application = ref;
+ ac->types_allowed = types_allowed;
+ acl = g_list_append (acl, ac);
+ }
+
+ if (acl_out != NULL) {
+ *acl_out = acl;
+ } else {
+ g_list_free (acl);
+ }
+ *next_offset = offset;
+ return TRUE;
+
+ bail:
+ g_list_free (acl);
+ return FALSE;
+}
+
+
+gboolean
+gnome_keyring_proto_add_attribute_list (GString *buffer,
+ GnomeKeyringAttributeList *attributes)
+{
+ int i;
+ GnomeKeyringAttribute *array;
+
+ array = (GnomeKeyringAttribute *)attributes->data;
+
+ i = 0;
+ gnome_keyring_proto_add_uint32 (buffer, attributes->len);
+
+ for (i = 0; i < attributes->len; i++) {
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ array[i].name)) {
+ return FALSE;
+ }
+ gnome_keyring_proto_add_uint32 (buffer, array[i].type);
+ switch (array[i].type) {
+ case GNOME_KEYRING_ATTRIBUTE_TYPE_STRING:
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ array[i].value.string)) {
+ return FALSE;
+ }
+ break;
+ case GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32:
+ gnome_keyring_proto_add_uint32 (buffer, array[i].value.integer);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_add_acl (GString *buffer,
+ GList *acl)
+{
+ int length;
+ GnomeKeyringAccessControl *ac;
+ GList *tmp;
+
+ length = g_list_length (acl);
+
+ gnome_keyring_proto_add_uint32 (buffer, length);
+
+ for (tmp = acl; tmp != NULL; tmp = tmp->next) {
+ ac = (GnomeKeyringAccessControl *)tmp->data;
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ ac->application->display_name)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_add_utf8_string (buffer,
+ ac->application->pathname)) {
+ return FALSE;
+ }
+ gnome_keyring_proto_add_uint32 (buffer, ac->types_allowed);
+ }
+
+ return TRUE;
+}
+
+
+
+gboolean
+gnome_keyring_proto_decode_result_reply (GString *buffer,
+ GnomeKeyringResult *result)
+{
+ gsize offset;
+ guint32 res;
+
+ offset = 4;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &res)) {
+ return FALSE;
+ }
+ *result = res;
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_decode_result_string_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ char **str)
+{
+ gsize offset;
+ guint32 res;
+
+ offset = 4;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &res)) {
+ return FALSE;
+ }
+ *result = res;
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ str)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_decode_result_string_list_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GList **list)
+{
+ gsize offset;
+ guint32 res;
+ guint32 list_size, i;
+ GList *names;
+ char *str;
+
+ offset = 4;
+ names = NULL;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &res)) {
+ return FALSE;
+ }
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &list_size)) {
+ goto bail;
+ }
+
+ for (i = 0; i < list_size; i++) {
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ &str)) {
+ goto bail;
+ }
+ names = g_list_prepend (names, str);
+ }
+
+ *result = res;
+ *list = g_list_reverse (names);
+
+ return TRUE;
+
+ bail:
+ g_list_foreach (names, (GFunc) g_free, NULL);
+ g_list_free (names);
+ return FALSE;
+}
+
+gboolean
+gnome_keyring_proto_decode_find_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GList **list_out)
+{
+ GList *list;
+ gsize offset;
+ guint32 res;
+ GnomeKeyringFound *found;
+
+ offset = 4;
+
+ *list_out = NULL;
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &res)) {
+ return FALSE;
+ }
+ *result = res;
+
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ return TRUE;
+ }
+
+ list = NULL;
+ while (offset < buffer->len) {
+ found = g_new0 (GnomeKeyringFound, 1);
+ list = g_list_prepend (list, found);
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ &found->keyring)) {
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &found->item_id)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ &found->secret)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_decode_attribute_list (buffer, offset, &offset,
+ &found->attributes)) {
+ goto bail;
+ }
+ }
+
+ *list_out = g_list_reverse (list);
+ return TRUE;
+
+ bail:
+ g_list_foreach (list, (GFunc)gnome_keyring_found_free, NULL);
+ return FALSE;
+}
+
+gboolean
+gnome_keyring_proto_decode_find (GString *buffer,
+ GnomeKeyringItemType *type,
+ GnomeKeyringAttributeList **attributes)
+{
+ gsize offset;
+ GnomeKeyringOpCode op;
+ guint32 t;
+
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, &op)) {
+ return FALSE;
+ }
+ if (op != GNOME_KEYRING_OP_FIND) {
+ return FALSE;
+ }
+
+ offset = 8;
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &t)) {
+ return FALSE;
+ }
+ *type = t;
+ return gnome_keyring_proto_decode_attribute_list (buffer,
+ offset, &offset,
+ attributes);
+}
+
+gboolean
+gnome_keyring_proto_decode_op_string (GString *buffer,
+ GnomeKeyringOpCode *op_out,
+ char **str1)
+{
+ gsize offset;
+
+ if (str1 != NULL) {
+ *str1 = NULL;
+ }
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, op_out)) {
+ return FALSE;
+ }
+ offset = 8;
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ str1)) {
+ goto bail;
+ }
+
+ return TRUE;
+ bail:
+ if (str1 != NULL) {
+ g_free (*str1);
+ *str1 = NULL;
+ }
+ return FALSE;
+}
+
+gboolean
+gnome_keyring_proto_decode_op_string_int (GString *buffer,
+ GnomeKeyringOpCode *op_out,
+ char **str1,
+ guint32 *val)
+{
+ gsize offset;
+
+ if (str1 != NULL) {
+ *str1 = NULL;
+ }
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, op_out)) {
+ return FALSE;
+ }
+ offset = 8;
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ str1)) {
+ goto bail;
+ }
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset,
+ val)) {
+ return FALSE;
+ }
+
+ return TRUE;
+ bail:
+ if (str1 != NULL) {
+ g_free (*str1);
+ *str1 = NULL;
+ }
+ return FALSE;
+}
+
+gboolean
+gnome_keyring_proto_decode_get_item_info (GString *buffer,
+ GnomeKeyringOpCode *op_out,
+ char **keyring,
+ guint32 *item_id,
+ guint32 *flags)
+{
+ gsize offset = 8;
+ *keyring = NULL;
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, op_out))
+ return FALSE;
+ if (!gnome_keyring_proto_get_utf8_string (buffer, offset, &offset, keyring))
+ goto bail;
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, item_id))
+ goto bail;
+ if (*op_out == GNOME_KEYRING_OP_GET_ITEM_INFO_FULL) {
+ /* Pull in lookup flags/parts, find out which ones */
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, flags))
+ goto bail;
+ } else {
+ /* All parts of the item by default */
+ *flags = GNOME_KEYRING_ITEM_INFO_ALL;
+ }
+
+ return TRUE;
+ bail:
+ g_free (*keyring);
+ *keyring = NULL;
+ return FALSE;
+}
+
+gboolean
+gnome_keyring_proto_decode_op_string_string (GString *buffer,
+ GnomeKeyringOpCode *op_out,
+ char **str1,
+ char **str2)
+{
+ gsize offset;
+
+ if (str1 != NULL) {
+ *str1 = NULL;
+ }
+ if (str2 != NULL) {
+ *str2 = NULL;
+ }
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, op_out)) {
+ return FALSE;
+ }
+ offset = 8;
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ str1)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ str2)) {
+ goto bail;
+ }
+
+ return TRUE;
+ bail:
+ if (str1 != NULL) {
+ g_free (*str1);
+ *str1 = NULL;
+ }
+ if (str2 != NULL) {
+ g_free (*str2);
+ *str2 = NULL;
+ }
+ return FALSE;
+}
+
+gboolean
+gnome_keyring_proto_decode_op_string_string_string (GString *buffer,
+ GnomeKeyringOpCode *op_out,
+ char **str1,
+ char **str2,
+ char **str3)
+{
+ gsize offset;
+
+ if (str1 != NULL) {
+ *str1 = NULL;
+ }
+ if (str2 != NULL) {
+ *str2 = NULL;
+ }
+ if (str3 != NULL) {
+ *str3 = NULL;
+ }
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, op_out)) {
+ return FALSE;
+ }
+ offset = 8;
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ str1)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ str2)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ str3)) {
+ goto bail;
+ }
+
+ return TRUE;
+ bail:
+ if (str1 != NULL) {
+ g_free (*str1);
+ *str1 = NULL;
+ }
+ if (str2 != NULL) {
+ g_free (*str2);
+ *str2 = NULL;
+ }
+ if (str3 != NULL) {
+ g_free (*str3);
+ *str3 = NULL;
+ }
+ return FALSE;
+}
+
+
+gboolean
+gnome_keyring_proto_decode_get_attributes_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GnomeKeyringAttributeList **attributes)
+{
+ gsize offset;
+ guint32 res;
+
+ offset = 4;
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &res)) {
+ return FALSE;
+ }
+ *attributes = NULL;
+ *result = res;
+ if (res == GNOME_KEYRING_RESULT_OK) {
+ if (!gnome_keyring_proto_decode_attribute_list (buffer,
+ offset, &offset,
+ attributes)) {
+ return FALSE;
+ }
+
+ }
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_decode_get_acl_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GList **acl)
+{
+ gsize offset;
+ guint32 res;
+
+ offset = 4;
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &res)) {
+ return FALSE;
+ }
+ *acl = NULL;
+ *result = res;
+ if (res == GNOME_KEYRING_RESULT_OK) {
+ if (!gnome_keyring_proto_decode_acl (buffer,
+ offset, &offset,
+ acl)) {
+ return FALSE;
+ }
+
+ }
+
+ return TRUE;
+}
+
+
+gboolean
+gnome_keyring_proto_decode_get_item_info_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GnomeKeyringItemInfo **info_out)
+{
+ gsize offset;
+ guint32 res, type;
+ GnomeKeyringItemInfo *info;
+ time_t mtime, ctime;
+ char *name;
+ char *secret;
+
+ info = NULL;
+
+ offset = 4;
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &res)) {
+ return FALSE;
+ }
+ if (res == GNOME_KEYRING_RESULT_OK) {
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset,
+ &type)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ &name)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ &secret)) {
+ g_free (name);
+ return FALSE;
+ }
+
+ if (!gnome_keyring_proto_get_time (buffer, offset, &offset,
+ &mtime)) {
+ g_free (name);
+ gnome_keyring_free_password (secret);
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_get_time (buffer, offset, &offset,
+ &ctime)) {
+ g_free (name);
+ gnome_keyring_free_password (secret);
+ return FALSE;
+ }
+
+ info = g_new (GnomeKeyringItemInfo, 1);
+ info->type = type;
+ info->display_name = name;
+ info->secret = secret;
+ info->mtime = mtime;
+ info->ctime = ctime;
+ }
+
+ *result = res;
+ *info_out = info;
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_decode_get_keyring_info_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GnomeKeyringInfo **info_out)
+{
+ gsize offset;
+ guint32 res;
+ GnomeKeyringInfo *info;
+ guint32 lock_on_idle, lock_timeout, is_locked;
+ time_t mtime, ctime;
+
+ info = NULL;
+
+ offset = 4;
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &res)) {
+ return FALSE;
+ }
+ if (res == GNOME_KEYRING_RESULT_OK) {
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset,
+ &lock_on_idle)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset,
+ &lock_timeout)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_get_time (buffer, offset, &offset,
+ &mtime)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_get_time (buffer, offset, &offset,
+ &ctime)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset,
+ &is_locked)) {
+ return FALSE;
+ }
+ info = g_new (GnomeKeyringInfo, 1);
+ info->lock_on_idle = lock_on_idle;
+ info->lock_timeout = lock_timeout;
+ info->mtime = mtime;
+ info->ctime = ctime;
+ info->is_locked = is_locked;
+ }
+
+ *result = res;
+ *info_out = info;
+
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_decode_set_item_info (GString *buffer,
+ char **keyring,
+ guint32 *item_id,
+ GnomeKeyringItemType *type,
+ char **display_name,
+ char **secret)
+{
+ gsize offset;
+ GnomeKeyringOpCode op;
+ guint32 typeint;
+
+ *keyring = NULL;
+ *display_name = NULL;
+ *secret = NULL;
+
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, &op)) {
+ return FALSE;
+ }
+ if (op != GNOME_KEYRING_OP_SET_ITEM_INFO) {
+ return FALSE;
+ }
+ offset = 8;
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ keyring)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, item_id)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &typeint)) {
+ goto bail;
+ }
+ *type = typeint;
+
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ display_name)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ secret)) {
+ goto bail;
+ }
+
+ return TRUE;
+
+ bail:
+ g_free (*keyring);
+ g_free (*display_name);
+ gnome_keyring_free_password (*secret);
+ return FALSE;
+}
+
+gboolean
+gnome_keyring_proto_decode_set_keyring_info (GString *buffer,
+ char **keyring,
+ gboolean *lock_on_idle,
+ guint32 *lock_timeout)
+
+{
+ gsize offset;
+ GnomeKeyringOpCode op;
+ guint32 lock_int;
+
+ *keyring = NULL;
+
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, &op)) {
+ return FALSE;
+ }
+ if (op != GNOME_KEYRING_OP_SET_KEYRING_INFO) {
+ return FALSE;
+ }
+ offset = 8;
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ keyring)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &lock_int)) {
+ goto bail;
+ }
+ *lock_on_idle = lock_int;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, lock_timeout)) {
+ goto bail;
+ }
+
+ return TRUE;
+
+ bail:
+ g_free (*keyring);
+ return FALSE;
+}
+
+gboolean
+gnome_keyring_proto_decode_set_attributes (GString *buffer,
+ char **keyring,
+ guint32 *item_id,
+ GnomeKeyringAttributeList **attributes)
+{
+ gsize offset;
+ GnomeKeyringOpCode op;
+
+ *keyring = NULL;
+ *attributes = NULL;
+
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, &op)) {
+ return FALSE;
+ }
+ if (op != GNOME_KEYRING_OP_SET_ITEM_ATTRIBUTES) {
+ return FALSE;
+ }
+ offset = 8;
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ keyring)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, item_id)) {
+ goto bail;
+ }
+
+ if (!gnome_keyring_proto_decode_attribute_list (buffer,
+ offset, &offset,
+ attributes)) {
+ goto bail;
+ }
+
+ return TRUE;
+
+ bail:
+ g_free (*keyring);
+ return FALSE;
+}
+
+
+gboolean
+gnome_keyring_proto_decode_set_acl (GString *buffer,
+ char **keyring,
+ guint32 *item_id,
+ GList **acl)
+{
+ gsize offset;
+ GnomeKeyringOpCode op;
+
+ *keyring = NULL;
+ *acl = NULL;
+
+ if (!gnome_keyring_proto_decode_packet_operation (buffer, &op)) {
+ return FALSE;
+ }
+ if (op != GNOME_KEYRING_OP_SET_ITEM_ACL) {
+ return FALSE;
+ }
+ offset = 8;
+ if (!gnome_keyring_proto_get_utf8_string (buffer,
+ offset, &offset,
+ keyring)) {
+ goto bail;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, item_id)) {
+ goto bail;
+ }
+
+ if (!gnome_keyring_proto_decode_acl (buffer,
+ offset, &offset,
+ acl)) {
+ goto bail;
+ }
+
+ return TRUE;
+
+ bail:
+ g_free (*keyring);
+ return FALSE;
+}
+
+
+
+gboolean
+gnome_keyring_proto_decode_result_int_list_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GList **list)
+{
+ gsize offset;
+ guint32 res, len, i, id;
+
+ *list = NULL;
+
+ offset = 4;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &res)) {
+ return FALSE;
+ }
+ *result = res;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &len)) {
+ return FALSE;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &id)) {
+ g_list_free (*list);
+ *list = NULL;
+ return FALSE;
+ }
+ *list = g_list_prepend (*list, GUINT_TO_POINTER (id));
+
+ }
+ *list = g_list_reverse (*list);
+ return TRUE;
+}
+
+gboolean
+gnome_keyring_proto_decode_result_integer_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ guint32 *integer)
+{
+ gsize offset;
+ guint32 res, val;
+
+ offset = 4;
+
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &res)) {
+ return FALSE;
+ }
+ if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &val)) {
+ return FALSE;
+ }
+
+ *result = res;
+ if (integer != NULL) {
+ *integer = val;
+ }
+
+ return TRUE;
+}
+
diff --git a/library/gnome-keyring-proto.h b/library/gnome-keyring-proto.h
new file mode 100644
index 00000000..67d5880d
--- /dev/null
+++ b/library/gnome-keyring-proto.h
@@ -0,0 +1,247 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-keyring-proto.h - helper code for the keyring daemon protocol
+
+ Copyright (C) 2003 Red Hat, Inc
+
+ 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
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Alexander Larsson <alexl@redhat.com>
+*/
+#ifndef GNOME_KEYRING_PROTO_H
+#define GNOME_KEYRING_PROTO_H
+
+#include <stdarg.h>
+#include "gnome-keyring.h"
+
+typedef enum {
+ GNOME_KEYRING_OP_LOCK_ALL,
+ GNOME_KEYRING_OP_SET_DEFAULT_KEYRING,
+ GNOME_KEYRING_OP_GET_DEFAULT_KEYRING,
+ GNOME_KEYRING_OP_LIST_KEYRINGS,
+ GNOME_KEYRING_OP_CREATE_KEYRING,
+ GNOME_KEYRING_OP_LOCK_KEYRING,
+ GNOME_KEYRING_OP_UNLOCK_KEYRING,
+ GNOME_KEYRING_OP_DELETE_KEYRING,
+ GNOME_KEYRING_OP_GET_KEYRING_INFO,
+ GNOME_KEYRING_OP_SET_KEYRING_INFO,
+ GNOME_KEYRING_OP_LIST_ITEMS,
+ GNOME_KEYRING_OP_FIND,
+ GNOME_KEYRING_OP_CREATE_ITEM,
+ GNOME_KEYRING_OP_DELETE_ITEM,
+ GNOME_KEYRING_OP_GET_ITEM_INFO,
+ GNOME_KEYRING_OP_SET_ITEM_INFO,
+ GNOME_KEYRING_OP_GET_ITEM_ATTRIBUTES,
+ GNOME_KEYRING_OP_SET_ITEM_ATTRIBUTES,
+ GNOME_KEYRING_OP_GET_ITEM_ACL,
+ GNOME_KEYRING_OP_SET_ITEM_ACL,
+ GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD,
+ GNOME_KEYRING_OP_SET_DAEMON_DISPLAY,
+ GNOME_KEYRING_OP_GET_ITEM_INFO_FULL,
+
+ /* Add new ops here */
+
+ GNOME_KEYRING_NUM_OPS
+} GnomeKeyringOpCode;
+
+/* request:
+ uint32 package size
+ uint32 operation
+ ... op data
+
+ reply:
+ uint32 reply size
+ uint32 result
+*/
+
+/* Core buffer ops */
+void gnome_keyring_proto_add_uint32 (GString *buffer,
+ guint32 val);
+gboolean gnome_keyring_proto_set_uint32 (GString *buffer,
+ gsize offset,
+ guint32 val);
+gboolean gnome_keyring_proto_get_uint32 (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ guint32 *val);
+gboolean gnome_keyring_proto_get_bytes (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ guchar *out,
+ gsize n_bytes);
+void gnome_keyring_proto_add_time (GString *buffer,
+ time_t val);
+gboolean gnome_keyring_proto_get_time (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ time_t *time);
+gboolean gnome_keyring_proto_add_utf8_string (GString *buffer,
+ const char *str);
+gboolean gnome_keyring_proto_get_utf8_string (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ char **str_ret);
+gboolean gnome_keyring_proto_add_attribute_list (GString *buffer,
+ GnomeKeyringAttributeList *attributes);
+gboolean gnome_keyring_proto_add_acl (GString *buffer,
+ GList *acl);
+
+
+/* marshallers */
+gboolean gnome_keyring_proto_encode_op_only (GString *buffer,
+ GnomeKeyringOpCode op);
+gboolean gnome_keyring_proto_encode_op_string (GString *buffer,
+ GnomeKeyringOpCode op,
+ const char *str);
+gboolean gnome_keyring_proto_encode_op_string_int (GString *buffer,
+ GnomeKeyringOpCode op,
+ const char *str,
+ guint32 integer);
+gboolean gnome_keyring_proto_encode_op_string_int_int (GString *buffer,
+ GnomeKeyringOpCode op,
+ const char *str,
+ guint32 integer1,
+ guint32 integer2);
+gboolean gnome_keyring_proto_encode_op_string_string (GString *buffer,
+ GnomeKeyringOpCode op,
+ const char *str1,
+ const char *str2);
+gboolean gnome_keyring_proto_encode_op_string_string_string (GString *buffer,
+ GnomeKeyringOpCode op,
+ const char *str1,
+ const char *str2,
+ const char *str3);
+gboolean gnome_keyring_proto_encode_find (GString *buffer,
+ GnomeKeyringItemType type,
+ GnomeKeyringAttributeList *attributes);
+gboolean gnome_keyring_proto_encode_create_item (GString *buffer,
+ const char *keyring,
+ const char *display_name,
+ GnomeKeyringAttributeList *attributes,
+ const char *secret,
+ GnomeKeyringItemType type,
+ gboolean update_if_exists);
+gboolean gnome_keyring_proto_encode_set_attributes (GString *buffer,
+ const char *keyring,
+ guint32 id,
+ GnomeKeyringAttributeList *attributes);
+gboolean gnome_keyring_proto_encode_set_acl (GString *buffer,
+ const char *keyring,
+ guint32 id,
+ GList *acl);
+gboolean gnome_keyring_proto_encode_set_item_info (GString *buffer,
+ const char *keyring,
+ guint32 id,
+ GnomeKeyringItemInfo *info);
+gboolean gnome_keyring_proto_encode_set_keyring_info (GString *buffer,
+ const char *keyring,
+ GnomeKeyringInfo *info);
+
+
+/* demarshallers */
+gboolean gnome_keyring_proto_decode_packet_operation (GString *buffer,
+ GnomeKeyringOpCode *op);
+gboolean gnome_keyring_proto_decode_packet_size (GString *buffer,
+ guint32 *size);
+gboolean gnome_keyring_proto_decode_attribute_list (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ GnomeKeyringAttributeList **attributes_out);
+gboolean gnome_keyring_proto_decode_acl (GString *buffer,
+ gsize offset,
+ gsize *next_offset,
+ GList **attributes_out);
+gboolean gnome_keyring_proto_decode_result_reply (GString *buffer,
+ GnomeKeyringResult *result);
+gboolean gnome_keyring_proto_decode_result_string_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ char **str);
+gboolean gnome_keyring_proto_decode_result_string_list_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GList **list);
+gboolean gnome_keyring_proto_decode_op_string (GString *buffer,
+ GnomeKeyringOpCode *op_out,
+ char **str_out);
+gboolean gnome_keyring_proto_decode_op_string_string (GString *buffer,
+ GnomeKeyringOpCode *op_out,
+ char **str1_out,
+ char **str2_out);
+gboolean gnome_keyring_proto_decode_op_string_string_string (GString *buffer,
+ GnomeKeyringOpCode *op_out,
+ char **str1_out,
+ char **str2_out,
+ char **str3_out);
+gboolean gnome_keyring_proto_decode_op_string_int (GString *buffer,
+ GnomeKeyringOpCode *op_out,
+ char **str1,
+ guint32 *val);
+gboolean gnome_keyring_proto_decode_get_item_info (GString *buffer,
+ GnomeKeyringOpCode *op_out,
+ char **keyring,
+ guint32 *item_id,
+ guint32 *flags);
+gboolean gnome_keyring_proto_decode_find (GString *buffer,
+ GnomeKeyringItemType *type,
+ GnomeKeyringAttributeList **attributes);
+gboolean gnome_keyring_proto_decode_find_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GList **list_out);
+gboolean gnome_keyring_proto_decode_get_attributes_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GnomeKeyringAttributeList **attributes);
+gboolean gnome_keyring_proto_decode_get_acl_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GList **acl);
+gboolean gnome_keyring_proto_decode_get_item_info_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GnomeKeyringItemInfo **info);
+gboolean gnome_keyring_proto_decode_get_keyring_info_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GnomeKeyringInfo **info);
+gboolean gnome_keyring_proto_decode_result_int_list_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ GList **list);
+gboolean gnome_keyring_proto_decode_result_integer_reply (GString *buffer,
+ GnomeKeyringResult *result,
+ guint32 *integer);
+gboolean gnome_keyring_proto_decode_create_item (GString *packet,
+ char **keyring,
+ char **display_name,
+ GnomeKeyringAttributeList **attributes,
+ char **secret,
+ GnomeKeyringItemType *type_out,
+ gboolean *update_if_exists);
+gboolean gnome_keyring_proto_decode_set_item_info (GString *buffer,
+ char **keyring,
+ guint32 *item_id,
+ GnomeKeyringItemType *type,
+ char **display_name,
+ char **secret);
+gboolean gnome_keyring_proto_decode_set_keyring_info (GString *buffer,
+ char **keyring,
+ gboolean *lock_on_idle,
+ guint32 *lock_timeout);
+gboolean gnome_keyring_proto_decode_set_attributes (GString *buffer,
+ char **keyring,
+ guint32 *item_id,
+ GnomeKeyringAttributeList **attributes);
+gboolean gnome_keyring_proto_decode_set_acl (GString *buffer,
+ char **keyring,
+ guint32 *item_id,
+ GList **acl);
+
+
+
+#endif /* GNOME_KEYRING_PROTO_H */
diff --git a/library/gnome-keyring-utils.c b/library/gnome-keyring-utils.c
new file mode 100644
index 00000000..c802ca02
--- /dev/null
+++ b/library/gnome-keyring-utils.c
@@ -0,0 +1,270 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-keyring-proto.c - shared utility functions
+
+ Copyright (C) 2003 Red Hat, Inc
+
+ 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
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Alexander Larsson <alexl@redhat.com>
+*/
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+
+#include "gnome-keyring-private.h"
+
+/* Functions used by both the library and the daemon */
+
+/**
+ * gnome_keyring_free_password():
+ * @str: the password to be freed
+ *
+ * Clears the memory used by password by filling with '\0' and frees the memory
+ * after doing this. You should use this function instead of g_free() for
+ * secret information.
+ */
+void
+gnome_keyring_free_password (char *str)
+{
+ if (str != NULL) {
+ memset (str, 0, strlen (str));
+ g_free (str);
+ }
+}
+
+/**
+ * gnome_keyring_found_free():
+ * @found: a #GnomeKeyringFound
+ *
+ * Free the memory used by a #GnomeKeyringFound item.
+ *
+ * You usually want to use gnome_keyring_found_list_free() on the list of
+ * results.
+ */
+void
+gnome_keyring_found_free (GnomeKeyringFound *found)
+{
+ g_free (found->keyring);
+ g_free (found->secret);
+ gnome_keyring_attribute_list_free (found->attributes);
+ g_free (found);
+}
+
+/**
+ * gnome_keyring_found_list_free():
+ * @found_list: a #GList of #GnomeKeyringFound
+ *
+ * Free the memory used by the #GnomeKeyringFound items in @found_list.
+ */
+void
+gnome_keyring_found_list_free (GList *found_list)
+{
+ g_list_foreach (found_list, (GFunc) gnome_keyring_found_free, NULL);
+ g_list_free (found_list);
+}
+
+/**
+ * gnome_keyring_attribute_list_free():
+ * @attributes: a #GnomeKeyringAttributeList
+ *
+ * Free the memory used by @attributes.
+ */
+void
+gnome_keyring_attribute_list_free (GnomeKeyringAttributeList *attributes)
+{
+ GnomeKeyringAttribute *array;
+ int i;
+
+ if (attributes == NULL) {
+ return;
+ }
+
+ array = (GnomeKeyringAttribute *)attributes->data;
+ for (i = 0; i < attributes->len; i++) {
+ g_free (array[i].name);
+ if (array[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
+ g_free (array[i].value.string);
+ }
+ }
+
+ g_array_free (attributes, TRUE);
+}
+
+GnomeKeyringAttributeList *
+gnome_keyring_attribute_list_copy (GnomeKeyringAttributeList *attributes)
+{
+ GnomeKeyringAttribute *array;
+ GnomeKeyringAttributeList *copy;
+ int i;
+
+ if (attributes == NULL) {
+ return NULL;
+ }
+
+ copy = g_array_sized_new (FALSE, FALSE, sizeof (GnomeKeyringAttribute), attributes->len);
+
+ copy->len = attributes->len;
+ memcpy (copy->data, attributes->data, sizeof (GnomeKeyringAttribute) * attributes->len);
+
+ array = (GnomeKeyringAttribute *)copy->data;
+ for (i = 0; i < copy->len; i++) {
+ array[i].name = g_strdup (array[i].name);
+ if (array[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
+ array[i].value.string = g_strdup (array[i].value.string);
+ }
+ }
+ return copy;
+}
+
+void
+gnome_keyring_info_free (GnomeKeyringInfo *keyring_info)
+{
+ g_free (keyring_info);
+}
+
+GnomeKeyringInfo *
+gnome_keyring_info_copy (GnomeKeyringInfo *keyring_info)
+{
+ GnomeKeyringInfo *copy;
+
+ copy = g_new (GnomeKeyringInfo, 1);
+ memcpy (copy, keyring_info, sizeof (GnomeKeyringInfo));
+
+ return copy;
+}
+
+
+void
+gnome_keyring_item_info_free (GnomeKeyringItemInfo *item_info)
+{
+ if (item_info != NULL) {
+ g_free (item_info->display_name);
+ if (item_info->secret != NULL) {
+ /* clear the secret on free */
+ memset (item_info->secret, 0, strlen (item_info->secret));
+ g_free (item_info->secret);
+ }
+ g_free (item_info);
+ }
+}
+
+GnomeKeyringItemInfo *
+gnome_keyring_item_info_new (void)
+{
+ GnomeKeyringItemInfo *info;
+
+ info = g_new0 (GnomeKeyringItemInfo, 1);
+
+ info->type = GNOME_KEYRING_ITEM_NO_TYPE;
+
+ return info;
+}
+
+GnomeKeyringItemInfo *
+gnome_keyring_item_info_copy (GnomeKeyringItemInfo *item_info)
+{
+ GnomeKeyringItemInfo *copy;
+
+ copy = g_new (GnomeKeyringItemInfo, 1);
+ memcpy (copy, item_info, sizeof (GnomeKeyringItemInfo));
+
+ copy->display_name = g_strdup (copy->display_name);
+ copy->secret = g_strdup (copy->secret);
+
+ return copy;
+}
+
+GnomeKeyringApplicationRef *
+gnome_keyring_application_ref_new (void)
+{
+ GnomeKeyringApplicationRef *app_ref;
+
+ app_ref = g_new0 (GnomeKeyringApplicationRef, 1);
+
+ return app_ref;
+}
+
+void
+gnome_keyring_application_ref_free (GnomeKeyringApplicationRef *app_ref)
+{
+ g_free (app_ref->display_name);
+ g_free (app_ref->pathname);
+ g_free (app_ref);
+}
+
+GnomeKeyringApplicationRef *
+gnome_keyring_application_ref_copy (const GnomeKeyringApplicationRef *app)
+{
+ GnomeKeyringApplicationRef *copy;
+
+ copy = g_new (GnomeKeyringApplicationRef, 1);
+ copy->display_name = g_strdup (app->display_name);
+ copy->pathname = g_strdup (app->pathname);
+
+ return copy;
+}
+
+GnomeKeyringAccessControl *
+gnome_keyring_access_control_new (const GnomeKeyringApplicationRef *application,
+ GnomeKeyringAccessType types_allowed)
+{
+ GnomeKeyringAccessControl *ac;
+ ac = g_new (GnomeKeyringAccessControl, 1);
+
+ ac->application = gnome_keyring_application_ref_copy (application);
+ ac->types_allowed = types_allowed;
+
+ return ac;
+}
+
+void
+gnome_keyring_access_control_free (GnomeKeyringAccessControl *ac)
+{
+ gnome_keyring_application_ref_free (ac->application);
+ g_free (ac);
+}
+
+GnomeKeyringAccessControl *
+gnome_keyring_access_control_copy (GnomeKeyringAccessControl *ac)
+{
+ GnomeKeyringAccessControl *ret;
+
+ ret = gnome_keyring_access_control_new (gnome_keyring_application_ref_copy (ac->application), ac->types_allowed);
+
+ return ret;
+}
+
+GList *
+gnome_keyring_acl_copy (GList *list)
+{
+ GList *ret, *l;
+
+ ret = g_list_copy (list);
+ for (l = ret; l != NULL; l = l->next) {
+ l->data = gnome_keyring_access_control_copy (l->data);
+ }
+
+ return ret;
+}
+
+void
+gnome_keyring_acl_free (GList *acl)
+{
+ g_list_foreach (acl, (GFunc)gnome_keyring_access_control_free, NULL);
+ g_list_free (acl);
+}
+
diff --git a/library/gnome-keyring.c b/library/gnome-keyring.c
new file mode 100644
index 00000000..000089c8
--- /dev/null
+++ b/library/gnome-keyring.c
@@ -0,0 +1,2825 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-keyring.c - library for talking to the keyring daemon.
+
+ Copyright (C) 2003 Red Hat, Inc
+
+ 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
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Alexander Larsson <alexl@redhat.com>
+*/
+
+#include "config.h"
+
+#include "gnome-keyring.h"
+#include "gnome-keyring-private.h"
+#include "gnome-keyring-proto.h"
+
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <stdarg.h>
+
+#ifdef WITH_DBUS
+#include <dbus/dbus.h>
+#endif
+
+typedef enum {
+ CALLBACK_DONE,
+ CALLBACK_GET_STRING,
+ CALLBACK_GET_INT,
+ CALLBACK_GET_LIST,
+ CALLBACK_GET_KEYRING_INFO,
+ CALLBACK_GET_ITEM_INFO,
+ CALLBACK_GET_ATTRIBUTES,
+ CALLBACK_GET_ACL
+} KeyringCallbackType;
+
+typedef enum {
+ STATE_FAILED,
+ STATE_WRITING_CREDS,
+ STATE_WRITING_PACKET,
+ STATE_READING_REPLY
+} KeyringState;
+
+typedef struct GnomeKeyringOperation GnomeKeyringOperation;
+
+typedef void (*KeyringHandleReply) (GnomeKeyringOperation *op);
+
+struct GnomeKeyringOperation {
+ int socket;
+
+ KeyringState state;
+ GnomeKeyringResult result;
+
+ guint io_watch;
+
+ GString *send_buffer;
+ gsize send_pos;
+
+ GString *receive_buffer;
+ gsize receive_pos;
+
+ KeyringCallbackType user_callback_type;
+ gpointer user_callback;
+ gpointer user_data;
+ GDestroyNotify destroy_user_data;
+
+ KeyringHandleReply reply_handler;
+};
+
+#ifdef WITH_DBUS
+
+static gchar*
+find_daemon_via_dbus ()
+{
+ DBusConnection *dconn;
+ DBusMessage *reply;
+ DBusMessage *msg;
+ DBusMessageIter args;
+ DBusError derr;
+ char* socket = NULL;
+
+ dbus_error_init (&derr);
+ dconn = dbus_bus_get (DBUS_BUS_SESSION, &derr);
+ if (!dconn) {
+ g_warning ("couldn't connect to dbus session bus: %s", derr.message);
+ return NULL;
+ }
+
+ msg = dbus_message_new_method_call (GNOME_KEYRING_DAEMON_SERVICE,
+ GNOME_KEYRING_DAEMON_PATH,
+ GNOME_KEYRING_DAEMON_INTERFACE,
+ "GetSocketPath");
+ if (!msg) {
+ g_warning ("couldn't create dbus message");
+ dbus_connection_unref (dconn);
+ return NULL;
+ }
+
+ /* Send message and get a handle for a reply */
+ reply = dbus_connection_send_with_reply_and_block (dconn, msg, 1000, &derr);
+ dbus_message_unref (msg);
+ if (!reply) {
+ g_warning ("couldn't communicate with gnome keyring daemon via dbus: %s", derr.message);
+ dbus_connection_unref (dconn);
+ return NULL;
+ }
+
+ /* Read the return value */
+ if (!dbus_message_iter_init(reply, &args) ||
+ dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) {
+ g_warning ("gnome-keyring-daemon sent back an invalid reply");
+ } else {
+ dbus_message_iter_get_basic(&args, &socket);
+ socket = g_strdup (socket);
+ }
+
+ dbus_message_unref (reply);
+ dbus_connection_unref (dconn);
+
+ return socket;
+}
+
+#endif
+
+static int
+connect_to_daemon_at (const gchar *path)
+{
+ struct sockaddr_un addr;
+ int sock;
+
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, path, sizeof (addr.sun_path));
+
+ sock = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ return -1;
+ }
+
+ /* close on exec */
+ if (fcntl (sock, F_SETFD, 1) == -1) {
+ close (sock);
+ return -1;
+ }
+
+ if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
+ close (sock);
+ return -1;
+ }
+
+ return sock;
+}
+
+static int
+connect_to_daemon (gboolean non_blocking)
+{
+ const gchar *epath = NULL;
+ int sock = -1;
+ int val;
+
+ /* Try using the environment variable */
+ epath = g_getenv ("GNOME_KEYRING_SOCKET");
+ if (epath && epath[0]) {
+ sock = connect_to_daemon_at (epath);
+ if (sock < 0) {
+ g_warning ("couldn't connect to daemon at $GNOME_KEYRING_SOCKET: %s: %s",
+ epath, g_strerror (errno));
+ }
+ }
+
+#ifdef WITH_DBUS
+ /* Try using DBus to find daemon */
+ if (sock < 0) {
+ gchar *dpath = find_daemon_via_dbus ();
+ if (dpath) {
+ sock = connect_to_daemon_at (dpath);
+ g_free (dpath);
+ if (sock < 0) {
+ g_warning ("couldn't connect to daemon at DBus discovered socket: %s: %s",
+ dpath, g_strerror (errno));
+ }
+ }
+ }
+#endif
+
+ if (sock < 0)
+ return -1;
+
+ /* Setup non blocking */
+ if (non_blocking) {
+ val = fcntl (sock, F_GETFL, 0);
+ if (val < 0) {
+ close (sock);
+ return -1;
+ }
+
+ if (fcntl (sock, F_SETFL, val | O_NONBLOCK) < 0) {
+ close (sock);
+ return -1;
+ }
+ }
+
+ return sock;
+}
+
+
+static void
+gnome_keyring_operation_free (GnomeKeyringOperation *op)
+{
+ if (op->io_watch != 0) {
+ g_source_remove (op->io_watch);
+ op->io_watch = 0;
+ }
+ if (op->destroy_user_data != NULL) {
+ (*op->destroy_user_data) (op->user_data);
+ }
+ if (op->send_buffer != NULL) {
+ g_string_free (op->send_buffer, TRUE);
+ }
+ if (op->receive_buffer != NULL) {
+ g_string_free (op->receive_buffer, TRUE);
+ }
+ close (op->socket);
+ g_free (op);
+}
+
+static gboolean
+op_failed (gpointer data)
+{
+ GnomeKeyringOperation *op;
+
+ op = data;
+
+ switch (op->user_callback_type) {
+ case CALLBACK_DONE:
+ ((GnomeKeyringOperationDoneCallback)op->user_callback) (op->result, op->user_data);
+ break;
+ case CALLBACK_GET_STRING:
+ ((GnomeKeyringOperationGetStringCallback)op->user_callback) (op->result, NULL, op->user_data);
+ break;
+ case CALLBACK_GET_INT:
+ ((GnomeKeyringOperationGetIntCallback)op->user_callback) (op->result, 0, op->user_data);
+ break;
+ case CALLBACK_GET_LIST:
+ ((GnomeKeyringOperationGetListCallback)op->user_callback) (op->result, NULL, op->user_data);
+ break;
+ case CALLBACK_GET_KEYRING_INFO:
+ ((GnomeKeyringOperationGetKeyringInfoCallback)op->user_callback) (op->result, NULL, op->user_data);
+ break;
+ case CALLBACK_GET_ITEM_INFO:
+ ((GnomeKeyringOperationGetItemInfoCallback)op->user_callback) (op->result, NULL, op->user_data);
+ break;
+ case CALLBACK_GET_ATTRIBUTES:
+ ((GnomeKeyringOperationGetAttributesCallback)op->user_callback) (op->result, NULL, op->user_data);
+ break;
+ case CALLBACK_GET_ACL:
+ ((GnomeKeyringOperationGetListCallback)op->user_callback) (op->result, NULL, op->user_data);
+ break;
+ }
+
+ gnome_keyring_operation_free (op);
+
+ return FALSE;
+}
+
+
+static void
+schedule_op_failed (GnomeKeyringOperation *op,
+ GnomeKeyringResult result)
+{
+ if (op->io_watch != 0) {
+ g_source_remove (op->io_watch);
+ op->io_watch = 0;
+ }
+ op->state = STATE_FAILED;
+ op->result = result;
+ g_idle_add (op_failed, op);
+}
+
+static int
+read_all (int fd, char *buf, size_t len)
+{
+ size_t bytes;
+ ssize_t res;
+
+ bytes = 0;
+ while (bytes < len) {
+ res = read (fd, buf + bytes, len - bytes);
+ if (res <= 0) {
+ if (res == 0)
+ res = -1;
+ return res;
+ }
+ bytes += res;
+ }
+ return 0;
+}
+
+
+static int
+write_all (int fd, const char *buf, size_t len)
+{
+ size_t bytes;
+ ssize_t res;
+
+ bytes = 0;
+ while (bytes < len) {
+ res = write (fd, buf + bytes, len - bytes);
+ if (res < 0) {
+ if (errno != EINTR &&
+ errno != EAGAIN) {
+ perror ("write_all write failure:");
+ return -1;
+ }
+ } else {
+ bytes += res;
+ }
+ }
+ return 0;
+}
+
+static GnomeKeyringResult
+write_credentials_byte_sync (int socket)
+{
+ char buf;
+ int bytes_written;
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+ union {
+ struct cmsghdr hdr;
+ char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
+ } cmsg;
+ struct iovec iov;
+ struct msghdr msg;
+#endif
+
+ buf = 0;
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+ iov.iov_base = &buf;
+ iov.iov_len = 1;
+
+ memset (&msg, 0, sizeof (msg));
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ msg.msg_control = (caddr_t) &cmsg;
+ msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
+ memset (&cmsg, 0, sizeof (cmsg));
+ cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
+ cmsg.hdr.cmsg_level = SOL_SOCKET;
+ cmsg.hdr.cmsg_type = SCM_CREDS;
+#endif
+
+ again:
+
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+ bytes_written = sendmsg (socket, &msg, 0);
+#else
+ bytes_written = write (socket, &buf, 1);
+#endif
+
+ if (bytes_written < 0 && errno == EINTR)
+ goto again;
+
+ if (bytes_written <= 0) {
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ } else {
+ return GNOME_KEYRING_RESULT_OK;
+ }
+}
+
+
+static void
+write_credentials_byte (GnomeKeyringOperation *op)
+{
+ char buf;
+ int bytes_written;
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+ union {
+ struct cmsghdr hdr;
+ char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
+ } cmsg;
+ struct iovec iov;
+ struct msghdr msg;
+#endif
+
+ buf = 0;
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+ iov.iov_base = &buf;
+ iov.iov_len = 1;
+
+ memset (&msg, 0, sizeof (msg));
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ msg.msg_control = (caddr_t) &cmsg;
+ msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
+ memset (&cmsg, 0, sizeof (cmsg));
+ cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
+ cmsg.hdr.cmsg_level = SOL_SOCKET;
+ cmsg.hdr.cmsg_type = SCM_CREDS;
+#endif
+
+ again:
+
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+ bytes_written = sendmsg (op->socket, &msg, 0);
+#else
+ bytes_written = write (op->socket, &buf, 1);
+#endif
+
+ if (bytes_written < 0 && errno == EINTR)
+ goto again;
+
+ if (bytes_written <= 0) {
+ if (errno == EAGAIN) {
+ return;
+ }
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_IO_ERROR);
+ return;
+ } else {
+ op->state = STATE_WRITING_PACKET;
+ return;
+ }
+}
+
+
+
+static gboolean
+operation_io (GIOChannel *io_channel,
+ GIOCondition cond,
+ gpointer callback_data)
+{
+ GIOChannel *channel;
+ GnomeKeyringOperation *op;
+ int res;
+ guint32 packet_size;
+
+ op = callback_data;
+
+ if (cond & G_IO_HUP && !(cond & G_IO_IN)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_IO_ERROR);
+ }
+
+ if (op->state == STATE_WRITING_CREDS && (cond & G_IO_OUT)) {
+ write_credentials_byte (op);
+ }
+ if (op->state == STATE_WRITING_PACKET && (cond & G_IO_OUT)) {
+ res = write (op->socket,
+ op->send_buffer->str + op->send_pos,
+ op->send_buffer->len - op->send_pos);
+ if (res <= 0) {
+ if (errno != EAGAIN &&
+ errno != EINTR) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_IO_ERROR);
+ }
+ } else {
+ op->send_pos += res;
+
+ if (op->send_pos == op->send_buffer->len) {
+ op->state = STATE_READING_REPLY;
+ op->receive_buffer = g_string_new (NULL);
+ op->receive_pos = 0;
+
+ g_source_remove (op->io_watch);
+ channel = g_io_channel_unix_new (op->socket);
+ op->io_watch = g_io_add_watch (channel,
+ G_IO_IN | G_IO_HUP,
+ operation_io, op);
+ g_io_channel_unref (channel);
+ }
+ }
+ }
+
+ if (op->state == STATE_READING_REPLY && (cond & G_IO_IN)) {
+ if (op->receive_pos < 4) {
+ g_string_set_size (op->receive_buffer, 4);
+ res = read (op->socket,
+ op->receive_buffer->str + op->receive_pos,
+ 4 - op->receive_pos);
+ if (res <= 0) {
+ if (errno != EAGAIN &&
+ errno != EINTR) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_IO_ERROR);
+ }
+ } else {
+ op->receive_pos += res;
+ }
+ }
+
+ if (op->receive_pos >= 4) {
+ if (!gnome_keyring_proto_decode_packet_size (op->receive_buffer,
+ &packet_size) ||
+ packet_size < 4) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_IO_ERROR);
+ }
+
+ g_assert (op->receive_pos <= packet_size);
+ g_string_set_size (op->receive_buffer, packet_size);
+
+ res = read (op->socket, op->receive_buffer->str + op->receive_pos,
+ packet_size - op->receive_pos);
+ if (res <= 0) {
+ if (errno != EAGAIN &&
+ errno != EINTR) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_IO_ERROR);
+ }
+ } else {
+ op->receive_pos += res;
+
+ if (op->receive_pos == packet_size) {
+ g_source_remove (op->io_watch);
+ op->io_watch = 0;
+ op->result = GNOME_KEYRING_RESULT_OK;
+
+ (*op->reply_handler) (op);
+ gnome_keyring_operation_free (op);
+ }
+ }
+ }
+ }
+
+
+ return TRUE;
+}
+
+
+static GnomeKeyringOperation *
+start_operation (gpointer callback, KeyringCallbackType callback_type,
+ gpointer user_data, GDestroyNotify destroy_user_data)
+{
+ GnomeKeyringOperation *op;
+ GIOChannel *channel;
+
+ op = g_new0 (GnomeKeyringOperation, 1);
+
+ /* Start in failed mode */
+ op->state = STATE_FAILED;
+ op->result = GNOME_KEYRING_RESULT_OK;
+
+ op->user_callback_type = callback_type;
+ op->user_callback = callback;
+ op->user_data = user_data;
+ op->destroy_user_data = destroy_user_data;
+
+ op->socket = connect_to_daemon (TRUE);
+
+ if (op->socket < 0) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON);
+ } else {
+ op->state = STATE_WRITING_CREDS;
+ op->send_buffer = g_string_new (NULL);
+ op->send_pos = 0;
+
+ channel = g_io_channel_unix_new (op->socket);
+ op->io_watch = g_io_add_watch (channel,
+ G_IO_OUT | G_IO_HUP,
+ operation_io, op);
+ g_io_channel_unref (channel);
+ }
+
+ return op;
+}
+
+static GnomeKeyringResult
+run_sync_operation (GString *buffer,
+ GString *receive_buffer)
+{
+ GnomeKeyringResult res;
+ int socket;
+ guint32 packet_size;
+
+ g_assert (buffer != NULL);
+ g_assert (receive_buffer != NULL);
+
+ socket = connect_to_daemon (FALSE);
+ if (socket < 0) {
+ return GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON;
+ }
+ res = write_credentials_byte_sync (socket);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ close (socket);
+ return res;
+ }
+
+ if (write_all (socket,
+ buffer->str, buffer->len) < 0) {
+ close (socket);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+
+ g_string_set_size (receive_buffer, 4);
+ if (read_all (socket, receive_buffer->str, 4) < 0) {
+ close (socket);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+
+ if (!gnome_keyring_proto_decode_packet_size (receive_buffer,
+ &packet_size) ||
+ packet_size < 4) {
+ close (socket);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+
+ g_string_set_size (receive_buffer, packet_size);
+ if (read_all (socket, receive_buffer->str + 4, packet_size - 4) < 0) {
+ close (socket);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ close (socket);
+
+ return GNOME_KEYRING_RESULT_OK;
+}
+
+/**
+ * gnome_keyring_is_available():
+ *
+ * Check whether you can communicate with a Gnome Keyring Daemon.
+ *
+ * Returns %FALSE if you can't communicate with the daemon (so you can't load
+ * and save passwords).
+ */
+gboolean
+gnome_keyring_is_available (void)
+{
+ int socket;
+
+ socket = connect_to_daemon (FALSE);
+ if (socket < 0) {
+ return FALSE;
+ }
+ close (socket);
+ return TRUE;
+}
+
+
+void
+gnome_keyring_cancel_request (gpointer request)
+{
+ GnomeKeyringOperation *op;
+
+ op = request;
+
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_CANCELLED);
+}
+
+static void
+gnome_keyring_standard_reply (GnomeKeyringOperation *op)
+{
+ GnomeKeyringResult result;
+ GnomeKeyringOperationDoneCallback callback;
+
+ g_assert (op->user_callback_type == CALLBACK_DONE);
+
+ callback = op->user_callback;
+
+ if (!gnome_keyring_proto_decode_result_reply (op->receive_buffer, &result)) {
+ (*callback) (GNOME_KEYRING_RESULT_IO_ERROR, op->user_data);
+ } else {
+ (*callback) (result, op->user_data);
+ }
+}
+
+static void
+gnome_keyring_string_reply (GnomeKeyringOperation *op)
+{
+ GnomeKeyringResult result;
+ GnomeKeyringOperationGetStringCallback callback;
+ char *string;
+
+ g_assert (op->user_callback_type == CALLBACK_GET_STRING);
+
+ callback = op->user_callback;
+
+ if (!gnome_keyring_proto_decode_result_string_reply (op->receive_buffer, &result, &string)) {
+ (*callback) (GNOME_KEYRING_RESULT_IO_ERROR, NULL, op->user_data);
+ } else {
+ (*callback) (result, string, op->user_data);
+ g_free (string);
+ }
+}
+
+static void
+gnome_keyring_int_reply (GnomeKeyringOperation *op)
+{
+ GnomeKeyringResult result;
+ GnomeKeyringOperationGetIntCallback callback;
+ guint32 integer;
+
+ g_assert (op->user_callback_type == CALLBACK_GET_INT);
+
+ callback = op->user_callback;
+
+ if (!gnome_keyring_proto_decode_result_integer_reply (op->receive_buffer, &result, &integer)) {
+ (*callback) (GNOME_KEYRING_RESULT_IO_ERROR, 0, op->user_data);
+ } else {
+ (*callback) (result, integer, op->user_data);
+ }
+}
+
+gpointer
+gnome_keyring_set_default_keyring (const char *keyring,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string (op->send_buffer,
+ GNOME_KEYRING_OP_SET_DEFAULT_KEYRING,
+ keyring)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_set_default_keyring_sync (const char *keyring)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_op_string (send,
+ GNOME_KEYRING_OP_SET_DEFAULT_KEYRING,
+ keyring)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_reply (receive, &res)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_get_default_keyring (GnomeKeyringOperationGetStringCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_GET_STRING, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_only (op->send_buffer,
+ GNOME_KEYRING_OP_GET_DEFAULT_KEYRING)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_string_reply;
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_get_default_keyring_sync (char **keyring)
+{
+ GString *send;
+ GString *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ *keyring = NULL;
+
+ if (!gnome_keyring_proto_encode_op_only (send,
+ GNOME_KEYRING_OP_GET_DEFAULT_KEYRING)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_string_reply (receive, &res, keyring)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+static void
+gnome_keyring_list_keyring_names_reply (GnomeKeyringOperation *op)
+{
+ GnomeKeyringResult result;
+ GnomeKeyringOperationGetListCallback callback;
+ GList *names;
+
+ callback = op->user_callback;
+
+ if (!gnome_keyring_proto_decode_result_string_list_reply (op->receive_buffer, &result, &names)) {
+ (*callback) (GNOME_KEYRING_RESULT_IO_ERROR, NULL, op->user_data);
+ } else {
+ (*callback) (result, names, op->user_data);
+ g_list_foreach (names, (GFunc) g_free, NULL);
+ g_list_free (names);
+ }
+}
+
+gpointer
+gnome_keyring_list_keyring_names (GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_GET_LIST, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_only (op->send_buffer,
+ GNOME_KEYRING_OP_LIST_KEYRINGS)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_list_keyring_names_reply;
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_list_keyring_names_sync (GList **keyrings)
+{
+ GString *send;
+ GString *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ *keyrings = NULL;
+
+ if (!gnome_keyring_proto_encode_op_only (send,
+ GNOME_KEYRING_OP_LIST_KEYRINGS)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_string_list_reply (receive, &res, keyrings)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_lock_all (GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_only (op->send_buffer,
+ GNOME_KEYRING_OP_LOCK_ALL)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_lock_all_sync (void)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_op_only (send,
+ GNOME_KEYRING_OP_LOCK_ALL)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_reply (receive, &res)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+
+
+/* NULL password means ask user */
+gpointer
+gnome_keyring_create (const char *keyring_name,
+ const char *password,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string_string (op->send_buffer,
+ GNOME_KEYRING_OP_CREATE_KEYRING,
+ keyring_name, password)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_create_sync (const char *keyring_name,
+ const char *password)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_op_string_string (send,
+ GNOME_KEYRING_OP_CREATE_KEYRING,
+ keyring_name, password)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_reply (receive, &res)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_unlock (const char *keyring,
+ const char *password,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string_string (op->send_buffer,
+ GNOME_KEYRING_OP_UNLOCK_KEYRING,
+ keyring, password)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_unlock_sync (const char *keyring,
+ const char *password)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_op_string_string (send,
+ GNOME_KEYRING_OP_UNLOCK_KEYRING,
+ keyring, password)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_reply (receive, &res)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_lock (const char *keyring,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string (op->send_buffer,
+ GNOME_KEYRING_OP_LOCK_KEYRING,
+ keyring)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_lock_sync (const char *keyring)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_op_string (send,
+ GNOME_KEYRING_OP_LOCK_KEYRING,
+ keyring)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_reply (receive, &res)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_delete (const char *keyring,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string (op->send_buffer,
+ GNOME_KEYRING_OP_DELETE_KEYRING,
+ keyring)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_delete_sync (const char *keyring)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_op_string (send,
+ GNOME_KEYRING_OP_DELETE_KEYRING,
+ keyring)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_reply (receive, &res)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_change_password (const char *keyring,
+ const char *original,
+ const char *password,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string_string_string (op->send_buffer,
+ GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD,
+ keyring, original, password)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_change_password_sync (const char *keyring_name,
+ const char *original, const char *password)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_op_string_string_string (send,
+ GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD,
+ keyring_name, original, password)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_reply (receive, &res)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+static void
+gnome_keyring_get_keyring_info_reply (GnomeKeyringOperation *op)
+{
+ GnomeKeyringResult result;
+ GnomeKeyringOperationGetKeyringInfoCallback callback;
+ GnomeKeyringInfo *info;
+
+ callback = op->user_callback;
+
+ if (!gnome_keyring_proto_decode_get_keyring_info_reply (op->receive_buffer, &result, &info)) {
+ (*callback) (GNOME_KEYRING_RESULT_IO_ERROR, NULL, op->user_data);
+ } else {
+ (*callback) (result, info, op->user_data);
+ gnome_keyring_info_free (info);
+ }
+}
+
+gpointer
+gnome_keyring_get_info (const char *keyring,
+ GnomeKeyringOperationGetKeyringInfoCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_GET_KEYRING_INFO, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string (op->send_buffer,
+ GNOME_KEYRING_OP_GET_KEYRING_INFO,
+ keyring)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_get_keyring_info_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_get_info_sync (const char *keyring,
+ GnomeKeyringInfo **info)
+{
+ GString *send;
+ GString *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ *info = NULL;
+
+ if (!gnome_keyring_proto_encode_op_string (send,
+ GNOME_KEYRING_OP_GET_KEYRING_INFO,
+ keyring)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_get_keyring_info_reply (receive, &res, info)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_set_info (const char *keyring,
+ GnomeKeyringInfo *info,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_set_keyring_info (op->send_buffer,
+ keyring, info)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_set_info_sync (const char *keyring,
+ GnomeKeyringInfo *info)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_set_keyring_info (send,
+ keyring, info)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+static void
+gnome_keyring_list_item_ids_reply (GnomeKeyringOperation *op)
+{
+ GnomeKeyringResult result;
+ GnomeKeyringOperationGetListCallback callback;
+ GList *items;
+
+ callback = op->user_callback;
+
+ if (!gnome_keyring_proto_decode_result_int_list_reply (op->receive_buffer, &result, &items)) {
+ (*callback) (GNOME_KEYRING_RESULT_IO_ERROR, NULL, op->user_data);
+ } else {
+ (*callback) (result, items, op->user_data);
+ g_list_free (items);
+ }
+}
+
+gpointer
+gnome_keyring_list_item_ids (const char *keyring,
+ GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_GET_LIST, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string (op->send_buffer,
+ GNOME_KEYRING_OP_LIST_ITEMS,
+ keyring)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_list_item_ids_reply;
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_list_item_ids_sync (const char *keyring,
+ GList **ids)
+{
+ GString *send;
+ GString *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ *ids = NULL;
+
+ if (!gnome_keyring_proto_encode_op_string (send,
+ GNOME_KEYRING_OP_LIST_ITEMS,
+ keyring)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_int_list_reply (receive, &res, ids)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+GnomeKeyringResult
+gnome_keyring_daemon_set_display_sync (const char *display)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_op_string (send,
+ GNOME_KEYRING_OP_SET_DAEMON_DISPLAY,
+ display)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_reply (receive, &res)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+void
+gnome_keyring_info_set_lock_on_idle (GnomeKeyringInfo *keyring_info,
+ gboolean value)
+{
+ keyring_info->lock_on_idle = value;
+}
+
+gboolean
+gnome_keyring_info_get_lock_on_idle (GnomeKeyringInfo *keyring_info)
+{
+ return keyring_info->lock_on_idle;
+}
+
+void
+gnome_keyring_info_set_lock_timeout (GnomeKeyringInfo *keyring_info,
+ guint32 value)
+{
+ keyring_info->lock_timeout = value;
+}
+
+guint32
+gnome_keyring_info_get_lock_timeout (GnomeKeyringInfo *keyring_info)
+{
+ return keyring_info->lock_timeout;
+}
+
+time_t
+gnome_keyring_info_get_mtime (GnomeKeyringInfo *keyring_info)
+{
+ return keyring_info->mtime;
+}
+
+time_t
+gnome_keyring_info_get_ctime (GnomeKeyringInfo *keyring_info)
+{
+ return keyring_info->ctime;
+}
+
+gboolean
+gnome_keyring_info_get_is_locked (GnomeKeyringInfo *keyring_info)
+{
+ return keyring_info->is_locked;
+}
+
+static void
+gnome_keyring_find_items_reply (GnomeKeyringOperation *op)
+{
+ GnomeKeyringResult result;
+ GnomeKeyringOperationGetListCallback callback;
+ GList *found_items;
+
+ callback = op->user_callback;
+
+ if (!gnome_keyring_proto_decode_find_reply (op->receive_buffer, &result, &found_items)) {
+ (*callback) (GNOME_KEYRING_RESULT_IO_ERROR, NULL, op->user_data);
+ } else {
+ (*callback) (result, found_items, op->user_data);
+ gnome_keyring_found_list_free (found_items);
+ }
+}
+
+gpointer
+gnome_keyring_find_items (GnomeKeyringItemType type,
+ GnomeKeyringAttributeList *attributes,
+ GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_GET_LIST, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_find (op->send_buffer,
+ type,
+ attributes)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_find_items_reply;
+ return op;
+}
+
+
+static GnomeKeyringAttributeList *
+make_attribute_list_va (va_list args)
+{
+ GnomeKeyringAttributeList *attributes;
+ GnomeKeyringAttribute attribute;
+ char *str;
+ guint32 val;
+
+ attributes = g_array_new (FALSE, FALSE, sizeof (GnomeKeyringAttribute));
+
+ while ((attribute.name = va_arg (args, char *)) != NULL) {
+ attribute.type = va_arg (args, GnomeKeyringAttributeType);
+
+ switch (attribute.type) {
+ case GNOME_KEYRING_ATTRIBUTE_TYPE_STRING:
+ str = va_arg (args, char *);
+ attribute.value.string = str;
+ g_array_append_val (attributes, attribute);
+ break;
+ case GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32:
+ val = va_arg (args, guint32);
+ attribute.value.integer = val;
+ g_array_append_val (attributes, attribute);
+ break;
+ default:
+ g_array_free (attributes, TRUE);
+ return NULL;
+ }
+ }
+ return attributes;
+}
+
+
+gpointer
+gnome_keyring_find_itemsv (GnomeKeyringItemType type,
+ GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data,
+ ...)
+{
+ GnomeKeyringOperation *op;
+ GnomeKeyringAttributeList *attributes;
+ va_list args;
+
+ op = start_operation (callback, CALLBACK_GET_LIST, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ va_start (args, destroy_data);
+ attributes = make_attribute_list_va (args);
+ va_end (args);
+ if (attributes == NULL) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_find (op->send_buffer,
+ type,
+ attributes)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+ g_array_free (attributes, TRUE);
+
+ op->reply_handler = gnome_keyring_find_items_reply;
+ return op;
+}
+
+/**
+ * gnome_keyring_find_items_sync:
+ * @type: a #GnomeKeyringItemType
+ * @attributes: a #GnomeKeyringAttributeList
+ * @found: a return location for the found items, must not be %NULL
+ *
+ * Find elements of type #GnomeKeyring by matching attributes and @type.
+ *
+ * Returns: %GNOME_KEYRING_RESULT_OK if everythink went fine. A #GList of
+ * #GnomeKeyringFound will be returned into @found, free all results with
+ * gnome_keyring_found_list_free() or every single item with
+ * gnome_keyring_found_free()
+ */
+GnomeKeyringResult
+gnome_keyring_find_items_sync (GnomeKeyringItemType type,
+ GnomeKeyringAttributeList *attributes,
+ GList **found)
+{
+ GString *send;
+ GString *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ *found = NULL;
+
+ if (!gnome_keyring_proto_encode_find (send, type,
+ attributes)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_find_reply (receive, &res, found)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+GnomeKeyringResult
+gnome_keyring_find_itemsv_sync (GnomeKeyringItemType type,
+ GList **found,
+ ...)
+{
+ GnomeKeyringAttributeList *attributes;
+ GnomeKeyringResult res;
+ va_list args;
+
+ va_start (args, found);
+ attributes = make_attribute_list_va (args);
+ va_end (args);
+ if (attributes == NULL) {
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ res = gnome_keyring_find_items_sync (type, attributes, found);
+ g_array_free (attributes, TRUE);
+ return res;
+}
+
+
+gpointer
+gnome_keyring_item_create (const char *keyring,
+ GnomeKeyringItemType type,
+ const char *display_name,
+ GnomeKeyringAttributeList *attributes,
+ const char *secret,
+ gboolean update_if_exists,
+ GnomeKeyringOperationGetIntCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_GET_INT, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_create_item (op->send_buffer,
+ keyring,
+ display_name,
+ attributes,
+ secret,
+ type,
+ update_if_exists)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_int_reply;
+
+ return op;
+}
+
+/**
+ * gnome_keyring_item_create_sync():
+ * @keyring: the keyring name (%NULL for default)
+ * @type: the #GnomeKeyringItemType of the item to save
+ * @display_name: the name for this item to be used in the password manager
+ * @attributes: the attributes specifying the keyring item
+ * @secret: the secret information (password, passphrase, pin, etc) to be saved
+ * @update_if_exists: set to %TRUE to update an existing item, if found. Create
+ * a new one otherwise. Only item @attributes are matched.
+ * @item_id: return location for the id of the created/updated keyring item.
+ *
+ * Create (or update of @update_if_exists is set) a keyring item with the
+ * specified type, attributes and secret.
+ *
+ * Returns %GNOME_KEYRING_RESULT_OK if everything went fine.
+ */
+GnomeKeyringResult
+gnome_keyring_item_create_sync (const char *keyring,
+ GnomeKeyringItemType type,
+ const char *display_name,
+ GnomeKeyringAttributeList *attributes,
+ const char *secret,
+ gboolean update_if_exists,
+ guint32 *item_id)
+{
+ GString *send;
+ GString *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ *item_id = 0;
+
+ if (!gnome_keyring_proto_encode_create_item (send,
+ keyring,
+ display_name,
+ attributes,
+ secret,
+ type,
+ update_if_exists)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_result_integer_reply (receive, &res, item_id)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_item_delete (const char *keyring,
+ guint32 id,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string_int (op->send_buffer,
+ GNOME_KEYRING_OP_DELETE_ITEM,
+ keyring, id)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+
+ return op;
+}
+
+/**
+ * gnome_keyring_item_delete_sync():
+ * @keyring: the keyring to work with (%NULL for the default keyring)
+ * @id: the keyring item id to delete
+ *
+ * Deletes an item from your keyring. Obtain @id by calling a function like
+ * gnome_keyring_find_items_sync() or gnome_keyring_item_create_sync().
+ *
+ * Returns %GNOME_KEYRING_RESULT_OK on success, the error code otherwise.
+ */
+GnomeKeyringResult
+gnome_keyring_item_delete_sync (const char *keyring,
+ guint32 id)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_op_string_int (send,
+ GNOME_KEYRING_OP_DELETE_ITEM,
+ keyring,
+ id)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+static void
+gnome_keyring_get_item_info_reply (GnomeKeyringOperation *op)
+{
+ GnomeKeyringResult result;
+ GnomeKeyringOperationGetItemInfoCallback callback;
+ GnomeKeyringItemInfo *info;
+
+ callback = op->user_callback;
+
+ if (!gnome_keyring_proto_decode_get_item_info_reply (op->receive_buffer, &result, &info)) {
+ (*callback) (GNOME_KEYRING_RESULT_IO_ERROR, NULL, op->user_data);
+ } else {
+ (*callback) (result, info, op->user_data);
+ gnome_keyring_item_info_free (info);
+ }
+}
+
+gpointer
+gnome_keyring_item_get_info (const char *keyring,
+ guint32 id,
+ GnomeKeyringOperationGetItemInfoCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_GET_ITEM_INFO, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string_int (op->send_buffer,
+ GNOME_KEYRING_OP_GET_ITEM_INFO,
+ keyring, id)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_get_item_info_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_item_get_info_sync (const char *keyring,
+ guint32 id,
+ GnomeKeyringItemInfo **info)
+{
+ GString *send;
+ GString *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ *info = NULL;
+
+ if (!gnome_keyring_proto_encode_op_string_int (send,
+ GNOME_KEYRING_OP_GET_ITEM_INFO,
+ keyring, id)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_get_item_info_reply (receive, &res, info)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_item_get_info_full (const char *keyring,
+ guint32 id,
+ guint32 flags,
+ GnomeKeyringOperationGetItemInfoCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_GET_ITEM_INFO, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string_int_int (op->send_buffer,
+ GNOME_KEYRING_OP_GET_ITEM_INFO_FULL,
+ keyring, id, flags)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_get_item_info_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_item_get_info_full_sync (const char *keyring,
+ guint32 id,
+ guint32 flags,
+ GnomeKeyringItemInfo **info)
+{
+ GString *send;
+ GString *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ *info = NULL;
+
+ if (!gnome_keyring_proto_encode_op_string_int_int (send,
+ GNOME_KEYRING_OP_GET_ITEM_INFO_FULL,
+ keyring, id, flags)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_get_item_info_reply (receive, &res, info)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_item_set_info (const char *keyring,
+ guint32 id,
+ GnomeKeyringItemInfo *info,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_set_item_info (op->send_buffer,
+ keyring, id, info)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_item_set_info_sync (const char *keyring,
+ guint32 id,
+ GnomeKeyringItemInfo *info)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_set_item_info (send,
+ keyring, id, info)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+static void
+gnome_keyring_get_attributes_reply (GnomeKeyringOperation *op)
+{
+ GnomeKeyringResult result;
+ GnomeKeyringOperationGetAttributesCallback callback;
+ GnomeKeyringAttributeList *attributes;
+
+ callback = op->user_callback;
+
+ if (!gnome_keyring_proto_decode_get_attributes_reply (op->receive_buffer, &result, &attributes)) {
+ (*callback) (GNOME_KEYRING_RESULT_IO_ERROR, NULL, op->user_data);
+ } else {
+ (*callback) (result, attributes, op->user_data);
+ gnome_keyring_attribute_list_free (attributes);
+ }
+}
+
+static void
+gnome_keyring_get_acl_reply (GnomeKeyringOperation *op)
+{
+ GnomeKeyringResult result;
+ GnomeKeyringOperationGetListCallback callback;
+ GList *acl;
+
+ callback = op->user_callback;
+
+ if (!gnome_keyring_proto_decode_get_acl_reply (op->receive_buffer, &result, &acl)) {
+ (*callback) (GNOME_KEYRING_RESULT_IO_ERROR, NULL, op->user_data);
+ } else {
+ (*callback) (result, acl, op->user_data);
+ g_list_free (acl);
+ }
+}
+
+
+gpointer
+gnome_keyring_item_get_attributes (const char *keyring,
+ guint32 id,
+ GnomeKeyringOperationGetAttributesCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_GET_ATTRIBUTES, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string_int (op->send_buffer,
+ GNOME_KEYRING_OP_GET_ITEM_ATTRIBUTES,
+ keyring, id)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_get_attributes_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_item_get_attributes_sync (const char *keyring,
+ guint32 id,
+ GnomeKeyringAttributeList **attributes)
+{
+ GString *send;
+ GString *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ *attributes = NULL;
+
+ if (!gnome_keyring_proto_encode_op_string_int (send,
+ GNOME_KEYRING_OP_GET_ITEM_ATTRIBUTES,
+ keyring, id)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_get_attributes_reply (receive, &res, attributes)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_item_set_attributes (const char *keyring,
+ guint32 id,
+ GnomeKeyringAttributeList *attributes,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_set_attributes (op->send_buffer,
+ keyring, id,
+ attributes)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_item_set_attributes_sync (const char *keyring,
+ guint32 id,
+ GnomeKeyringAttributeList *attributes)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_set_attributes (send,
+ keyring, id,
+ attributes)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ g_string_free (receive, TRUE);
+
+ return res;
+
+}
+
+gpointer
+gnome_keyring_item_get_acl (const char *keyring,
+ guint32 id,
+ GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_GET_ACL, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_op_string_int (op->send_buffer,
+ GNOME_KEYRING_OP_GET_ITEM_ACL,
+ keyring, id)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_get_acl_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_item_get_acl_sync (const char *keyring,
+ guint32 id,
+ GList **acl)
+{
+ GString *send;
+ GString *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ *acl = NULL;
+
+ if (!gnome_keyring_proto_encode_op_string_int (send,
+ GNOME_KEYRING_OP_GET_ITEM_ACL,
+ keyring, id)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ if (res != GNOME_KEYRING_RESULT_OK) {
+ g_string_free (receive, TRUE);
+ return res;
+ }
+
+ if (!gnome_keyring_proto_decode_get_acl_reply (receive, &res, acl)) {
+ g_string_free (receive, TRUE);
+ return GNOME_KEYRING_RESULT_IO_ERROR;
+ }
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+gpointer
+gnome_keyring_item_set_acl (const char *keyring,
+ guint32 id,
+ GList *acl,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringOperation *op;
+
+ op = start_operation (callback, CALLBACK_DONE, data, destroy_data);
+ if (op->state == STATE_FAILED) {
+ return op;
+ }
+
+ if (!gnome_keyring_proto_encode_set_acl (op->send_buffer,
+ keyring, id,
+ acl)) {
+ schedule_op_failed (op, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
+ }
+
+ op->reply_handler = gnome_keyring_standard_reply;
+
+ return op;
+}
+
+GnomeKeyringResult
+gnome_keyring_item_set_acl_sync (const char *keyring,
+ guint32 id,
+ GList *acl)
+{
+ GString *send, *receive;
+ GnomeKeyringResult res;
+
+ send = g_string_new (NULL);
+
+ if (!gnome_keyring_proto_encode_set_acl (send,
+ keyring, id,
+ acl)) {
+ g_string_free (send, TRUE);
+ return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+ }
+
+ receive = g_string_new (NULL);
+ res = run_sync_operation (send, receive);
+ g_string_free (send, TRUE);
+ g_string_free (receive, TRUE);
+
+ return res;
+}
+
+GnomeKeyringResult
+gnome_keyring_item_grant_access_rights_sync (const char *keyring,
+ const char *display_name,
+ const char *full_path,
+ const guint32 id,
+ const GnomeKeyringAccessType rights)
+{
+ GList *acl_list = NULL;
+ GnomeKeyringApplicationRef new_app_ref;
+ GnomeKeyringAccessControl acl;
+ GnomeKeyringResult res;
+
+ /* setup application structure */
+ new_app_ref.display_name = (char *) display_name;
+ new_app_ref.pathname = (char *) full_path;
+ acl.application = &new_app_ref;
+ acl.types_allowed = rights;
+
+ /* get the original acl list */
+ res = gnome_keyring_item_get_acl_sync (keyring,
+ id,
+ &acl_list);
+ if (GNOME_KEYRING_RESULT_OK != res)
+ goto out;
+
+ /* append access rights */
+ acl_list = g_list_append (acl_list, (gpointer) &acl);
+ res = gnome_keyring_item_set_acl_sync (keyring,
+ id,
+ acl_list);
+out:
+ if (acl_list)
+ g_list_free (acl_list);
+
+ return res;
+}
+
+GnomeKeyringItemType
+gnome_keyring_item_info_get_type (GnomeKeyringItemInfo *item_info)
+{
+ return item_info->type;
+}
+
+void
+gnome_keyring_item_info_set_type (GnomeKeyringItemInfo *item_info,
+ GnomeKeyringItemType type)
+{
+ item_info->type = type;
+}
+
+char *
+gnome_keyring_item_info_get_secret (GnomeKeyringItemInfo *item_info)
+{
+ return g_strdup (item_info->secret);
+}
+
+void
+gnome_keyring_item_info_set_secret (GnomeKeyringItemInfo *item_info,
+ const char *value)
+{
+ g_free (item_info->secret);
+ item_info->secret = g_strdup (value);
+}
+
+char *
+gnome_keyring_item_info_get_display_name (GnomeKeyringItemInfo *item_info)
+{
+ return g_strdup (item_info->display_name);
+}
+
+void
+gnome_keyring_item_info_set_display_name (GnomeKeyringItemInfo *item_info,
+ const char *value)
+{
+ g_free (item_info->display_name);
+ item_info->display_name = g_strdup (value);
+}
+
+time_t
+gnome_keyring_item_info_get_mtime (GnomeKeyringItemInfo *item_info)
+{
+ return item_info->mtime;
+}
+
+time_t
+gnome_keyring_item_info_get_ctime (GnomeKeyringItemInfo *item_info)
+{
+ return item_info->ctime;
+}
+
+char *
+gnome_keyring_item_ac_get_display_name (GnomeKeyringAccessControl *ac)
+{
+ return g_strdup (ac->application->display_name);
+}
+
+void
+gnome_keyring_item_ac_set_display_name (GnomeKeyringAccessControl *ac,
+ const char *value)
+{
+ g_free (ac->application->display_name);
+ ac->application->display_name = g_strdup (value);
+}
+
+char *
+gnome_keyring_item_ac_get_path_name (GnomeKeyringAccessControl *ac)
+{
+ return g_strdup (ac->application->pathname);
+}
+
+void
+gnome_keyring_item_ac_set_path_name (GnomeKeyringAccessControl *ac,
+ const char *value)
+{
+ g_free (ac->application->pathname);
+ ac->application->pathname = g_strdup (value);
+}
+
+GnomeKeyringAccessType
+gnome_keyring_item_ac_get_access_type (GnomeKeyringAccessControl *ac)
+{
+ return ac->types_allowed;
+}
+
+void
+gnome_keyring_item_ac_set_access_type (GnomeKeyringAccessControl *ac,
+ const GnomeKeyringAccessType value)
+{
+ ac->types_allowed = value;
+}
+
+
+struct FindNetworkPasswordInfo {
+ GnomeKeyringOperationGetListCallback callback;
+ gpointer data;
+ GDestroyNotify destroy_data;
+};
+
+static void
+free_find_network_password_info (struct FindNetworkPasswordInfo *info)
+{
+ if (info->destroy_data != NULL) {
+ info->destroy_data (info->data);
+ }
+ g_free (info);
+}
+
+static GList *
+found_list_to_nework_password_list (GList *found_list)
+{
+ GnomeKeyringNetworkPasswordData *data;
+ GnomeKeyringFound *found;
+ GnomeKeyringAttribute *attributes;
+ GList *result, *l;
+ int i;
+
+ result = NULL;
+ for (l = found_list; l != NULL; l = l->next) {
+ found = l->data;
+
+ data = g_new0 (GnomeKeyringNetworkPasswordData, 1);
+
+ result = g_list_prepend (result, data);
+
+ data->keyring = g_strdup (found->keyring);
+ data->item_id = found->item_id;
+ data->password = g_strdup (found->secret);
+
+ attributes = (GnomeKeyringAttribute *) found->attributes->data;
+ for (i = 0; i < found->attributes->len; i++) {
+ if (strcmp (attributes[i].name, "user") == 0 &&
+ attributes[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
+ data->user = g_strdup (attributes[i].value.string);
+ } else if (strcmp (attributes[i].name, "domain") == 0 &&
+ attributes[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
+ data->domain = g_strdup (attributes[i].value.string);
+ } else if (strcmp (attributes[i].name, "server") == 0 &&
+ attributes[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
+ data->server = g_strdup (attributes[i].value.string);
+ } else if (strcmp (attributes[i].name, "object") == 0 &&
+ attributes[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
+ data->object = g_strdup (attributes[i].value.string);
+ } else if (strcmp (attributes[i].name, "protocol") == 0 &&
+ attributes[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
+ data->protocol = g_strdup (attributes[i].value.string);
+ } else if (strcmp (attributes[i].name, "authtype") == 0 &&
+ attributes[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
+ data->authtype = g_strdup (attributes[i].value.string);
+ } else if (strcmp (attributes[i].name, "port") == 0 &&
+ attributes[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) {
+ data->port = attributes[i].value.integer;
+ }
+ }
+ }
+
+ return g_list_reverse (result);
+}
+
+void
+gnome_keyring_network_password_free (GnomeKeyringNetworkPasswordData *data)
+{
+ g_free (data->keyring);
+ g_free (data->protocol);
+ g_free (data->server);
+ g_free (data->object);
+ g_free (data->authtype);
+ g_free (data->user);
+ g_free (data->domain);
+ g_free (data->password);
+
+ g_free (data);
+}
+
+void
+gnome_keyring_network_password_list_free (GList *list)
+{
+ g_list_foreach (list, (GFunc)gnome_keyring_network_password_free, NULL);
+ g_list_free (list);
+}
+
+static void
+find_network_password_callback (GnomeKeyringResult result,
+ GList *list,
+ gpointer data)
+{
+ struct FindNetworkPasswordInfo *info;
+ GList *data_list;
+
+ info = data;
+
+ data_list = NULL;
+ if (result == GNOME_KEYRING_RESULT_OK) {
+ data_list = found_list_to_nework_password_list (list);
+ }
+ info->callback (result, data_list, info->data);
+ gnome_keyring_network_password_list_free (data_list);
+ return;
+}
+
+/**
+ * gnome_keyring_attribute_list_append_string():
+ * @attributes: a #GnomeKeyringAttributeList
+ * @attributename: the name of the new attribute
+ * @value: the value to store in @attributes
+ *
+ * Store a key-value-pair with a string value in @attributes.
+ */
+void
+gnome_keyring_attribute_list_append_string (GnomeKeyringAttributeList *attributes,
+ const char *attributename, const char *value)
+{
+ GnomeKeyringAttribute attribute;
+
+ attribute.name = g_strdup (attributename);
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup (value);
+
+ g_array_append_val (attributes, attribute);
+}
+
+/**
+ * gnome_keyring_attribute_append_uint32:
+ * @attributes: a #GnomeKeyringAttributeList
+ * @attributename: the name of the new attribute
+ * @value: the value to store in @attributes
+ *
+ * Store a key-value-pair with an unsigned 32bit number value in @attributes.
+ */
+void
+gnome_keyring_attribute_list_append_uint32 (GnomeKeyringAttributeList *attributes,
+ const char *attributename, guint32 value)
+{
+ GnomeKeyringAttribute attribute;
+
+ attribute.name = g_strdup (attributename);
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32;
+ attribute.value.integer = value;
+ g_array_append_val (attributes, attribute);
+}
+
+static GnomeKeyringAttributeList *
+make_attribute_list_for_network_password (const char *user,
+ const char *domain,
+ const char *server,
+ const char *object,
+ const char *protocol,
+ const char *authtype,
+ guint32 port)
+{
+ GnomeKeyringAttributeList *attributes;
+
+ attributes = g_array_new (FALSE, FALSE, sizeof (GnomeKeyringAttribute));
+
+ if (user != NULL) {
+ gnome_keyring_attribute_list_append_string (attributes, "user", user);
+ }
+ if (domain != NULL) {
+ gnome_keyring_attribute_list_append_string (attributes, "domain", domain);
+ }
+ if (server != NULL) {
+ gnome_keyring_attribute_list_append_string (attributes, "server", server);
+ }
+ if (object != NULL) {
+ gnome_keyring_attribute_list_append_string (attributes, "object", object);
+ }
+ if (protocol != NULL) {
+ gnome_keyring_attribute_list_append_string (attributes, "protocol", protocol);
+ }
+ if (authtype != NULL) {
+ gnome_keyring_attribute_list_append_string (attributes, "authtype", authtype);
+ }
+ if (port != 0) {
+ gnome_keyring_attribute_list_append_uint32 (attributes, "port", port);
+ }
+ return attributes;
+}
+
+
+gpointer
+gnome_keyring_find_network_password (const char *user,
+ const char *domain,
+ const char *server,
+ const char *object,
+ const char *protocol,
+ const char *authtype,
+ guint32 port,
+ GnomeKeyringOperationGetListCallback callback,
+ gpointer user_data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringAttributeList *attributes;
+ gpointer request;
+ struct FindNetworkPasswordInfo *info;
+
+ info = g_new0 (struct FindNetworkPasswordInfo, 1);
+ info->callback = callback;
+ info->data = user_data;
+ info->destroy_data = destroy_data;
+
+ attributes = make_attribute_list_for_network_password (user,
+ domain,
+ server,
+ object,
+ protocol,
+ authtype,
+ port);
+
+ request = gnome_keyring_find_items (GNOME_KEYRING_ITEM_NETWORK_PASSWORD,
+ attributes,
+ find_network_password_callback,
+ info,
+ (GDestroyNotify)free_find_network_password_info);
+
+ gnome_keyring_attribute_list_free (attributes);
+ return request;
+}
+
+
+
+GnomeKeyringResult
+gnome_keyring_find_network_password_sync (const char *user,
+ const char *domain,
+ const char *server,
+ const char *object,
+ const char *protocol,
+ const char *authtype,
+ guint32 port,
+ GList **out_list)
+{
+ GnomeKeyringAttributeList *attributes;
+ GnomeKeyringResult result;
+ GList *found;
+
+ *out_list = NULL;
+ attributes = make_attribute_list_for_network_password (user,
+ domain,
+ server,
+ object,
+ protocol,
+ authtype,
+ port);
+
+ result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_NETWORK_PASSWORD,
+ attributes,
+ &found);
+
+ gnome_keyring_attribute_list_free (attributes);
+
+ if (result == GNOME_KEYRING_RESULT_OK) {
+ *out_list = found_list_to_nework_password_list (found);
+ gnome_keyring_found_list_free (found);
+ }
+
+ return result;
+}
+
+static char *
+get_network_password_display_name (const char *user,
+ const char *server,
+ const char *object,
+ guint32 port)
+{
+ GString *s;
+ char *name;
+
+ if (server != NULL) {
+ s = g_string_new (NULL);
+ if (user != NULL) {
+ g_string_append_printf (s, "%s@", user);
+ }
+ g_string_append (s, server);
+ if (port != 0) {
+ g_string_append_printf (s, ":%d", port);
+ }
+ if (object != NULL) {
+ g_string_append_printf (s, "/%s", object);
+ }
+ name = g_string_free (s, FALSE);
+ } else {
+ name = g_strdup ("network password");
+ }
+ return name;
+}
+
+
+
+gpointer
+gnome_keyring_set_network_password (const char *keyring,
+ const char *user,
+ const char *domain,
+ const char *server,
+ const char *object,
+ const char *protocol,
+ const char *authtype,
+ guint32 port,
+ const char *password,
+ GnomeKeyringOperationGetIntCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data)
+{
+ GnomeKeyringAttributeList *attributes;
+ gpointer req;
+ char *name;
+
+ name = get_network_password_display_name (user, server, object, port);
+
+ attributes = make_attribute_list_for_network_password (user,
+ domain,
+ server,
+ object,
+ protocol,
+ authtype,
+ port);
+
+ req = gnome_keyring_item_create (keyring,
+ GNOME_KEYRING_ITEM_NETWORK_PASSWORD,
+ name,
+ attributes,
+ password,
+ TRUE,
+ callback, data, destroy_data);
+
+ gnome_keyring_attribute_list_free (attributes);
+ g_free (name);
+
+ return req;
+}
+
+GnomeKeyringResult
+gnome_keyring_set_network_password_sync (const char *keyring,
+ const char *user,
+ const char *domain,
+ const char *server,
+ const char *object,
+ const char *protocol,
+ const char *authtype,
+ guint32 port,
+ const char *password,
+ guint32 *item_id)
+{
+ GnomeKeyringAttributeList *attributes;
+ char *name;
+ GnomeKeyringResult res;
+
+ name = get_network_password_display_name (user, server, object, port);
+ attributes = make_attribute_list_for_network_password (user,
+ domain,
+ server,
+ object,
+ protocol,
+ authtype,
+ port);
+
+ res = gnome_keyring_item_create_sync (keyring,
+ GNOME_KEYRING_ITEM_NETWORK_PASSWORD,
+ name,
+ attributes,
+ password,
+ TRUE,
+ item_id);
+
+ gnome_keyring_attribute_list_free (attributes);
+ g_free (name);
+
+ return res;
+}
diff --git a/library/gnome-keyring.h b/library/gnome-keyring.h
new file mode 100644
index 00000000..1739b8a0
--- /dev/null
+++ b/library/gnome-keyring.h
@@ -0,0 +1,459 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-keyring.h - library for talking to the keyring daemon.
+
+ Copyright (C) 2003 Red Hat, Inc
+
+ 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
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Alexander Larsson <alexl@redhat.com>
+*/
+
+#ifndef GNOME_KEYRING_H
+#define GNOME_KEYRING_H
+
+#include <glib.h>
+#include <time.h>
+
+typedef enum {
+ GNOME_KEYRING_RESULT_OK,
+ GNOME_KEYRING_RESULT_DENIED,
+ GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON,
+ GNOME_KEYRING_RESULT_ALREADY_UNLOCKED,
+ GNOME_KEYRING_RESULT_NO_SUCH_KEYRING,
+ GNOME_KEYRING_RESULT_BAD_ARGUMENTS,
+ GNOME_KEYRING_RESULT_IO_ERROR,
+ GNOME_KEYRING_RESULT_CANCELLED,
+ GNOME_KEYRING_RESULT_ALREADY_EXISTS
+} GnomeKeyringResult;
+
+typedef enum {
+ /* The item types */
+ GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ GNOME_KEYRING_ITEM_NETWORK_PASSWORD,
+ GNOME_KEYRING_ITEM_NOTE,
+
+ /* Used internally */
+ GNOME_KEYRING_ITEM_LAST_TYPE,
+ GNOME_KEYRING_ITEM_TYPE_MASK = 0x0000ffff,
+ GNOME_KEYRING_ITEM_NO_TYPE = GNOME_KEYRING_ITEM_TYPE_MASK,
+
+ /* Makes a item only for applications in ACL */
+ GNOME_KEYRING_ITEM_APPLICATION_SECRET = 0x01000000,
+
+} GnomeKeyringItemType;
+
+typedef enum {
+ GNOME_KEYRING_ACCESS_ASK,
+ GNOME_KEYRING_ACCESS_DENY,
+ GNOME_KEYRING_ACCESS_ALLOW
+} GnomeKeyringAccessRestriction;
+
+typedef enum {
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
+ GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32
+} GnomeKeyringAttributeType;
+
+typedef struct GnomeKeyringAccessControl GnomeKeyringAccessControl;
+typedef struct GnomeKeyringApplicationRef GnomeKeyringApplicationRef;
+typedef GArray GnomeKeyringAttributeList;
+
+typedef enum {
+ GNOME_KEYRING_ACCESS_READ = 1<<0,
+ GNOME_KEYRING_ACCESS_WRITE = 1<<1,
+ GNOME_KEYRING_ACCESS_REMOVE = 1<<2
+} GnomeKeyringAccessType;
+
+typedef enum {
+ GNOME_KEYRING_ITEM_INFO_BASICS = 0,
+ GNOME_KEYRING_ITEM_INFO_SECRET = 1<<0
+} GnomeKeyringItemInfoFlags;
+
+/* Add flags here as they are added above */
+#define GNOME_KEYRING_ITEM_INFO_ALL (GNOME_KEYRING_ITEM_INFO_BASICS | GNOME_KEYRING_ITEM_INFO_SECRET)
+
+typedef struct GnomeKeyringInfo GnomeKeyringInfo;
+typedef struct GnomeKeyringItemInfo GnomeKeyringItemInfo;
+
+typedef struct {
+ char *name;
+ GnomeKeyringAttributeType type;
+ union {
+ char *string;
+ guint32 integer;
+ } value;
+} GnomeKeyringAttribute;
+
+typedef struct {
+ char *keyring;
+ guint item_id;
+ GnomeKeyringAttributeList *attributes;
+ char *secret;
+} GnomeKeyringFound;
+
+typedef void (*GnomeKeyringOperationDoneCallback) (GnomeKeyringResult result,
+ gpointer data);
+typedef void (*GnomeKeyringOperationGetStringCallback) (GnomeKeyringResult result,
+ const char *string,
+ gpointer data);
+typedef void (*GnomeKeyringOperationGetIntCallback) (GnomeKeyringResult result,
+ guint32 val,
+ gpointer data);
+typedef void (*GnomeKeyringOperationGetListCallback) (GnomeKeyringResult result,
+ GList *list,
+ gpointer data);
+typedef void (*GnomeKeyringOperationGetKeyringInfoCallback) (GnomeKeyringResult result,
+ GnomeKeyringInfo *info,
+ gpointer data);
+typedef void (*GnomeKeyringOperationGetItemInfoCallback) (GnomeKeyringResult result,
+ GnomeKeyringItemInfo*info,
+ gpointer data);
+typedef void (*GnomeKeyringOperationGetAttributesCallback) (GnomeKeyringResult result,
+ GnomeKeyringAttributeList *attributes,
+ gpointer data);
+
+#define gnome_keyring_attribute_list_index(a, i) g_array_index ((a), GnomeKeyringAttribute, (i))
+#define gnome_keyring_attribute_list_new() (g_array_new (FALSE, FALSE, sizeof (GnomeKeyringAttribute)))
+void gnome_keyring_attribute_list_append_string (GnomeKeyringAttributeList *attributes,
+ const char *attribute,
+ const char *value);
+void gnome_keyring_attribute_list_append_uint32 (GnomeKeyringAttributeList *attributes,
+ const char *attribute,
+ guint32 value);
+void gnome_keyring_attribute_list_free (GnomeKeyringAttributeList *attributes);
+GnomeKeyringAttributeList *gnome_keyring_attribute_list_copy (GnomeKeyringAttributeList *attributes);
+
+
+gboolean gnome_keyring_is_available (void);
+
+void gnome_keyring_free_password (char *password);
+
+void gnome_keyring_found_free (GnomeKeyringFound *found);
+void gnome_keyring_found_list_free (GList *found_list);
+
+void gnome_keyring_cancel_request (gpointer request);
+
+gpointer gnome_keyring_set_default_keyring (const char *keyring,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_set_default_keyring_sync (const char *keyring);
+gpointer gnome_keyring_get_default_keyring (GnomeKeyringOperationGetStringCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_get_default_keyring_sync (char **keyring);
+gpointer gnome_keyring_list_keyring_names (GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_list_keyring_names_sync (GList **keyrings);
+gpointer gnome_keyring_lock_all (GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_lock_all_sync (void);
+
+
+/* NULL password means ask user */
+gpointer gnome_keyring_create (const char *keyring_name,
+ const char *password,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_create_sync (const char *keyring_name,
+ const char *password);
+gpointer gnome_keyring_unlock (const char *keyring,
+ const char *password,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_unlock_sync (const char *keyring,
+ const char *password);
+gpointer gnome_keyring_lock (const char *keyring,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_lock_sync (const char *keyring);
+gpointer gnome_keyring_delete (const char *keyring,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_delete_sync (const char *keyring);
+gpointer gnome_keyring_change_password (const char *keyring,
+ const char *original,
+ const char *password,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_change_password_sync (const char *keyring,
+ const char *original,
+ const char *password);
+gpointer gnome_keyring_get_info (const char *keyring,
+ GnomeKeyringOperationGetKeyringInfoCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_get_info_sync (const char *keyring,
+ GnomeKeyringInfo **info);
+gpointer gnome_keyring_set_info (const char *keyring,
+ GnomeKeyringInfo *info,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_set_info_sync (const char *keyring,
+ GnomeKeyringInfo *info);
+gpointer gnome_keyring_list_item_ids (const char *keyring,
+ GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_list_item_ids_sync (const char *keyring,
+ GList **ids);
+
+GnomeKeyringResult gnome_keyring_daemon_set_display_sync (const char *display);
+
+
+void gnome_keyring_info_free (GnomeKeyringInfo *keyring_info);
+GnomeKeyringInfo *gnome_keyring_info_copy (GnomeKeyringInfo *keyring_info);
+void gnome_keyring_info_set_lock_on_idle (GnomeKeyringInfo *keyring_info,
+ gboolean value);
+gboolean gnome_keyring_info_get_lock_on_idle (GnomeKeyringInfo *keyring_info);
+void gnome_keyring_info_set_lock_timeout (GnomeKeyringInfo *keyring_info,
+ guint32 value);
+guint32 gnome_keyring_info_get_lock_timeout (GnomeKeyringInfo *keyring_info);
+time_t gnome_keyring_info_get_mtime (GnomeKeyringInfo *keyring_info);
+time_t gnome_keyring_info_get_ctime (GnomeKeyringInfo *keyring_info);
+gboolean gnome_keyring_info_get_is_locked (GnomeKeyringInfo *keyring_info);
+
+gpointer gnome_keyring_find_items (GnomeKeyringItemType type,
+ GnomeKeyringAttributeList *attributes,
+ GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+gpointer gnome_keyring_find_itemsv (GnomeKeyringItemType type,
+ GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data,
+ ...);
+
+GnomeKeyringResult gnome_keyring_find_items_sync (GnomeKeyringItemType type,
+ GnomeKeyringAttributeList *attributes,
+ GList **found);
+GnomeKeyringResult gnome_keyring_find_itemsv_sync (GnomeKeyringItemType type,
+ GList **found,
+ ...);
+
+gpointer gnome_keyring_item_create (const char *keyring,
+ GnomeKeyringItemType type,
+ const char *display_name,
+ GnomeKeyringAttributeList *attributes,
+ const char *secret,
+ gboolean update_if_exists,
+ GnomeKeyringOperationGetIntCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_item_create_sync (const char *keyring,
+ GnomeKeyringItemType type,
+ const char *display_name,
+ GnomeKeyringAttributeList *attributes,
+ const char *secret,
+ gboolean update_if_exists,
+ guint32 *item_id);
+gpointer gnome_keyring_item_delete (const char *keyring,
+ guint32 id,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_item_delete_sync (const char *keyring,
+ guint32 id);
+gpointer gnome_keyring_item_get_info (const char *keyring,
+ guint32 id,
+ GnomeKeyringOperationGetItemInfoCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_item_get_info_sync (const char *keyring,
+ guint32 id,
+ GnomeKeyringItemInfo **info);
+gpointer gnome_keyring_item_get_info_full (const char *keyring,
+ guint32 id,
+ guint32 flags,
+ GnomeKeyringOperationGetItemInfoCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_item_get_info_full_sync (const char *keyring,
+ guint32 id,
+ guint32 flags,
+ GnomeKeyringItemInfo **info);
+gpointer gnome_keyring_item_set_info (const char *keyring,
+ guint32 id,
+ GnomeKeyringItemInfo *info,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_item_set_info_sync (const char *keyring,
+ guint32 id,
+ GnomeKeyringItemInfo *info);
+gpointer gnome_keyring_item_get_attributes (const char *keyring,
+ guint32 id,
+ GnomeKeyringOperationGetAttributesCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_item_get_attributes_sync (const char *keyring,
+ guint32 id,
+ GnomeKeyringAttributeList **attributes);
+gpointer gnome_keyring_item_set_attributes (const char *keyring,
+ guint32 id,
+ GnomeKeyringAttributeList *attributes,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_item_set_attributes_sync (const char *keyring,
+ guint32 id,
+ GnomeKeyringAttributeList *attributes);
+gpointer gnome_keyring_item_get_acl (const char *keyring,
+ guint32 id,
+ GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_item_get_acl_sync (const char *keyring,
+ guint32 id,
+ GList **acl);
+gpointer gnome_keyring_item_set_acl (const char *keyring,
+ guint32 id,
+ GList *acl,
+ GnomeKeyringOperationDoneCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_item_set_acl_sync (const char *keyring,
+ guint32 id,
+ GList *acl);
+
+/*
+ * Will grant the application access rights to the item, provided
+ * callee has, or is granted, write access to said item.
+ *
+ * keyring : Name of keyring to access or NULL for default keyring
+ * display_name : Display name of application to be granted access rights - As returned by g_get_application_name()
+ * full_path : Full path of application to be granted access rights
+ * id : ID of item to access in keyring
+ * rights : Bitmask of rights to grant the application
+ */
+GnomeKeyringResult gnome_keyring_item_grant_access_rights_sync (const char *keyring,
+ const char *display_name,
+ const char *full_path,
+ const guint32 id,
+ const GnomeKeyringAccessType rights);
+
+void gnome_keyring_item_info_free (GnomeKeyringItemInfo *item_info);
+GnomeKeyringItemInfo *gnome_keyring_item_info_new (void);
+GnomeKeyringItemInfo *gnome_keyring_item_info_copy (GnomeKeyringItemInfo *item_info);
+GnomeKeyringItemType gnome_keyring_item_info_get_type (GnomeKeyringItemInfo *item_info);
+void gnome_keyring_item_info_set_type (GnomeKeyringItemInfo *item_info,
+ GnomeKeyringItemType type);
+char * gnome_keyring_item_info_get_secret (GnomeKeyringItemInfo *item_info);
+void gnome_keyring_item_info_set_secret (GnomeKeyringItemInfo *item_info,
+ const char *value);
+char * gnome_keyring_item_info_get_display_name (GnomeKeyringItemInfo *item_info);
+void gnome_keyring_item_info_set_display_name (GnomeKeyringItemInfo *item_info,
+ const char *value);
+time_t gnome_keyring_item_info_get_mtime (GnomeKeyringItemInfo *item_info);
+time_t gnome_keyring_item_info_get_ctime (GnomeKeyringItemInfo *item_info);
+
+GnomeKeyringApplicationRef * gnome_keyring_application_ref_new (void);
+GnomeKeyringApplicationRef * gnome_keyring_application_ref_copy (const GnomeKeyringApplicationRef *app);
+void gnome_keyring_application_ref_free (GnomeKeyringApplicationRef *app);
+
+GnomeKeyringAccessControl * gnome_keyring_access_control_new (const GnomeKeyringApplicationRef *application,
+ GnomeKeyringAccessType types_allowed);
+GnomeKeyringAccessControl * gnome_keyring_access_control_copy (GnomeKeyringAccessControl *ac);
+
+
+void gnome_keyring_access_control_free (GnomeKeyringAccessControl *ac);
+GList * gnome_keyring_acl_copy (GList *list);
+void gnome_keyring_acl_free (GList *acl);
+
+
+char * gnome_keyring_item_ac_get_display_name (GnomeKeyringAccessControl *ac);
+void gnome_keyring_item_ac_set_display_name (GnomeKeyringAccessControl *ac,
+ const char *value);
+
+char * gnome_keyring_item_ac_get_path_name (GnomeKeyringAccessControl *ac);
+void gnome_keyring_item_ac_set_path_name (GnomeKeyringAccessControl *ac,
+ const char *value);
+
+
+GnomeKeyringAccessType gnome_keyring_item_ac_get_access_type (GnomeKeyringAccessControl *ac);
+void gnome_keyring_item_ac_set_access_type (GnomeKeyringAccessControl *ac,
+ const GnomeKeyringAccessType value);
+
+/* Specialized Helpers for network passwords items */
+
+typedef struct {
+ char *keyring;
+ guint32 item_id;
+
+ char *protocol;
+ char *server;
+ char *object;
+ char *authtype;
+ guint32 port;
+
+ char *user;
+ char *domain;
+ char *password;
+} GnomeKeyringNetworkPasswordData;
+
+void gnome_keyring_network_password_free (GnomeKeyringNetworkPasswordData *data);
+void gnome_keyring_network_password_list_free (GList *list);
+
+gpointer gnome_keyring_find_network_password (const char *user,
+ const char *domain,
+ const char *server,
+ const char *object,
+ const char *protocol,
+ const char *authtype,
+ guint32 port,
+ GnomeKeyringOperationGetListCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_find_network_password_sync (const char *user,
+ const char *domain,
+ const char *server,
+ const char *object,
+ const char *protocol,
+ const char *authtype,
+ guint32 port,
+ GList **result);
+gpointer gnome_keyring_set_network_password (const char *keyring,
+ const char *user,
+ const char *domain,
+ const char *server,
+ const char *object,
+ const char *protocol,
+ const char *authtype,
+ guint32 port,
+ const char *password,
+ GnomeKeyringOperationGetIntCallback callback,
+ gpointer data,
+ GDestroyNotify destroy_data);
+GnomeKeyringResult gnome_keyring_set_network_password_sync (const char *keyring,
+ const char *user,
+ const char *domain,
+ const char *server,
+ const char *object,
+ const char *protocol,
+ const char *authtype,
+ guint32 port,
+ const char *password,
+ guint32 *item_id);
+
+
+#endif /* GNOME_KEYRING_H */
diff --git a/library/list-keyrings.c b/library/list-keyrings.c
new file mode 100644
index 00000000..8c6219c0
--- /dev/null
+++ b/library/list-keyrings.c
@@ -0,0 +1,225 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* list-keyrings.c - test app to list keyrings
+
+ Copyright (C) 2003 Red Hat, Inc
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Alexander Larsson <alexl@redhat.com>
+*/
+#include "gnome-keyring.h"
+
+static GMainLoop *loop = NULL;
+
+
+static void
+string_callback (GnomeKeyringResult result,
+ const char *str,
+ gpointer data)
+{
+ char **out;
+
+ out = data;
+
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ g_print ("string op failed: %d\n", result);
+ *out = NULL;
+ } else {
+ *out = g_strdup (str);
+ }
+ g_main_loop_quit (loop);
+}
+
+
+static void
+print_keyring_info (GnomeKeyringResult result,
+ GnomeKeyringInfo *info,
+ gpointer data)
+{
+ gboolean *locked;
+ locked = data;
+
+ *locked = TRUE;
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ g_print ("error getting keyring info: %d\n", result);
+ } else {
+ g_print ("lock_on_idle: %d\n", gnome_keyring_info_get_lock_on_idle (info));
+ g_print ("lock timeout: %d\n", gnome_keyring_info_get_lock_timeout (info));
+ g_print ("mtime: %lu\n", (unsigned long)gnome_keyring_info_get_mtime (info));
+ g_print ("ctime: %lu\n", (unsigned long)gnome_keyring_info_get_ctime (info));
+ g_print ("locked: %d\n", gnome_keyring_info_get_is_locked (info));
+ *locked = gnome_keyring_info_get_is_locked (info);
+ }
+
+ g_main_loop_quit (loop);
+}
+
+static void
+print_item_info (GnomeKeyringResult result,
+ GnomeKeyringItemInfo *info,
+ gpointer data)
+{
+ char *secret;
+ char *name;
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ g_print ("error getting item info: %d\n", result);
+ } else {
+ name = gnome_keyring_item_info_get_display_name (info);
+ secret = gnome_keyring_item_info_get_secret (info);
+ g_print (" type: %u\n", gnome_keyring_item_info_get_type (info));
+ g_print (" name: %s\n", name);
+ g_print (" secret: %s\n", secret);
+ g_print (" mtime: %lu\n", (unsigned long)gnome_keyring_item_info_get_mtime (info));
+ g_print (" ctime: %lu\n", (unsigned long)gnome_keyring_item_info_get_ctime (info));
+ gnome_keyring_free_password (secret);
+ g_free (name);
+ }
+
+ g_main_loop_quit (loop);
+}
+
+static void
+print_attributes (GnomeKeyringResult result,
+ GnomeKeyringAttributeList *attributes,
+ gpointer data)
+{
+ GnomeKeyringAttribute *array;
+ int i;
+
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ g_print ("error getting item attributes: %d\n", result);
+ } else {
+ array = (GnomeKeyringAttribute *)attributes->data;
+ g_print (" Attributes:\n");
+ for (i = 0; i < attributes->len; i++) {
+ if (array[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
+ g_print (" %s = '%s'\n", array[i].name, array[i].value.string);
+ } else if (array[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) {
+ g_print (" %s = %u\n", array[i].name, array[i].value.integer);
+ } else {
+ g_print (" %s = ** unsupported attribute type **\n", array[i].name);
+ }
+ }
+ }
+
+ g_main_loop_quit (loop);
+}
+
+static void
+get_items_callback (GnomeKeyringResult result,
+ GList *list,
+ gpointer data)
+{
+ GList **out;
+
+ out = data;
+ *out = NULL;
+
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ g_print ("error getting item list: %d\n", result);
+ } else {
+ *out = g_list_copy (list);
+ }
+
+ g_main_loop_quit (loop);
+}
+
+static void
+string_list_callback (GnomeKeyringResult result,
+ GList *list,
+ gpointer data)
+{
+ GList *l;
+ char *name;
+ GList **out;
+
+ out = data;
+
+ *out = NULL;
+
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ g_print ("error getting keyring list: %d\n", result);
+ } else {
+ for (l = list; l != NULL; l = l->next) {
+ name = l->data;
+ *out = g_list_append (*out, g_strdup (name));
+ }
+ }
+
+ g_main_loop_quit (loop);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ GList *keyrings, *l, *items, *ll;
+ char *keyring;
+ gboolean locked;
+ guint32 item_id;
+
+ g_set_application_name("list-keyrings");
+ loop = g_main_loop_new (NULL, FALSE);
+
+ g_print ("Keyrings:\n");
+ gnome_keyring_list_keyring_names (string_list_callback, &keyrings, NULL);
+ g_main_loop_run (loop);
+ for (l = keyrings; l != NULL; l = l->next) {
+ keyring = l->data;
+ g_print ("\nkeyring: %s\n", keyring);
+
+ gnome_keyring_get_info (keyring, print_keyring_info, &locked, NULL);
+ g_main_loop_run (loop);
+
+ if (1 || !locked) {
+ gnome_keyring_list_item_ids (keyring, get_items_callback, &items, NULL);
+ g_main_loop_run (loop);
+
+ if (items != NULL) {
+ g_print ("Items: \n");
+ }
+ for (ll = items; ll != NULL; ll = ll->next) {
+ item_id = GPOINTER_TO_UINT(ll->data);
+
+ g_print ("\n");
+ g_print (" id: %u\n", item_id);
+ gnome_keyring_item_get_info (keyring,
+ item_id,
+ print_item_info, NULL, NULL);
+ g_main_loop_run (loop);
+ gnome_keyring_item_get_attributes (keyring,
+ item_id,
+ print_attributes, NULL, NULL);
+ g_main_loop_run (loop);
+ }
+ g_list_free (items);
+ }
+
+ g_free (keyring);
+ }
+ g_list_free (keyrings);
+
+ gnome_keyring_get_default_keyring (string_callback, &keyring, NULL);
+ g_main_loop_run (loop);
+ g_print ("\n");
+ if (keyring != NULL) {
+ g_print ("The default keyring for storage is '%s'\n", keyring);
+ } else {
+ g_print ("No default keyring defined\n");
+ }
+
+ return 0;
+}
diff --git a/library/test.c b/library/test.c
new file mode 100644
index 00000000..ecdcb64d
--- /dev/null
+++ b/library/test.c
@@ -0,0 +1,502 @@
+#include <stdlib.h>
+
+#include "gnome-keyring.h"
+
+static GMainLoop *loop = NULL;
+
+static void
+print_attributes (GnomeKeyringAttributeList *attributes)
+{
+ GnomeKeyringAttribute *array;
+ int i;
+
+ array = (GnomeKeyringAttribute *)attributes->data;
+ g_print (" Attributes:\n");
+ for (i = 0; i < attributes->len; i++) {
+ if (array[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
+ g_print (" %s = '%s'\n", array[i].name, array[i].value.string);
+ } else if (array[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32) {
+ g_print (" %s = %u\n", array[i].name, array[i].value.integer);
+ } else {
+ g_print (" %s = ** unsupported attribute type **\n", array[i].name);
+ }
+ }
+}
+
+static const gchar* result_msg[] = {
+ "GNOME_KEYRING_RESULT_OK",
+ "GNOME_KEYRING_RESULT_DENIED",
+ "GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON",
+ "GNOME_KEYRING_RESULT_ALREADY_UNLOCKED",
+ "GNOME_KEYRING_RESULT_NO_SUCH_KEYRING",
+ "GNOME_KEYRING_RESULT_BAD_ARGUMENTS",
+ "GNOME_KEYRING_RESULT_IO_ERROR",
+ "GNOME_KEYRING_RESULT_CANCELLED",
+ "GNOME_KEYRING_RESULT_ALREADY_EXISTS"
+};
+
+static const gchar*
+get_msg_for_keyring_result (GnomeKeyringResult result)
+{
+ if (result<=GNOME_KEYRING_RESULT_ALREADY_EXISTS) {
+ return result_msg[result];
+ } else {
+ return "Unknown GnomeKeyringResult";
+ }
+}
+
+static void
+ok_cb (GnomeKeyringResult result,
+ gpointer data)
+{
+ g_print ("%s: %d (%s)\n", (char *)data, result, get_msg_for_keyring_result (result));
+ g_main_loop_quit (loop);
+}
+
+static void
+lock_all (void)
+{
+ gnome_keyring_lock_all (ok_cb, "lock all", NULL);
+ g_main_loop_run (loop);
+}
+
+static void
+lock (char *keyring)
+{
+ gnome_keyring_lock (keyring,
+ ok_cb, "lock", NULL);
+ g_main_loop_run (loop);
+}
+
+static void
+unlock (char *keyring, char *password)
+{
+ gnome_keyring_unlock (keyring, password,
+ ok_cb, "unlock", NULL);
+ g_main_loop_run (loop);
+}
+
+static void
+find_items_cb (GnomeKeyringResult result,
+ GList *found_items,
+ gpointer data)
+{
+ g_print ("found items: res: %d (%s) nr items: %d\n", result, get_msg_for_keyring_result (result), g_list_length (found_items));
+
+ if (found_items != NULL) {
+ GnomeKeyringFound *found = found_items->data;
+
+ g_print ("Found item: keyring=%s, id=%d, secret='%s'\n", found->keyring, found->item_id, found->secret);
+ print_attributes (found->attributes);
+ }
+
+ g_main_loop_quit (loop);
+}
+
+static void
+find_items (char *attr_val)
+{
+ gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_NOTE,
+ find_items_cb, NULL, NULL,
+ "testattribute", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, attr_val,
+ NULL);
+ g_main_loop_run (loop);
+}
+
+static void
+creat_item_cb (GnomeKeyringResult result,
+ guint32 id,
+ gpointer data)
+{
+ g_print ("created item: res: %d (%s) id: %d\n", result, get_msg_for_keyring_result (result), id);
+ g_main_loop_quit (loop);
+}
+
+static void
+create_item (char *name, char *attr_name, gboolean update_if_exists)
+{
+ GnomeKeyringAttributeList *attributes;
+ GnomeKeyringAttribute attribute;
+
+ attribute.name = g_strdup ("testattribute");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup (attr_name);
+
+ attributes = gnome_keyring_attribute_list_new ();
+ g_array_append_val (attributes, attribute);
+
+ gnome_keyring_item_create (NULL,
+ GNOME_KEYRING_ITEM_NOTE,
+ name,
+ attributes,
+ "secret text",
+ update_if_exists,
+ creat_item_cb, NULL, NULL);
+ gnome_keyring_attribute_list_free (attributes);
+ g_main_loop_run (loop);
+}
+
+static void
+creat_application_item_cb (GnomeKeyringResult result,
+ guint32 id,
+ gpointer data)
+{
+ g_print ("created application item: res: %d (%s) id: %d\n", result, get_msg_for_keyring_result (result), id);
+ g_main_loop_quit (loop);
+}
+
+static void
+create_application_item (char *name, char *attr_name, gboolean update_if_exists)
+{
+ GnomeKeyringAttributeList *attributes;
+ GnomeKeyringAttribute attribute;
+
+ attribute.name = g_strdup ("testattribute");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup (attr_name);
+
+ attributes = gnome_keyring_attribute_list_new ();
+ g_array_append_val (attributes, attribute);
+
+ gnome_keyring_item_create (NULL,
+ GNOME_KEYRING_ITEM_NOTE | GNOME_KEYRING_ITEM_APPLICATION_SECRET,
+ name,
+ attributes,
+ "application secret text",
+ update_if_exists,
+ creat_application_item_cb, NULL, NULL);
+ gnome_keyring_attribute_list_free (attributes);
+ g_main_loop_run (loop);
+}
+
+static void
+show_item_cb (GnomeKeyringResult result,
+ GnomeKeyringItemInfo *info,
+ gpointer data)
+{
+ char *secret;
+ char *name;
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ g_print ("error getting item info: %d (%s)\n", result, get_msg_for_keyring_result (result));
+ } else {
+ name = gnome_keyring_item_info_get_display_name (info);
+ secret = gnome_keyring_item_info_get_secret (info);
+ g_print (" type: %u\n", gnome_keyring_item_info_get_type (info));
+ g_print (" name: %s\n", name);
+ g_print (" secret: %s\n", secret);
+ g_print (" mtime: %lu\n", (unsigned long)gnome_keyring_item_info_get_mtime (info));
+ g_print (" ctime: %lu\n", (unsigned long)gnome_keyring_item_info_get_ctime (info));
+ gnome_keyring_free_password (secret);
+ g_free (name);
+ }
+
+ g_main_loop_quit (loop);
+}
+
+static void
+print_attributes_cb (GnomeKeyringResult result,
+ GnomeKeyringAttributeList *attributes,
+ gpointer data)
+{
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ g_print ("error getting item attributes: %d (%s)\n", result, get_msg_for_keyring_result (result));
+ } else {
+ print_attributes (attributes);
+ }
+
+ g_main_loop_quit (loop);
+}
+
+static void
+show_item (char *keyring, guint32 item_id, guint32 parts)
+{
+ gnome_keyring_item_get_info_full (keyring, item_id, parts,
+ show_item_cb, NULL, NULL);
+ g_main_loop_run (loop);
+ gnome_keyring_item_get_attributes (keyring, item_id,
+ print_attributes_cb, NULL, NULL);
+ g_main_loop_run (loop);
+}
+
+static void
+delete_item (char *keyring, guint32 item_id)
+{
+ gnome_keyring_item_delete (keyring, item_id,
+ ok_cb, "delete item", NULL);
+ g_main_loop_run (loop);
+}
+
+static void
+set_item_secret (char *keyring, guint32 item_id, char *secret)
+{
+ GnomeKeyringItemInfo *info;
+
+ info = gnome_keyring_item_info_new ();
+ gnome_keyring_item_info_set_secret (info, secret);
+ gnome_keyring_item_set_info (keyring, item_id, info,
+ ok_cb, "set item", NULL);
+ gnome_keyring_item_info_free (info);
+ g_main_loop_run (loop);
+}
+
+static void
+set_item_attribute (char *keyring, guint32 item_id, char *value)
+{
+ GnomeKeyringAttributeList *attributes;
+ GnomeKeyringAttribute attribute;
+
+ attribute.name = g_strdup ("testattribute");
+ attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+ attribute.value.string = g_strdup (value);
+
+ attributes = gnome_keyring_attribute_list_new ();
+ g_array_append_val (attributes, attribute);
+
+ gnome_keyring_item_set_attributes (keyring, item_id, attributes,
+ ok_cb, "set attributes", NULL);
+ gnome_keyring_attribute_list_free (attributes);
+ g_main_loop_run (loop);
+}
+
+static void
+create_keyring (char *name, char *password)
+{
+ gnome_keyring_create (name, password,
+ ok_cb, "create keyring", NULL);
+ g_main_loop_run (loop);
+}
+
+static void
+set_default (char *name)
+{
+ gnome_keyring_set_default_keyring (name,
+ ok_cb, "set default", NULL);
+ g_main_loop_run (loop);
+}
+
+static void
+set_network_cb (GnomeKeyringResult result,
+ guint32 id,
+ gpointer data)
+{
+ g_print ("set network password: res: %d id: %d\n", result, id);
+ g_main_loop_quit (loop);
+}
+
+
+static void
+set_network (char *server, char *password)
+{
+ gnome_keyring_set_network_password (NULL /* default keyring */,
+ NULL,
+ NULL,
+ server,
+ NULL,
+ "smb",
+ NULL,
+ 0,
+ password,
+ set_network_cb, NULL, NULL);
+ g_main_loop_run (loop);
+}
+
+static void
+set_network_sync (char *server, char *password)
+{
+ guint32 id;
+ GnomeKeyringResult res;
+ res = gnome_keyring_set_network_password_sync (NULL /* default keyring */,
+ NULL,
+ NULL,
+ server,
+ NULL,
+ "smb",
+ NULL,
+ 0,
+ password,
+ &id);
+ g_print ("set network password: res: %d id: %d\n", res, id);
+}
+
+static void
+find_network (char *server)
+{
+ GnomeKeyringResult res;
+ GList *list, *l;
+
+ list = NULL;
+ res = gnome_keyring_find_network_password_sync (NULL, NULL,
+ server, NULL,
+ "smb",
+ NULL,
+ 0,
+ &list);
+ g_print ("find network password, res: %d, len: %d\n", res, g_list_length (list));
+ for (l = list; l != NULL; l = l->next) {
+ GnomeKeyringNetworkPasswordData *data;
+ data = l->data;
+
+ g_print ("%s:%d - proto: %s, server: %s, object: %s, authtype: %s, port: %d, user: %s, domain: %s, password: %s\n",
+ data->keyring,
+ data->item_id,
+ data->protocol,
+ data->server,
+ data->object,
+ data->authtype,
+ data->port,
+ data->user,
+ data->domain,
+ data->password);
+ }
+}
+
+static void
+list_items_cb (GnomeKeyringResult result, GList *list, gpointer data)
+{
+ g_print ("list items: res: %d (%s)\n", result, get_msg_for_keyring_result (result));
+ for ( ; list; list = list->next)
+ g_print (" id: %d\n", GPOINTER_TO_UINT (list->data));
+ g_main_loop_quit (loop);
+}
+
+static void
+list_items (const char *keyring)
+{
+ gnome_keyring_list_item_ids (keyring, list_items_cb, NULL, NULL);
+ g_main_loop_run (loop);
+}
+
+int
+main (int argc, char *argv[])
+{
+ char arg;
+
+ g_set_application_name("test-keyring");
+ loop = g_main_loop_new (NULL, FALSE);
+
+ arg = 0;
+ if (argc >= 2) {
+ arg = argv[1][0];
+ }
+
+ if (arg == 'L') {
+ lock_all ();
+ } else if (arg == 'l') {
+ if (argc >= 3) {
+ lock (argv[2]);
+ } else {
+ lock (NULL);
+ }
+ } else if (arg == 'u') {
+ if (argc >= 4) {
+ unlock (argv[2], argv[3]);
+ } else {
+ g_print ("unlock requires keyring and password\n");
+ }
+ } else if (arg == 'c') {
+ if (argc >= 4) {
+ create_item (argv[2], argv[3], FALSE);
+ } else {
+ g_print ("create item requires item name and attr value\n");
+ }
+ } else if (arg == 'C') {
+ if (argc >= 4) {
+ create_item (argv[2], argv[3], TRUE);
+ } else {
+ g_print ("create item requires item name and attr value\n");
+ }
+
+ } else if (arg == 'A') {
+ if (argc >= 4) {
+ create_application_item (argv[2], argv[3], FALSE);
+ } else {
+ g_print ("create application item requires item name and attr value\n");
+ }
+
+ /* Show complete item information */
+ } else if (arg == 'i') {
+ if (argc >= 4) {
+ show_item (argv[2], atoi(argv[3]), GNOME_KEYRING_ITEM_INFO_SECRET);
+ } else {
+ g_print ("must give keyring & item id to show\n");
+ }
+
+ /* Show basic item information */
+ } else if (arg == 'b') {
+ if (argc >= 4) {
+ show_item (argv[2], atoi(argv[3]), GNOME_KEYRING_ITEM_INFO_BASICS);
+ } else {
+ g_print ("must give keyring & item id to show\n");
+ }
+ } else if (arg == 'd') {
+ if (argc >= 4) {
+ delete_item (argv[2] ,atoi (argv[3]));
+ } else {
+ g_print ("must give keyring & item id to delete\n");
+ }
+ } else if (arg == 's') {
+ if (argc >= 5) {
+ set_item_secret (argv[2] ,atoi (argv[3]), argv[4]);
+ } else {
+ g_print ("must give keyring & item id & secret\n");
+ }
+ } else if (arg == 'a') {
+ if (argc >= 5) {
+ set_item_attribute (argv[2] ,atoi (argv[3]), argv[4]);
+ } else {
+ g_print ("must give keyring & item id & attribute value\n");
+ }
+ } else if (arg == 'f') {
+ if (argc >= 3) {
+ find_items (argv[2]);
+ } else {
+ g_print ("must give testattribute value\n");
+ }
+ } else if (arg == 'k') {
+ if (argc >= 4) {
+ create_keyring (argv[2], argv[3]);
+ } else if (argc >= 3) {
+ create_keyring (argv[2], NULL);
+ } else {
+ g_print ("create keyring requires keyring name\n");
+ }
+ } else if (arg == 'D') {
+ if (argc >= 3) {
+ set_default (argv[2]);
+ } else {
+ set_default (NULL);
+ }
+ } else if (arg == 'n') {
+ if (argc >= 4) {
+ set_network (argv[2], argv[3]);
+ } else {
+ g_print ("need server & password\n");
+ }
+ } else if (arg == 'N') {
+ if (argc >= 4) {
+ set_network_sync (argv[2], argv[3]);
+ } else {
+ g_print ("need server & password\n");
+ }
+ } else if (arg == 'p') {
+ if (argc >= 3) {
+ find_network (argv[2]);
+ } else {
+ g_print ("need server\n");
+ }
+ } else if (arg == 't') {
+ g_print ("gnome keyring is: %s\n",
+ gnome_keyring_is_available ()?"available":"not available");
+ } else if (arg == 'I') {
+ if (argc >= 3) {
+ list_items(argv[2]);
+ } else {
+ g_print ("need keyring\n");
+ }
+ } else {
+ g_print ("unsupported test\n");
+ }
+
+
+ return 0;
+}