Use AM_CPPFLAGS instead of INCLUDES
[platform/upstream/libsecret.git] / libsecret / secret-schema.c
1 /* libsecret - GLib wrapper for Secret Service
2  *
3  * Copyright 2011 Collabora Ltd.
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: Stef Walter <stefw@gnome.org>
13  */
14
15 #include "config.h"
16
17 #include "secret-enum-types.h"
18 #include "secret-password.h"
19 #include "secret-private.h"
20 #include "secret-value.h"
21
22 #include <egg/egg-secure-memory.h>
23
24 /**
25  * SECTION:secret-schema
26  * @title: SecretSchema
27  * @short_description: Schema for defining which attributes are on items
28  *
29  * Each password is associated with a set of attributes. Attribute values can
30  * be either strings, integers or booleans.
31  *
32  * The names and types of allowed attributes for a given password are defined
33  * with a schema.
34  *
35  * Additional schemas can be defined via the %SecretSchema structure like this:
36  *
37  * <informalexample><programlisting language="c">
38  * /<!-- -->* in a header: *<!-- -->/
39  *
40  * const SecretSchema * example_get_schema (void) G_GNUC_CONST;
41  *
42  * #define EXAMPLE_SCHEMA  example_get_schema ()
43  *
44  *
45  * /<!-- -->* in a .c file: *<!-- -->/
46  *
47  * const SecretSchema *
48  * example_get_schema (void)
49  * {
50  *      static const SecretSchema the_schema = {
51  *              "org.example.Password", SECRET_SCHEMA_NONE,
52  *              {
53  *                      {  "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER },
54  *                      {  "string", SECRET_SCHEMA_ATTRIBUTE_STRING },
55  *                      {  "even", SECRET_SCHEMA_ATTRIBUTE_BOOLEAN },
56  *                      {  NULL, 0 },
57  *              }
58  *      };
59  *      return &the_schema;
60  * }
61  * </programlisting></informalexample>
62  *
63  * Stability: Stable
64  */
65
66 /**
67  * SecretSchema:
68  * @name: the dotted name of the schema
69  * @flags: flags for the schema
70  * @attributes: the attribute names and types of those attributes
71  *
72  * Represents a set of attributes that are stored with an item. These schemas
73  * are used for interoperability between various services storing the same types
74  * of items.
75  *
76  * Each schema has a name like "org.gnome.keyring.NetworkPassword", and defines
77  * a set of attributes, and types (string, integer, boolean) for those attributes.
78  *
79  * Attributes are stored as strings in the Secret Service, and the attribute
80  * types simply define standard ways to store integer and boolean values as strings.
81  * Attributes are represented in libsecret via a #GHashTable with string keys and
82  * values. Even for values that defined as an integer or boolean in the schema,
83  * the attribute values in the #GHashTable are strings. Boolean values are stored
84  * as the strings 'true' and 'false'. Integer values are stored in decimal, with
85  * a preceeding negative sign for negative integers.
86  *
87  * Schemas are handled entirely on the client side by this library. The name of the
88  * schema is automatically stored as an attribute on the item.
89  *
90  * Normally when looking up passwords only those with matching schema names are
91  * returned. If the schema @flags contain the %SECRET_SCHEMA_DONT_MATCH_NAME flag,
92  * then lookups will not check that the schema name matches that on the item, only
93  * the schema's attributes are matched. This is useful when you are looking up items
94  * that are not stored by the libsecret library. Other libraries such as libgnome-keyring
95  * don't store the schema name.
96  *
97  * Stability: Stable
98  */
99
100 /**
101  * SecretSchemaFlags:
102  * @SECRET_SCHEMA_NONE: no flags for the schema
103  * @SECRET_SCHEMA_DONT_MATCH_NAME: don't match the schema name when looking up or
104  *                                 removing passwords
105  *
106  * Flags for a #SecretSchema definition.
107  */
108
109 /**
110  * SecretSchemaAttribute:
111  * @name: name of the attribute
112  * @type: the type of the attribute
113  *
114  * An attribute in a #SecretSchema.
115  */
116
117 /**
118  * SecretSchemaAttributeType:
119  * @SECRET_SCHEMA_ATTRIBUTE_BOOLEAN: a boolean attribute, stored as 'true' or 'false'
120  * @SECRET_SCHEMA_ATTRIBUTE_INTEGER: an integer attribute, stored as a decimal
121  * @SECRET_SCHEMA_ATTRIBUTE_STRING: a utf-8 string attribute
122  *
123  * The type of an attribute in a #SecretSchema. Attributes are stored as strings
124  * in the Secret Service, and the attribute types simply define standard ways
125  * to store integer and boolean values as strings.
126  */
127
128 static SecretSchemaAttribute *
129 schema_attribute_copy (SecretSchemaAttribute *attribute)
130 {
131         SecretSchemaAttribute *copy;
132
133         copy = g_slice_new0 (SecretSchemaAttribute);
134         copy->name = g_strdup (attribute->name);
135         copy->type = attribute->type;
136
137         return copy;
138 }
139
140 static void
141 schema_attribute_free (SecretSchemaAttribute *attribute)
142 {
143         g_free ((gchar *)attribute->name);
144         g_slice_free (SecretSchemaAttribute, attribute);
145 }
146
147 G_DEFINE_BOXED_TYPE (SecretSchemaAttribute, secret_schema_attribute,
148                      schema_attribute_copy, schema_attribute_free);
149
150 /**
151  * secret_schema_newv:
152  * @name: the dotted name of the schema
153  * @flags: the flags for the schema
154  * @attribute_names_and_types: (element-type utf8 Secret.SchemaAttributeType): the attribute names and types of those attributes
155  *
156  * Using this function is not normally necessary from C code. This is useful
157  * for constructing #SecretSchema structures in bindings.
158  *
159  * A schema represents a set of attributes that are stored with an item. These
160  * schemas are used for interoperability between various services storing the
161  * same types of items.
162  *
163  * Each schema has an @name like "org.gnome.keyring.NetworkPassword", and
164  * defines a set of attributes names, and types (string, integer, boolean) for
165  * those attributes.
166  *
167  * Each key in the @attributes table should be a attribute name strings, and
168  * the values in the table should be integers from the #SecretSchemaAttributeType
169  * enumeration, representing the attribute type for each attribute name.
170  *
171  * Normally when looking up passwords only those with matching schema names are
172  * returned. If the schema @flags contain the %SECRET_SCHEMA_DONT_MATCH_NAME flag,
173  * then lookups will not check that the schema name matches that on the item, only
174  * the schema's attributes are matched. This is useful when you are looking up items
175  * that are not stored by the libsecret library. Other libraries such as libgnome-keyring
176  * don't store the schema name.
177  *
178  * Rename to: secret_schema_new
179  *
180  * Returns: (transfer full): the new schema, which should be unreferenced with
181  *          secret_schema_unref() when done
182  */
183 SecretSchema *
184 secret_schema_newv (const gchar *name,
185                     SecretSchemaFlags flags,
186                     GHashTable *attribute_names_and_types)
187 {
188         SecretSchema *schema;
189         GHashTableIter iter;
190         GEnumClass *enumc;
191         gpointer value;
192         gpointer key;
193         gint type;
194         gint ind = 0;
195
196         g_return_val_if_fail (name != NULL, NULL);
197         g_return_val_if_fail (attribute_names_and_types != NULL, NULL);
198
199         schema = g_slice_new0 (SecretSchema);
200         schema->name = g_strdup (name);
201         schema->flags = flags;
202         schema->reserved = 1;
203
204         if (attribute_names_and_types) {
205                 g_hash_table_iter_init (&iter, attribute_names_and_types);
206                 while (g_hash_table_iter_next (&iter, &key, &value)) {
207
208                         if (ind >= G_N_ELEMENTS (schema->attributes)) {
209                                 g_warning ("too many attributes for schema, max %d",
210                                            (gint) G_N_ELEMENTS (schema->attributes));
211                                 break;
212                         }
213
214                         type = GPOINTER_TO_INT (value);
215
216                         enumc = G_ENUM_CLASS (g_type_class_ref (SECRET_TYPE_SCHEMA_ATTRIBUTE_TYPE));
217                         if (!g_enum_get_value (enumc, type)) {
218                                 g_warning ("invalid type for attribute %s", (gchar *)key);
219                                 type = -1;
220                         }
221
222                         g_type_class_unref (enumc);
223
224                         if (type >= 0) {
225                                 schema->attributes[ind].name = g_strdup (key);
226                                 schema->attributes[ind].type = type;
227                         }
228
229                         ind++;
230                 }
231         }
232
233         return schema;
234 }
235
236 /**
237  * secret_schema_new: (skip)
238  * @name: the dotted name of the schema
239  * @flags: the flags for the schema
240  * @...: the attribute names and types, terminated with %NULL
241  *
242  * Using this function is not normally necessary from C code.
243  *
244  * A schema represents a set of attributes that are stored with an item. These
245  * schemas are used for interoperability between various services storing the
246  * same types of items.
247  *
248  * Each schema has an @name like "org.gnome.keyring.NetworkPassword", and
249  * defines a set of attributes names, and types (string, integer, boolean) for
250  * those attributes.
251  *
252  * The variable argument list should contain pairs of a) The attribute name as
253  * a null-terminated string, followed by b) integers from the
254  * #SecretSchemaAttributeType enumeration, representing the attribute type for
255  * each attribute name. The list of attribtues should be terminated with a %NULL.
256  *
257  * Normally when looking up passwords only those with matching schema names are
258  * returned. If the schema @flags contain the %SECRET_SCHEMA_DONT_MATCH_NAME flag,
259  * then lookups will not check that the schema name matches that on the item, only
260  * the schema's attributes are matched. This is useful when you are looking up items
261  * that are not stored by the libsecret library. Other libraries such as libgnome-keyring
262  * don't store the schema name.
263  *
264  * Returns: (transfer full): the new schema, which should be unreferenced with
265  *          secret_schema_unref() when done
266  */
267 SecretSchema *
268 secret_schema_new (const gchar *name,
269                    SecretSchemaFlags flags,
270                    ...)
271 {
272         SecretSchemaAttributeType type;
273         GHashTable *attributes;
274         SecretSchema *schema;
275         const gchar *attribute;
276         va_list va;
277
278         g_return_val_if_fail (name != NULL, NULL);
279
280         va_start (va, flags);
281         attributes = g_hash_table_new (g_str_hash, g_str_equal);
282
283         while ((attribute = va_arg (va, const gchar *)) != NULL) {
284                 type = va_arg (va, SecretSchemaAttributeType);
285                 g_hash_table_insert (attributes, (gpointer *)attribute,
286                                      GINT_TO_POINTER (type));
287         }
288
289         schema = secret_schema_newv (name, flags, attributes);
290
291         g_hash_table_unref (attributes);
292         va_end (va);
293
294         return schema;
295 }
296
297 /**
298  * secret_schema_ref:
299  * @schema: the schema to reference
300  *
301  * Adds a reference to the #SecretSchema.
302  *
303  * It is not normally necessary to call this function from C code, and is
304  * mainly present for the sake of bindings. If the @schema was statically
305  * allocated, then this function will copy the schema.
306  *
307  * Returns: (transfer full): the referenced schema, which should be later
308  *          unreferenced with secret_schema_unref()
309  */
310 SecretSchema *
311 secret_schema_ref (SecretSchema *schema)
312 {
313         SecretSchema *result;
314         gint i;
315
316         g_return_val_if_fail (schema != NULL, NULL);
317
318         /* If it's static, then copy it */
319         if (g_atomic_int_get (&schema->reserved) > 0) {
320                 g_atomic_int_inc (&schema->reserved);
321                 result = schema;
322         } else {
323                 result = g_slice_new0 (SecretSchema);
324                 result->reserved = 1;
325                 result->name = g_strdup (schema->name);
326
327                 for (i = 0; i < G_N_ELEMENTS (schema->attributes); i++) {
328                         result->attributes[i].name = g_strdup (schema->attributes[i].name);
329                         result->attributes[i].type = schema->attributes[i].type;
330                 }
331         }
332
333         return result;
334 }
335
336 const SecretSchema *
337 _secret_schema_ref_if_nonstatic (const SecretSchema *schema)
338 {
339         if (schema && g_atomic_int_get (&schema->reserved) > 0)
340                 secret_schema_ref ((SecretSchema *)schema);
341
342         return schema;
343 }
344
345 /**
346  * secret_schema_unref:
347  * @schema: the schema to reference
348  *
349  * Releases a reference to the #SecretSchema. If the last reference is
350  * released then the schema will be freed.
351  *
352  * It is not normally necessary to call this function from C code, and is
353  * mainly present for the sake of bindings. It is an error to call this for
354  * a @schema that was statically allocated.
355  */
356 void
357 secret_schema_unref (SecretSchema *schema)
358 {
359         gint refs;
360         gint i;
361
362         g_return_if_fail (schema != NULL);
363
364         refs = g_atomic_int_add (&schema->reserved, -1);
365         if (refs < 0) {
366                 g_warning ("should not unreference a static or invalid SecretSchema");
367
368         } else if (refs == 0) {
369                 g_free ((gpointer)schema->name);
370                 for (i = 0; i < G_N_ELEMENTS (schema->attributes); i++)
371                         g_free ((gpointer)schema->attributes[i].name);
372                 g_slice_free (SecretSchema, schema);
373         }
374 }
375
376 void
377 _secret_schema_unref_if_nonstatic (const SecretSchema *schema)
378 {
379         if (schema && g_atomic_int_get (&schema->reserved) > 0)
380                 secret_schema_unref ((SecretSchema *)schema);
381 }
382
383 G_DEFINE_BOXED_TYPE (SecretSchema, secret_schema, secret_schema_ref, secret_schema_unref);