2 * Copyright (C) 2010 Stefan Walter
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.
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.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 #define DEBUG_FLAG GCR_DEBUG_KEY
23 #include "gcr-debug.h"
24 #include "gcr-key-mechanisms.h"
26 #include <glib/gi18n-lib.h>
29 check_have_attributes (GckAttributes *attrs,
35 for (i = 0; i < n_types; i++) {
36 if (!gck_attributes_find (attrs, types[i]))
44 find_first_usable_mechanism (GckObject *key,
46 const gulong *mechanisms,
48 gulong action_attr_type)
56 if (gck_attributes_find_boolean (attrs, action_attr_type, &can) && !can) {
57 _gcr_debug ("key not capable of needed action");
61 session = gck_object_get_session (key);
62 slot = gck_session_get_slot (session);
63 mechs = gck_slot_get_mechanisms (slot);
64 g_object_unref (slot);
65 g_object_unref (session);
68 _gcr_debug ("couldn't get slot mechanisms");
72 for (i = 0; i < n_mechanisms; i++) {
73 if (gck_mechanisms_check (mechs, mechanisms[i], GCK_INVALID))
77 gck_mechanisms_free (mechs);
85 _gcr_key_mechanisms_check (GckObject *key,
86 const gulong *mechanisms,
88 gulong action_attr_type,
89 GCancellable *cancellable,
92 gulong attr_types[] = { action_attr_type };
93 GckAttributes *attrs = NULL;
96 g_return_val_if_fail (GCK_IS_OBJECT (key), GCK_INVALID);
97 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), GCK_INVALID);
98 g_return_val_if_fail (error == NULL || *error == NULL, GCK_INVALID);
100 if (GCK_IS_OBJECT_CACHE (key)) {
101 attrs = gck_object_cache_get_attributes (GCK_OBJECT_CACHE (key));
102 if (!check_have_attributes (attrs, attr_types, G_N_ELEMENTS (attr_types))) {
103 gck_attributes_unref (attrs);
109 attrs = gck_object_get_full (key, attr_types, G_N_ELEMENTS (attr_types),
116 result = find_first_usable_mechanism (key, attrs, mechanisms, n_mechanisms, action_attr_type);
117 gck_attributes_unref (attrs);
124 gulong action_attr_type;
125 GckAttributes *attrs;
129 check_closure_free (gpointer data)
131 CheckClosure *closure = data;
132 g_free (closure->mechanisms);
133 gck_attributes_unref (closure->attrs);
138 on_check_get_attributes (GObject *source,
139 GAsyncResult *result,
142 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
143 CheckClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
144 GError *error = NULL;
146 closure->attrs = gck_object_cache_lookup_finish (GCK_OBJECT (source), result, &error);
148 g_simple_async_result_take_error (res, error);
150 g_simple_async_result_complete (res);
151 g_object_unref (res);
155 _gcr_key_mechanisms_check_async (GckObject *key,
156 const gulong *mechanisms,
158 gulong action_attr_type,
159 GCancellable *cancellable,
160 GAsyncReadyCallback callback,
163 gulong attr_types[] = { action_attr_type };
164 CheckClosure *closure;
165 GSimpleAsyncResult *res;
167 g_return_if_fail (GCK_IS_OBJECT (key));
168 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
170 res = g_simple_async_result_new (G_OBJECT (key), callback, user_data,
171 _gcr_key_mechanisms_check_async);
172 closure = g_new0 (CheckClosure, 1);
173 closure->mechanisms = g_memdup (mechanisms, n_mechanisms * sizeof (gulong));
174 closure->n_mechanisms = n_mechanisms;
175 closure->action_attr_type = action_attr_type;
176 g_simple_async_result_set_op_res_gpointer (res, closure, check_closure_free);
178 gck_object_cache_lookup_async (key, attr_types, G_N_ELEMENTS (attr_types),
179 cancellable, on_check_get_attributes, g_object_ref (res));
181 g_object_unref (res);
187 _gcr_key_mechanisms_check_finish (GckObject *key,
188 GAsyncResult *result,
191 CheckClosure *closure;
192 GSimpleAsyncResult *res;
194 g_return_val_if_fail (GCK_IS_OBJECT (key), GCK_INVALID);
195 g_return_val_if_fail (error == NULL || *error == NULL, GCK_INVALID);
197 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (key),
198 _gcr_key_mechanisms_check_async), FALSE);
200 res = G_SIMPLE_ASYNC_RESULT (result);
201 if (g_simple_async_result_propagate_error (res, error))
204 closure = g_simple_async_result_get_op_res_gpointer (res);
206 return find_first_usable_mechanism (GCK_OBJECT (key), closure->attrs,
207 closure->mechanisms, closure->n_mechanisms,
208 closure->action_attr_type);