1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
/* gkr-keyring-item.c - represents an item in a keyring
4
Copyright (C) 2007 Stefan walter
6
The Gnome Keyring Library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Library General Public License as
8
published by the Free Software Foundation; either version 2 of the
9
License, or (at your option) any later version.
11
The Gnome Keyring Library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Library General Public License for more details.
16
You should have received a copy of the GNU Library General Public
17
License along with the Gnome Library; see the file COPYING.LIB. If not,
18
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
Boston, MA 02111-1307, USA.
21
Author: Stef Walter <stef@memberwebs.com>
26
#include "gkr-keyring-item.h"
27
#include "gkr-keyring.h"
29
#include "egg/egg-secure-memory.h"
42
G_DEFINE_TYPE (GkrKeyringItem, gkr_keyring_item, G_TYPE_OBJECT);
44
/* -----------------------------------------------------------------------------
51
/* Just random 32bit hash. Security here is not very important */
52
return 0x18273645 ^ x ^ (x << 16 | x >> 16);
56
md5_digest_to_ascii (unsigned char digest[16])
58
static char hex_digits[] = "0123456789abcdef";
64
for (i = 0; i < 16; i++) {
65
res[2*i] = hex_digits[digest[i] >> 4];
66
res[2*i+1] = hex_digits[digest[i] & 0xf];
74
hash_string (const char *str)
81
/* In case the world changes on us... */
82
g_return_val_if_fail (gcry_md_get_algo_dlen (GCRY_MD_MD5) == sizeof (digest), NULL);
84
gcry_md_hash_buffer (GCRY_MD_MD5, (void*)digest, str, strlen (str));
85
return md5_digest_to_ascii (digest);
88
/* -----------------------------------------------------------------------------
93
gkr_keyring_item_init (GkrKeyringItem *item)
99
gkr_keyring_item_get_property (GObject *obj, guint prop_id, GValue *value,
102
GkrKeyringItem *item = GKR_KEYRING_ITEM (obj);
106
g_value_set_string (value, item->display_name ? item->display_name : "");
112
gkr_keyring_item_dispose (GObject *obj)
114
GkrKeyringItem *item = GKR_KEYRING_ITEM (obj);
117
g_object_remove_weak_pointer (G_OBJECT (item->keyring),
118
(gpointer*)&(item->keyring));
119
item->keyring = NULL;
122
G_OBJECT_CLASS (gkr_keyring_item_parent_class)->dispose (obj);
126
gkr_keyring_item_finalize (GObject *obj)
128
GkrKeyringItem *item = GKR_KEYRING_ITEM (obj);
130
gnome_keyring_attribute_list_free (item->attributes);
131
if (item->acl != NULL)
132
gnome_keyring_acl_free (item->acl);
133
g_free (item->display_name);
134
egg_secure_strfree (item->secret);
136
G_OBJECT_CLASS (gkr_keyring_item_parent_class)->finalize (obj);
140
gkr_keyring_item_class_init (GkrKeyringItemClass *klass)
142
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
144
gkr_keyring_item_parent_class = g_type_class_peek_parent (klass);
146
gobject_class->get_property = gkr_keyring_item_get_property;
147
gobject_class->dispose = gkr_keyring_item_dispose;
148
gobject_class->finalize = gkr_keyring_item_finalize;
150
g_object_class_install_property (gobject_class, PROP_NAME,
151
g_param_spec_string ("name", "Name", "Item Name",
152
NULL, G_PARAM_READABLE));
155
/* -----------------------------------------------------------------------------
160
gkr_keyring_item_new (GkrKeyring* keyring, guint id, GnomeKeyringItemType type)
162
GkrKeyringItem *item = g_object_new (GKR_TYPE_KEYRING_ITEM, NULL);
164
/* TODO: These should move into properties */
166
g_assert (GKR_IS_KEYRING (keyring));
168
item->keyring = keyring;
171
item->attributes = gnome_keyring_attribute_list_new ();
173
/* Make sure we get disconnected when keyring goes away */
174
g_object_add_weak_pointer (G_OBJECT (item->keyring), (gpointer*)&(item->keyring));
180
gkr_keyring_item_create (GkrKeyring* keyring, GnomeKeyringItemType type)
182
GkrKeyringItem *item;
185
g_assert (!keyring->locked);
187
id = gkr_keyring_get_new_id (keyring);
188
g_return_val_if_fail (id != 0, NULL);
190
item = gkr_keyring_item_new (keyring, id, type);
191
item->locked = keyring->locked;
192
item->ctime = item->mtime = time (NULL);
199
gkr_keyring_item_clone (GkrKeyring* new_keyring, GkrKeyringItem *item)
201
GkrKeyringItem *nitem = g_object_new (GKR_TYPE_KEYRING_ITEM, NULL);
203
g_return_val_if_fail (GKR_IS_KEYRING (new_keyring), NULL);
204
g_return_val_if_fail (GKR_IS_KEYRING_ITEM (item), NULL);
206
nitem->keyring = new_keyring;
207
nitem->id = gkr_keyring_get_new_id (new_keyring);
208
nitem->locked = item->locked;
210
nitem->type = item->type;
211
nitem->secret = egg_secure_strdup (item->secret);
212
nitem->display_name = g_strdup (item->display_name);
214
nitem->attributes = gnome_keyring_attribute_list_copy (item->attributes);
215
nitem->acl = gnome_keyring_acl_copy (item->acl);
217
nitem->ctime = item->ctime;
218
nitem->mtime = item->mtime;
220
/* Make sure we get disconnected when keyring goes away */
221
g_object_add_weak_pointer (G_OBJECT (item->keyring), (gpointer*)&(item->keyring));
227
gkr_keyring_item_merge (GkrKeyringItem* merged, GkrKeyringItem* item)
229
GnomeKeyringAttributeList *attributes;
230
GnomeKeyringAttribute *attribute;
233
attributes = item->attributes;
234
for (i = 0; i < attributes->len; i++) {
235
attribute = &gnome_keyring_attribute_list_index (attributes, i);
236
gkr_attribute_list_set (merged->attributes, attribute);
241
gkr_keyring_item_match (GkrKeyringItem *item, GnomeKeyringItemType type,
242
GnomeKeyringAttributeList *attributes, gboolean match_all)
245
GnomeKeyringAttribute *item_attribute;
246
GnomeKeyringAttribute *attribute;
248
int attributes_matching;
250
if ((item->type & GNOME_KEYRING_ITEM_TYPE_MASK) != (type & GNOME_KEYRING_ITEM_TYPE_MASK))
253
attributes_matching = 0;
254
for (i = 0; i < attributes->len; i++) {
256
attribute = &g_array_index (attributes,
257
GnomeKeyringAttribute,
259
for (j = 0; j < item->attributes->len; j++) {
260
item_attribute = &g_array_index (item->attributes,
261
GnomeKeyringAttribute,
263
if (strcmp (attribute->name, item_attribute->name) == 0) {
265
attributes_matching++;
266
if (attribute->type != item_attribute->type) {
269
switch (attribute->type) {
270
case GNOME_KEYRING_ATTRIBUTE_TYPE_STRING:
271
if (attribute->value.string != item_attribute->value.string) {
272
if (attribute->value.string == NULL || item_attribute->value.string == NULL)
274
if (strcmp (attribute->value.string, item_attribute->value.string) != 0)
278
case GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32:
279
if (attribute->value.integer != item_attribute->value.integer) {
284
g_assert_not_reached ();
293
return attributes_matching == attributes->len;
299
/* -----------------------------------------------------------------------------
300
* ATTRIBUTE LIST FUNCTIONS
304
gkr_attribute_list_set (GnomeKeyringAttributeList *attrs, GnomeKeyringAttribute *attr)
306
GnomeKeyringAttribute *set;
307
GnomeKeyringAttribute last;
308
gchar *tofree = NULL;
310
g_return_if_fail (attrs);
311
g_return_if_fail (attr);
312
g_return_if_fail (attr->name);
314
set = gkr_attribute_list_find (attrs, attr->name);
316
/* Found, appropriate for our own uses */
318
if (set->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
319
tofree = set->value.string;
320
set->value.string = NULL;
323
/* Not found, add a new one to the end */
325
memset (&last, 0, sizeof (last));
326
g_array_append_val (attrs, last);
327
set = &g_array_index (attrs, GnomeKeyringAttribute, attrs->len - 1);
328
set->name = g_strdup (attr->name);
331
/* Set the actual value */
332
set->type = attr->type;
333
switch (attr->type) {
334
case GNOME_KEYRING_ATTRIBUTE_TYPE_STRING:
335
set->value.string = g_strdup (attr->value.string);
337
case GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32:
338
set->value.integer = attr->value.integer;
341
g_assert_not_reached ();
347
GnomeKeyringAttribute*
348
gkr_attribute_list_find (GnomeKeyringAttributeList *attrs, const gchar *name)
350
GnomeKeyringAttribute *attr;
353
g_return_val_if_fail (attrs, NULL);
354
g_return_val_if_fail (name, NULL);
356
for (i = 0; i < attrs->len; i++) {
357
attr = &gnome_keyring_attribute_list_index (attrs, i);
358
g_return_val_if_fail (attr->name, NULL);
359
if (strcmp (attr->name, name) == 0)
367
gkr_attribute_list_delete (GnomeKeyringAttributeList *attrs, const gchar *name)
369
GnomeKeyringAttribute *attr;
372
g_return_if_fail (attrs);
373
g_return_if_fail (name);
375
for (i = 0; i < attrs->len; i++) {
376
attr = &gnome_keyring_attribute_list_index (attrs, i);
377
g_return_if_fail (attr->name);
378
if (strcmp (attr->name, name) == 0) {
379
g_array_remove_index_fast (attrs, i);
385
GnomeKeyringAttributeList *
386
gkr_attribute_list_hash (GnomeKeyringAttributeList *attributes)
388
GnomeKeyringAttributeList *hashed;
389
GnomeKeyringAttribute *orig_attribute;
390
GnomeKeyringAttribute attribute;
393
hashed = g_array_new (FALSE, FALSE, sizeof (GnomeKeyringAttribute));
394
for (i = 0; i < attributes->len; i++) {
395
orig_attribute = &gnome_keyring_attribute_list_index (attributes, i);
396
attribute.name = g_strdup (orig_attribute->name);
397
attribute.type = orig_attribute->type;
398
switch (attribute.type) {
399
case GNOME_KEYRING_ATTRIBUTE_TYPE_STRING:
400
attribute.value.string = hash_string (orig_attribute->value.string);
402
case GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32:
403
attribute.value.integer = hash_int (orig_attribute->value.integer);
406
g_assert_not_reached ();
408
g_array_append_val (hashed, attribute);