docs: add documentation for GSignondStorageManager
[platform/upstream/gsignond.git] / src / common / gsignond-storage-manager.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of gsignond
5  *
6  * Copyright (C) 2012 Intel Corporation.
7  *
8  * Contact: Jussi Laako <jussi.laako@linux.intel.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  */
25
26 #include <sys/stat.h>
27
28 #include <glib/gstdio.h>
29
30 #include "gsignond/gsignond-log.h"
31 #include "gsignond/gsignond-storage-manager.h"
32 #include "gsignond/gsignond-utils.h"
33
34 /**
35  * SECTION:gsignond-storage-manager
36  * @short_description: manages encrypted disk storage for storing the secret database
37  * @include: gsignond/gsignond-plugin-interface.h
38  *
39  * #GSignondStorageManager manages encrypted disk storage for storing the secret
40  * database (as provided by #GSignondSecretStorage). The default implementation
41  * is a stub that does nothing, but gSSO can be configured to use a custom extension
42  * that provides a subclassed implementation of #GSignondStorageManager
43  * (see #GSignondExtension for instructions and pointers to examples).
44  */
45 /**
46  * GSignondStorageManager:
47  *
48  * Opaque #GSignondStorageManager data structure.
49  */
50  
51
52 #define GSIGNOND_STORAGE_MANAGER_GET_PRIVATE(obj) \
53     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
54                                   GSIGNOND_TYPE_STORAGE_MANAGER, \
55                                   GSignondStorageManagerPrivate))
56
57 struct _GSignondStorageManagerPrivate
58 {
59 };
60
61 enum
62 {
63     PROP_0,
64     PROP_CONFIG,
65     N_PROPERTIES
66 };
67
68 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
69
70 G_DEFINE_TYPE (GSignondStorageManager, gsignond_storage_manager, G_TYPE_OBJECT);
71
72 static void
73 _set_config (GSignondStorageManager *self, GSignondConfig *config)
74 {
75     g_assert (self->config == NULL);
76     self->config = config;
77
78     const gchar *secure_dir = gsignond_config_get_string (
79                                         self->config,
80                                         GSIGNOND_CONFIG_GENERAL_SECURE_DIR);
81     if (secure_dir)
82         self->location = g_build_filename (secure_dir,
83                                            "gsignond.secret",
84                                            NULL);
85     else
86         self->location = g_build_filename (g_get_user_data_dir (),
87                                            "gsignond.secret",
88                                            NULL);
89     DBG ("secure dir %s", self->location);
90 }
91
92 static void
93 _set_property (GObject *object, guint prop_id, const GValue *value,
94                GParamSpec *pspec)
95 {
96     GSignondStorageManager *self =
97         GSIGNOND_STORAGE_MANAGER (object);
98
99     switch (prop_id) {
100         case PROP_CONFIG:
101             g_assert (self->config == NULL);
102             _set_config (self, GSIGNOND_CONFIG (g_value_dup_object (value)));
103             break;
104         default:
105             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
106     }
107 }
108
109 static void
110 _get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
111 {
112     GSignondStorageManager *self =
113         GSIGNOND_STORAGE_MANAGER (object);
114
115     switch (prop_id) {
116         case PROP_CONFIG:
117             g_value_set_object (value, self->config);
118             break;
119         default:
120             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
121     }
122 }
123
124 static void
125 _dispose (GObject *object)
126 {
127     GSignondStorageManager *self =
128         GSIGNOND_STORAGE_MANAGER (object);
129
130     /* unmount mounted filesystem */
131     if (gsignond_storage_manager_filesystem_is_mounted (self)) {
132         gsignond_storage_manager_unmount_filesystem (self);
133     }
134
135     if (self->config) {
136         g_object_unref (self->config);
137         self->config = NULL;
138     }
139
140     G_OBJECT_CLASS (gsignond_storage_manager_parent_class)->dispose (object);
141 }
142
143 static void
144 _finalize (GObject *object)
145 {
146     GSignondStorageManager *self = 
147         GSIGNOND_STORAGE_MANAGER (object);
148
149     if (self->location) {
150         g_free (self->location);
151         self->location = NULL;
152     }
153
154     G_OBJECT_CLASS (gsignond_storage_manager_parent_class)->finalize (object);
155 }
156
157 static gboolean
158 _initialize_storage (GSignondStorageManager *self)
159 {
160     g_return_val_if_fail (self != NULL, FALSE);
161     g_return_val_if_fail (self->location, FALSE);
162
163     if (g_mkdir_with_parents (self->location, S_IRWXU))
164         return FALSE;
165
166     return TRUE;
167 }
168
169 static gboolean
170 _delete_storage (GSignondStorageManager *self)
171 {
172     g_return_val_if_fail (self != NULL, FALSE);
173     g_return_val_if_fail (self->location, FALSE);
174
175     return gsignond_wipe_directory (self->location);
176 }
177
178 static gboolean
179 _storage_is_initialized (GSignondStorageManager *self)
180 {
181     g_return_val_if_fail (self != NULL, FALSE);
182     g_return_val_if_fail (self->location, FALSE);
183
184     if (g_access (self->location, 0))  /* 0 should equal to F_OK */
185         return FALSE;
186
187     return TRUE;
188 }
189
190 static const gchar *
191 _mount_filesystem (GSignondStorageManager *self)
192 {
193     g_return_val_if_fail (self != NULL, NULL);
194
195     return self->location;
196 }
197
198 static gboolean
199 _unmount_filesystem (GSignondStorageManager *self)
200 {
201     g_return_val_if_fail (self != NULL, FALSE);
202
203     return TRUE;
204 }
205
206 static gboolean
207 _filesystem_is_mounted (GSignondStorageManager *self)
208 {
209     return _storage_is_initialized (self);
210 }
211
212 /**
213  * GSignondStorageManagerClass:
214  * @parent_class: parent class.
215  * @initialize_storage: an implementation of gsignond_storage_manager_initialize_storage()
216  * @delete_storage: an implementation of gsignond_storage_manager_delete_storage()
217  * @storage_is_initialized: an implementation of gsignond_storage_manager_storage_is_initialized()
218  * @mount_filesystem: an implementation of gsignond_storage_manager_mount_filesystem()
219  * @unmount_filesystem: an implementation of gsignond_storage_manager_unmount_filesystem()
220  * @filesystem_is_mounted: an implementation of gsignond_storage_manager_filesystem_is_mounted()
221  * 
222  * #GSignondStorageManagerClass class containing pointers to class methods.
223  */
224 static void
225 gsignond_storage_manager_class_init (GSignondStorageManagerClass *klass)
226 {
227     GObjectClass *base = G_OBJECT_CLASS (klass);
228
229     base->set_property = _set_property;
230     base->get_property = _get_property;
231     base->dispose = _dispose;
232     base->finalize = _finalize;
233     properties[PROP_CONFIG] = g_param_spec_object ("config",
234                                                    "config",
235                                                    "Configuration object",
236                                                    GSIGNOND_TYPE_CONFIG,
237                                                    G_PARAM_CONSTRUCT_ONLY|
238                                                    G_PARAM_READWRITE|
239                                                    G_PARAM_STATIC_STRINGS);
240     g_object_class_install_properties (base, N_PROPERTIES, properties);
241
242     /*g_type_class_add_private (klass, sizeof(GSignondStorageManagerPrivate));*/
243  
244     klass->initialize_storage = _initialize_storage;
245     klass->delete_storage = _delete_storage;
246     klass->storage_is_initialized = _storage_is_initialized;
247     klass->mount_filesystem = _mount_filesystem;
248     klass->unmount_filesystem = _unmount_filesystem;
249     klass->filesystem_is_mounted = _filesystem_is_mounted;
250 }
251
252 static void
253 gsignond_storage_manager_init (GSignondStorageManager *self)
254 {
255     /*self->priv = GSIGNOND_STORAGE_MANAGER_GET_PRIVATE (self);*/
256
257     self->location = NULL;
258     self->config = NULL;
259 }
260
261 /**
262  * gsignond_storage_manager_initialize_storage:
263  * @self: object instance.
264  *
265  * Initialize encryption storage. This means making sure that the 
266  * necessary directories exist and are accessible.
267  *
268  * Returns: success?
269  */
270 gboolean
271 gsignond_storage_manager_initialize_storage (GSignondStorageManager *self)
272 {
273     return GSIGNOND_STORAGE_MANAGER_GET_CLASS (self)->
274         initialize_storage (self);
275 }
276
277 /**
278  * gsignond_storage_manager_delete_storage:
279  * @self: object instance.
280  *
281  * Destroys all the encryption keys and wipes the storage. gsignond_wipe_directory()
282  * is typically used for the latter.
283  *
284  * Returns: success?
285  */
286 gboolean
287 gsignond_storage_manager_delete_storage (GSignondStorageManager *self)
288 {
289     return GSIGNOND_STORAGE_MANAGER_GET_CLASS (self)->
290         delete_storage (self);
291 }
292
293 /**
294  * gsignond_storage_manager_storage_is_initialized:
295  * @self: object instance.
296  *
297  * Checks if the storage has been initialized.
298  *
299  * Returns: storage has been initialized?
300  */
301 gboolean
302 gsignond_storage_manager_storage_is_initialized (GSignondStorageManager *self)
303 {
304     return GSIGNOND_STORAGE_MANAGER_GET_CLASS (self)->
305         storage_is_initialized (self);
306 }
307
308 /**
309  * gsignond_storage_manager_mount_filesystem:
310  * @self: object instance.
311  *
312  * Mounts an encrypted storage and returns the filesystem path of the storage
313  * mount point. This path will be used to access the secret database via
314  * #GSignondSecretStorage.
315  * 
316  * The default implemenation does nothing, and immediately returns the path for the 
317  * secret database.
318  *
319  * Returns: (transfer none): path of the storage mount point.
320  */
321 const gchar *
322 gsignond_storage_manager_mount_filesystem (GSignondStorageManager *self)
323 {
324     return GSIGNOND_STORAGE_MANAGER_GET_CLASS (self)->
325         mount_filesystem (self);
326 }
327
328 /**
329  * gsignond_storage_manager_unmount_filesystem:
330  * @self: object instance.
331  *
332  * Unmounts a previously mounted encrypted storage filesystem.
333  *
334  * Returns: success?
335  */
336 gboolean
337 gsignond_storage_manager_unmount_filesystem (GSignondStorageManager *self)
338 {
339     return GSIGNOND_STORAGE_MANAGER_GET_CLASS (self)->
340         unmount_filesystem (self);
341 }
342
343 /**
344  * gsignond_storage_manager_filesystem_is_mounted:
345  * @self: object instance.
346  *
347  * Checks if the encrypted storage filesystem is currently mounted.
348  *
349  * Returns: filesystem is currently mounted?
350  */
351 gboolean
352 gsignond_storage_manager_filesystem_is_mounted (GSignondStorageManager *self)
353 {
354     return GSIGNOND_STORAGE_MANAGER_GET_CLASS (self)->
355         filesystem_is_mounted (self);
356 }
357