Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2010 Stefan Walter
3 : : *
4 : : * This program is free software; you can redistribute it and/or modify
5 : : * it under the terms of the GNU Lesser General Public License as
6 : : * published by the Free Software Foundation; either version 2.1 of
7 : : * the License, or (at your option) any later version.
8 : : *
9 : : * This program is distributed in the hope that it will be useful, but
10 : : * WITHOUT ANY WARRANTY; without even the implied warranty of
11 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : : * Lesser General Public License for more details.
13 : : *
14 : : * You should have received a copy of the GNU Lesser General Public
15 : : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
16 : : */
17 : :
18 : : #include "config.h"
19 : :
20 : : #include "gcr-key-mechanisms.h"
21 : :
22 : : #include <glib/gi18n-lib.h>
23 : :
24 : : static gboolean
25 : 0 : check_have_attributes (GckAttributes *attrs,
26 : : const gulong *types,
27 : : gsize n_types)
28 : : {
29 : : gsize i;
30 : :
31 [ # # ]: 0 : for (i = 0; i < n_types; i++) {
32 [ # # ]: 0 : if (!gck_attributes_find (attrs, types[i]))
33 : 0 : return FALSE;
34 : : }
35 : :
36 : 0 : return TRUE;
37 : : }
38 : :
39 : : static gulong
40 : 0 : find_first_usable_mechanism (GckObject *key,
41 : : GckAttributes *attrs,
42 : : const gulong *mechanisms,
43 : : gsize n_mechanisms,
44 : : gulong action_attr_type)
45 : : {
46 : : GckSession *session;
47 : : GckSlot *slot;
48 : : GArray *mechs;
49 : : gboolean can;
50 : : gsize i;
51 : :
52 [ # # # # ]: 0 : if (gck_attributes_find_boolean (attrs, action_attr_type, &can) && !can) {
53 : 0 : g_debug ("key not capable of needed action");
54 : 0 : return GCK_INVALID;
55 : : }
56 : :
57 : 0 : session = gck_object_get_session (key);
58 : 0 : slot = gck_session_get_slot (session);
59 : 0 : mechs = gck_slot_get_mechanisms (slot);
60 : 0 : g_object_unref (slot);
61 : 0 : g_object_unref (session);
62 : :
63 [ # # ]: 0 : if (!mechs) {
64 : 0 : g_debug ("couldn't get slot mechanisms");
65 : 0 : return GCK_INVALID;
66 : : }
67 : :
68 [ # # ]: 0 : for (i = 0; i < n_mechanisms; i++) {
69 [ # # ]: 0 : if (gck_mechanisms_check (mechs, mechanisms[i], GCK_INVALID))
70 : 0 : break;
71 : : }
72 : :
73 : 0 : g_array_unref (mechs);
74 : :
75 [ # # ]: 0 : if (i < n_mechanisms)
76 : 0 : return mechanisms[i];
77 : 0 : return GCK_INVALID;
78 : : }
79 : :
80 : : gulong
81 : 0 : _gcr_key_mechanisms_check (GckObject *key,
82 : : const gulong *mechanisms,
83 : : gsize n_mechanisms,
84 : : gulong action_attr_type,
85 : : GCancellable *cancellable,
86 : : GError **error)
87 : : {
88 : 0 : gulong attr_types[] = { action_attr_type };
89 : 0 : GckAttributes *attrs = NULL;
90 : : gulong result;
91 : :
92 [ # # ]: 0 : g_return_val_if_fail (GCK_IS_OBJECT (key), GCK_INVALID);
93 [ # # # # : 0 : g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), GCK_INVALID);
# # # # #
# ]
94 [ # # # # ]: 0 : g_return_val_if_fail (error == NULL || *error == NULL, GCK_INVALID);
95 : :
96 [ # # ]: 0 : if (GCK_IS_OBJECT_CACHE (key)) {
97 : 0 : attrs = gck_object_cache_get_attributes (GCK_OBJECT_CACHE (key));
98 [ # # ]: 0 : if (!check_have_attributes (attrs, attr_types, G_N_ELEMENTS (attr_types))) {
99 : 0 : gck_attributes_unref (attrs);
100 : 0 : attrs = NULL;
101 : : }
102 : : }
103 : :
104 [ # # ]: 0 : if (attrs == NULL) {
105 : 0 : attrs = gck_object_get_full (key, attr_types, G_N_ELEMENTS (attr_types),
106 : : cancellable, error);
107 : : }
108 : :
109 [ # # ]: 0 : if (!attrs)
110 : 0 : return GCK_INVALID;
111 : :
112 : 0 : result = find_first_usable_mechanism (key, attrs, mechanisms, n_mechanisms, action_attr_type);
113 : 0 : gck_attributes_unref (attrs);
114 : 0 : return result;
115 : : }
116 : :
117 : : typedef struct {
118 : : gulong *mechanisms;
119 : : gsize n_mechanisms;
120 : : gulong action_attr_type;
121 : : } CheckClosure;
122 : :
123 : : static void
124 : 0 : check_closure_free (gpointer data)
125 : : {
126 : 0 : CheckClosure *closure = data;
127 : 0 : g_free (closure->mechanisms);
128 : 0 : g_free (closure);
129 : 0 : }
130 : :
131 : : static void
132 : 0 : on_check_get_attributes (GObject *source,
133 : : GAsyncResult *result,
134 : : gpointer user_data)
135 : : {
136 : 0 : GTask *task = G_TASK (user_data);
137 : : GckAttributes *attrs;
138 : 0 : GError *error = NULL;
139 : :
140 : 0 : attrs = gck_object_cache_lookup_finish (GCK_OBJECT (source), result, &error);
141 [ # # ]: 0 : if (error != NULL)
142 : 0 : g_task_return_error (task, g_steal_pointer (&error));
143 : : else
144 : 0 : g_task_return_pointer (task, attrs, gck_attributes_unref);
145 : :
146 [ # # ]: 0 : g_clear_object (&task);
147 : 0 : }
148 : :
149 : : void
150 : 0 : _gcr_key_mechanisms_check_async (GckObject *key,
151 : : const gulong *mechanisms,
152 : : gsize n_mechanisms,
153 : : gulong action_attr_type,
154 : : GCancellable *cancellable,
155 : : GAsyncReadyCallback callback,
156 : : gpointer user_data)
157 : : {
158 : 0 : gulong attr_types[] = { action_attr_type };
159 : : CheckClosure *closure;
160 : : GTask *task;
161 : :
162 [ # # ]: 0 : g_return_if_fail (GCK_IS_OBJECT (key));
163 [ # # # # : 0 : g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
# # # # #
# ]
164 : :
165 : 0 : task = g_task_new (key, cancellable, callback, user_data);
166 [ # # ]: 0 : g_task_set_source_tag (task, _gcr_key_mechanisms_check_async);
167 : 0 : closure = g_new0 (CheckClosure, 1);
168 : 0 : closure->mechanisms = g_memdup2 (mechanisms, n_mechanisms * sizeof (gulong));
169 : 0 : closure->n_mechanisms = n_mechanisms;
170 : 0 : closure->action_attr_type = action_attr_type;
171 : 0 : g_task_set_task_data (task, closure, check_closure_free);
172 : :
173 : 0 : gck_object_cache_lookup_async (key, attr_types, G_N_ELEMENTS (attr_types),
174 : : cancellable, on_check_get_attributes,
175 : : g_steal_pointer (&task));
176 : :
177 [ # # ]: 0 : g_clear_object (&task);
178 : : }
179 : :
180 : : gulong
181 : 0 : _gcr_key_mechanisms_check_finish (GckObject *key,
182 : : GAsyncResult *result,
183 : : GError **error)
184 : : {
185 : : CheckClosure *closure;
186 : : GckAttributes *attrs;
187 : 0 : gulong ret = GCK_INVALID;
188 : :
189 [ # # ]: 0 : g_return_val_if_fail (GCK_IS_OBJECT (key), GCK_INVALID);
190 [ # # # # ]: 0 : g_return_val_if_fail (error == NULL || *error == NULL, GCK_INVALID);
191 : :
192 [ # # ]: 0 : g_return_val_if_fail (g_task_is_valid (result, key), GCK_INVALID);
193 [ # # ]: 0 : g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
194 : : _gcr_key_mechanisms_check_async, GCK_INVALID);
195 : :
196 : 0 : closure = g_task_get_task_data (G_TASK (result));
197 : :
198 : 0 : attrs = g_task_propagate_pointer (G_TASK (result), error);
199 [ # # ]: 0 : if (!attrs)
200 : 0 : return GCK_INVALID;
201 : :
202 : 0 : ret = find_first_usable_mechanism (GCK_OBJECT (key), attrs,
203 : 0 : closure->mechanisms, closure->n_mechanisms,
204 : : closure->action_attr_type);
205 : :
206 : 0 : gck_attributes_unref (attrs);
207 : 0 : return ret;
208 : : }
|