Refresh upstream 2.1.0 release
[profile/ivi/libgsignon-glib.git] / libgsignon-glib / signon-security-context.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 libgsignon-glib
5  *
6  * Copyright (C) 2012-2013 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 License
12  * version 2.1 as published by the Free Software Foundation.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  */
24
25 /**
26  * SECTION:signon-security-context
27  * @title: SignonSecurityContext
28  * @short_description: representation of a security context.
29  *
30  * The #SignonSecurityContext represents a security context within
31  * system and also within application. Security contexts are used:
32  * 
33  * - within identities to specify the owner of the identity, and 
34  * users of the identity (items on the access control list). See #SignonIdentity.
35  * - by gSSO daemon to identify the application accessing the gSSO service and
36  * to determine if the application is an identity's owner, or is on the identity's access
37  * control list, and make access control decisions accordingly.
38  * 
39  * #SignonSecurityContext contains two strings: a system context and an 
40  * application context.
41  *
42  * System context can be a binary path, SMACK-label, or MSSF token. Specific 
43  * interpretation of the system context value is performed by a gSSO extension module.
44  * The default gSSO extension expects binary paths.
45  * 
46  * Application context identifies a script or a webpage within an application,
47  * and it's used for providing access control to runtime environments (when making an access
48  * control decision requires not only a binary identifier, but also information
49  * about what the binary is doing). 
50  * 
51  * System context and application context can contain a wildcard
52  * operator "*" to match 'any', while "" matches 'none' when a default
53  * gSSO extension is used. The system context is always evaluated first 
54  * and if a match is found, only then the application context is evaluated.
55  * Check the documentation of a platform specific extension to determine
56  * any particular match rules used by a custom ACM (Access Control Manager).
57  */
58
59 #include "signon-security-context.h"
60
61 G_DEFINE_BOXED_TYPE (SignonSecurityContext, signon_security_context,
62                      (GBoxedCopyFunc) signon_security_context_copy,
63                      (GBoxedFreeFunc) signon_security_context_free);
64
65 static void
66 _security_context_free (gpointer ptr)
67 {
68     SignonSecurityContext *ctx = (SignonSecurityContext *) ptr;
69
70     signon_security_context_free (ctx);
71 }
72
73 /**
74  * signon_security_context_new:
75  *
76  * Allocates a new security context item.
77  *
78  * Returns: (transfer full): allocated #SignonSecurityContext.
79  */
80 SignonSecurityContext *
81 signon_security_context_new ()
82 {
83     SignonSecurityContext *ctx;
84
85     ctx = g_slice_new0 (SignonSecurityContext);
86     ctx->sys_ctx = g_strdup ("");
87     ctx->app_ctx = g_strdup ("");
88
89     return ctx;
90 }
91
92 /**
93  * signon_security_context_new_from_values:
94  * @system_context: system security context (such as SMACK/MSSF label/token).
95  * @application_context: application security context (such as a script name).
96  *
97  * Allocates and initializes a new security context item.
98  *
99  * Returns: (transfer full): allocated #SignonSecurityContext.
100  */
101 SignonSecurityContext *
102 signon_security_context_new_from_values (const gchar *system_context,
103                                          const gchar *application_context)
104 {
105     SignonSecurityContext *ctx;
106
107     g_return_val_if_fail (system_context != NULL, NULL);
108
109     ctx = g_slice_new0 (SignonSecurityContext);
110     ctx->sys_ctx = g_strdup (system_context);
111     if (application_context)
112         ctx->app_ctx = g_strdup (application_context);
113     else
114         ctx->app_ctx = g_strdup ("");
115
116     return ctx;
117 }
118
119 /**
120  * signon_security_context_copy:
121  * @src_ctx: source security context to copy.
122  *
123  * Copy a security context item.
124  *
125  * Returns: (transfer full): a copy of the #SignonSecurityContext item.
126  */
127 SignonSecurityContext *
128 signon_security_context_copy (const SignonSecurityContext *src_ctx)
129 {
130     if (!src_ctx)
131         return NULL;
132
133     return signon_security_context_new_from_values (src_ctx->sys_ctx,
134                                                     src_ctx->app_ctx);
135 }
136
137 /**
138  * signon_security_context_free:
139  * @ctx: #SignonSecurityContext to be freed.
140  *
141  * Frees a security context item.
142  */
143 void
144 signon_security_context_free (SignonSecurityContext *ctx)
145 {
146     if (ctx == NULL) return;
147
148     g_free (ctx->sys_ctx);
149     g_free (ctx->app_ctx);
150     g_slice_free (SignonSecurityContext, ctx);
151 }
152
153 /**
154  * signon_security_context_set_system_context:
155  * @ctx: #SignonSecurityContext item.
156  * @system_context: system security context.
157  *
158  * Sets the system context part (such as SMACK label or MSSF token) of the
159  * #SignonSecurityContext.
160  */
161 void
162 signon_security_context_set_system_context (SignonSecurityContext *ctx,
163                                             const gchar *system_context)
164 {
165     g_return_if_fail (ctx != NULL);
166
167     g_free (ctx->sys_ctx);
168     ctx->sys_ctx = g_strdup (system_context);
169 }
170
171 /**
172  * signon_security_context_get_system_context:
173  * @ctx: #SignonSecurityContext item.
174  * 
175  * Get the system context part (such as SMACK label or MSSF token) of the
176  * #SignonSecurityContext.
177  *
178  * Returns: (transfer none): system context.
179  */
180 const gchar *
181 signon_security_context_get_system_context (const SignonSecurityContext *ctx)
182 {
183     g_return_val_if_fail (ctx != NULL, NULL);
184
185     return ctx->sys_ctx;
186 }
187
188 /**
189  * signon_security_context_set_application_context:
190  * @ctx: #SignonSecurityContext item.
191  * @application_context: application security context.
192  *
193  * Sets the application context part (such as a script name or a web page) of
194  * the #SignonSecurityContext.
195  */
196 void
197 signon_security_context_set_application_context (SignonSecurityContext *ctx,
198                                               const gchar *application_context)
199 {
200     g_return_if_fail (ctx != NULL);
201
202     g_free (ctx->app_ctx);
203     ctx->app_ctx = g_strdup (application_context);
204 }
205
206 /**
207  * signon_security_context_get_application_context:
208  * @ctx: #SignonSecurityContext item.
209  *
210  * Get the application context part (such as script name or a web page) of
211  * the #SignonSecurityContext.
212  *
213  * Returns: (transfer none): application context.
214  */
215 const gchar *
216 signon_security_context_get_application_context (
217                                                const SignonSecurityContext *ctx)
218 {
219     g_return_val_if_fail (ctx != NULL, NULL);
220
221     return ctx->app_ctx;
222 }
223
224 /**
225  * signon_security_context_build_variant:
226  * @ctx: #SignonSecurityContext item.
227  *
228  * Build a GVariant of type "(ss)" from a #SignonSecurityContext item.
229  *
230  * Returns: (transfer full): GVariant construct of a #SignonSecurityContext.
231  */
232 GVariant *
233 signon_security_context_build_variant (const SignonSecurityContext *ctx)
234 {
235     GVariant *variant;
236
237     g_return_val_if_fail (ctx != NULL, NULL);
238
239     variant = g_variant_new ("(ss)",
240                              ctx->sys_ctx ? ctx->sys_ctx : "",
241                              ctx->app_ctx ? ctx->app_ctx : "");
242
243     return variant;
244 }
245
246 /**
247  * signon_security_context_deconstruct_variant:
248  * @variant: GVariant item with a #SignonSecurityContext construct.
249  *
250  * Builds a #SignonSecurityContext item from a GVariant of type "(ss)".
251  *
252  * Returns: (transfer full): #SignonSecurityContext item.
253  */
254 SignonSecurityContext *
255 signon_security_context_deconstruct_variant (GVariant *variant)
256 {
257     gchar *sys_ctx = NULL;
258     gchar *app_ctx = NULL;
259     SignonSecurityContext *ctx;
260
261     g_return_val_if_fail (variant != NULL, NULL);
262
263     g_variant_get (variant, "(ss)", &sys_ctx, &app_ctx);
264     ctx = signon_security_context_new_from_values (sys_ctx, app_ctx);
265     g_free (sys_ctx);
266     g_free (app_ctx);
267     return ctx;
268 }
269
270 /**
271  * signon_security_context_list_build_variant:
272  * @list: #SignonSecurityContextList item.
273  *
274  * Builds a GVariant of type "a(ss)" from a GList of #SignonSecurityContext
275  * items.
276  *
277  * Returns: (transfer full): GVariant construct of a #SignonSecurityContextList.
278  */
279 GVariant *
280 signon_security_context_list_build_variant (
281                                           const SignonSecurityContextList *list)
282 {
283     GVariantBuilder builder;
284     GVariant *variant;
285     SignonSecurityContext *ctx;
286
287     g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
288     for ( ; list != NULL; list = g_list_next (list))
289     {
290         ctx = (SignonSecurityContext *) list->data;
291         g_variant_builder_add_value (&builder,
292                                    signon_security_context_build_variant (ctx));
293     }
294     variant = g_variant_builder_end (&builder);
295
296     return variant;
297 }
298
299 /**
300  * signon_security_context_list_deconstruct_variant:
301  * @variant: GVariant item with a list of security context tuples.
302  *
303  * Builds a GList of #SignonSecurityContext items from a GVariant of type
304  * "a(ss)".
305  *
306  * Returns: (transfer full): #SignonSecurityContextList item.
307  */
308 SignonSecurityContextList *
309 signon_security_context_list_deconstruct_variant (GVariant *variant)
310 {
311     SignonSecurityContextList *list = NULL;
312     GVariantIter iter;
313     GVariant *value;
314
315     g_return_val_if_fail (variant != NULL, NULL);
316
317     g_variant_iter_init (&iter, variant);
318     while ((value = g_variant_iter_next_value (&iter)))
319     {
320         list = g_list_append (
321             list, signon_security_context_deconstruct_variant (value));
322         g_variant_unref (value);
323     }
324
325     return list;
326 }
327
328 /**
329  * signon_security_context_list_copy:
330  * @src_list: source #SignonSecurityContextList.
331  *
332  * Copies a GList of #SignonSecurityContext items.
333  *
334  * Returns: (transfer full): #SignonSecurityContextList item.
335  */
336 SignonSecurityContextList *
337 signon_security_context_list_copy (const SignonSecurityContextList *src_list)
338 {
339     SignonSecurityContext *ctx;
340     SignonSecurityContextList *dst_list = NULL;
341
342     for ( ; src_list != NULL; src_list = g_list_next (src_list))
343     {
344         ctx = (SignonSecurityContext *) src_list->data;
345         dst_list = g_list_append (
346             dst_list, signon_security_context_copy (ctx));
347     }
348
349     return dst_list;
350 }
351
352 /**
353  * signon_security_context_list_free:
354  * @seclist: (transfer full): #SignonSecurityContextList item.
355  *
356  * Frees all items and the GList of #SignonSecurityContext.
357  */
358 void
359 signon_security_context_list_free (SignonSecurityContextList *seclist)
360 {
361     g_list_free_full (seclist, _security_context_free);
362 }
363