Branch data Line data Source code
1 : : /* libsecret - GLib wrapper for Secret Service
2 : : *
3 : : * Copyright 2019 Red Hat, Inc.
4 : : *
5 : : * This program is free software: you can redistribute it and/or modify
6 : : * it under the terms of the GNU Lesser General Public License as published
7 : : * by the Free Software Foundation; either version 2.1 of the licence or (at
8 : : * your option) any later version.
9 : : *
10 : : * See the included COPYING file for more information.
11 : : *
12 : : * Author: Daiki Ueno
13 : : */
14 : :
15 : : #include "config.h"
16 : :
17 : : #include "secret-file-item.h"
18 : : #include "secret-retrievable.h"
19 : : #include "secret-value.h"
20 : :
21 : : struct _SecretFileItem
22 : : {
23 : : GObject parent;
24 : : GHashTable *attributes;
25 : : gchar *label;
26 : : guint64 created;
27 : : guint64 modified;
28 : : SecretValue *value;
29 : : GVariant *encrypted;
30 : : };
31 : :
32 : : static void secret_file_item_retrievable_iface (SecretRetrievableInterface *iface);
33 : :
34 [ + + + - : 220 : G_DEFINE_TYPE_WITH_CODE (SecretFileItem, secret_file_item, G_TYPE_OBJECT,
+ + ]
35 : : G_IMPLEMENT_INTERFACE (SECRET_TYPE_RETRIEVABLE, secret_file_item_retrievable_iface);
36 : : );
37 : :
38 : : enum {
39 : : PROP_0,
40 : : PROP_ATTRIBUTES,
41 : : PROP_LABEL,
42 : : PROP_CREATED,
43 : : PROP_MODIFIED,
44 : : PROP_VALUE
45 : : };
46 : :
47 : : static void
48 : 23 : secret_file_item_init (SecretFileItem *self)
49 : : {
50 : 23 : }
51 : :
52 : : static void
53 : 115 : secret_file_item_set_property (GObject *object,
54 : : guint prop_id,
55 : : const GValue *value,
56 : : GParamSpec *pspec)
57 : : {
58 : 115 : SecretFileItem *self = SECRET_FILE_ITEM (object);
59 : :
60 [ + + + + : 115 : switch (prop_id) {
+ - ]
61 : 23 : case PROP_ATTRIBUTES:
62 : 23 : self->attributes = g_value_dup_boxed (value);
63 : 23 : break;
64 : 23 : case PROP_LABEL:
65 : 23 : self->label = g_value_dup_string (value);
66 : 23 : break;
67 : 23 : case PROP_CREATED:
68 : 23 : self->created = g_value_get_uint64 (value);
69 : 23 : break;
70 : 23 : case PROP_MODIFIED:
71 : 23 : self->modified = g_value_get_uint64 (value);
72 : 23 : break;
73 : 23 : case PROP_VALUE:
74 : 23 : self->value = g_value_dup_boxed (value);
75 : 23 : break;
76 : 0 : default:
77 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
78 : 0 : break;
79 : : }
80 : 115 : }
81 : :
82 : : static void
83 : 27 : secret_file_item_get_property (GObject *object,
84 : : guint prop_id,
85 : : GValue *value,
86 : : GParamSpec *pspec)
87 : : {
88 : 27 : SecretFileItem *self = SECRET_FILE_ITEM (object);
89 : :
90 [ + + + + : 27 : switch (prop_id) {
- ]
91 : 6 : case PROP_ATTRIBUTES:
92 : 6 : g_value_set_boxed (value, self->attributes);
93 : 6 : break;
94 : 8 : case PROP_LABEL:
95 : 8 : g_value_set_string (value, self->label);
96 : 8 : break;
97 : 7 : case PROP_CREATED:
98 : 7 : g_value_set_uint64 (value, self->created);
99 : 7 : break;
100 : 6 : case PROP_MODIFIED:
101 : 6 : g_value_set_uint64 (value, self->modified);
102 : 6 : break;
103 : 0 : default:
104 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
105 : 0 : break;
106 : : }
107 : 27 : }
108 : :
109 : : static void
110 : 23 : secret_file_item_finalize (GObject *object)
111 : : {
112 : 23 : SecretFileItem *self = SECRET_FILE_ITEM (object);
113 : :
114 : 23 : g_hash_table_unref (self->attributes);
115 : 23 : g_free (self->label);
116 : 23 : secret_value_unref (self->value);
117 : 23 : G_OBJECT_CLASS (secret_file_item_parent_class)->finalize (object);
118 : 23 : }
119 : :
120 : : static void
121 : 11 : secret_file_item_class_init (SecretFileItemClass *klass)
122 : : {
123 : 11 : GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
124 : 11 : gobject_class->set_property = secret_file_item_set_property;
125 : 11 : gobject_class->get_property = secret_file_item_get_property;
126 : 11 : gobject_class->finalize = secret_file_item_finalize;
127 : :
128 : 11 : g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
129 : 11 : g_object_class_override_property (gobject_class, PROP_LABEL, "label");
130 : 11 : g_object_class_override_property (gobject_class, PROP_CREATED, "created");
131 : 11 : g_object_class_override_property (gobject_class, PROP_MODIFIED, "modified");
132 : 11 : g_object_class_install_property (gobject_class, PROP_VALUE,
133 : : g_param_spec_boxed ("value", "Value", "Value",
134 : : SECRET_TYPE_VALUE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
135 : 11 : }
136 : :
137 : : static void
138 : 10 : secret_file_item_retrieve_secret (SecretRetrievable *retrievable,
139 : : GCancellable *cancellable,
140 : : GAsyncReadyCallback callback,
141 : : gpointer user_data)
142 : : {
143 : 10 : SecretFileItem *self = SECRET_FILE_ITEM (retrievable);
144 : 10 : GTask *task = g_task_new (retrievable, cancellable, callback, user_data);
145 : :
146 : 10 : g_task_return_pointer (task,
147 : 10 : secret_value_ref (self->value),
148 : : secret_value_unref);
149 : 10 : g_object_unref (task);
150 : 10 : }
151 : :
152 : : static SecretValue *
153 : 10 : secret_file_item_retrieve_secret_finish (SecretRetrievable *retrievable,
154 : : GAsyncResult *result,
155 : : GError **error)
156 : : {
157 [ - + ]: 10 : g_return_val_if_fail (g_task_is_valid (result, retrievable), NULL);
158 : :
159 : 10 : return g_task_propagate_pointer (G_TASK (result), error);
160 : : }
161 : :
162 : : static void
163 : 11 : secret_file_item_retrievable_iface (SecretRetrievableInterface *iface)
164 : : {
165 : 11 : iface->retrieve_secret = secret_file_item_retrieve_secret;
166 : 11 : iface->retrieve_secret_finish = secret_file_item_retrieve_secret_finish;
167 : 11 : }
168 : :
169 : : static GHashTable *
170 : 11 : variant_to_attributes (GVariant *variant)
171 : : {
172 : : GVariantIter iter;
173 : : gchar *key;
174 : : gchar *value;
175 : : GHashTable *attributes;
176 : :
177 : 11 : attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
178 : : g_free, g_free);
179 : :
180 : 11 : g_variant_iter_init (&iter, variant);
181 [ + + ]: 30 : while (g_variant_iter_next (&iter, "{ss}", &key, &value))
182 : 19 : g_hash_table_insert (attributes, key, value);
183 : :
184 : 11 : return attributes;
185 : : }
186 : :
187 : : SecretFileItem *
188 : 11 : secret_file_item_deserialize (GVariant *serialized)
189 : : {
190 : : GVariant *attributes_variant;
191 : : GHashTable *attributes;
192 : : const gchar *label;
193 : : guint64 created;
194 : : guint64 modified;
195 : : GVariant *array;
196 : : const gchar *secret;
197 : : gsize n_secret;
198 : : SecretValue *value;
199 : : SecretFileItem *result;
200 : :
201 : 11 : g_variant_get (serialized, "(@a{ss}&stt@ay)",
202 : : &attributes_variant, &label, &created, &modified, &array);
203 : :
204 : 11 : secret = g_variant_get_fixed_array (array, &n_secret, sizeof(gchar));
205 : 11 : value = secret_value_new (secret, n_secret, "text/plain");
206 : :
207 : 11 : attributes = variant_to_attributes (attributes_variant);
208 : 11 : g_variant_unref (attributes_variant);
209 : :
210 : 11 : result = g_object_new (SECRET_TYPE_FILE_ITEM,
211 : : "attributes", attributes,
212 : : "label", label,
213 : : "created", created,
214 : : "modified", modified,
215 : : "value", value,
216 : : NULL);
217 : 11 : g_hash_table_unref (attributes);
218 : 11 : g_variant_unref (array);
219 : 11 : secret_value_unref (value);
220 : :
221 : 11 : return result;
222 : : }
223 : :
224 : : GVariant *
225 : 12 : secret_file_item_serialize (SecretFileItem *self)
226 : : {
227 : : GVariantBuilder builder;
228 : : GHashTableIter iter;
229 : : gpointer key;
230 : : gpointer value;
231 : : GVariant *variant;
232 : : const gchar *secret;
233 : : gsize n_secret;
234 : :
235 : 12 : g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
236 : 12 : g_hash_table_iter_init (&iter, self->attributes);
237 [ + + ]: 41 : while (g_hash_table_iter_next (&iter, &key, &value))
238 : 29 : g_variant_builder_add (&builder, "{ss}", key, value);
239 : :
240 : 12 : secret = secret_value_get (self->value, &n_secret);
241 : 12 : variant = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
242 : : secret, n_secret, sizeof(guint8));
243 : :
244 : 12 : variant = g_variant_new ("(@a{ss}stt@ay)",
245 : : g_variant_builder_end (&builder),
246 : : self->label,
247 : : self->created,
248 : : self->modified,
249 : : variant);
250 : 12 : g_variant_get_data (variant); /* force serialize */
251 : 12 : return g_variant_ref_sink (variant);
252 : : }
|