diff options
Diffstat (limited to 'src/identity-attribute/identity_attribute.c')
-rw-r--r-- | src/identity-attribute/identity_attribute.c | 421 |
1 files changed, 421 insertions, 0 deletions
diff --git a/src/identity-attribute/identity_attribute.c b/src/identity-attribute/identity_attribute.c new file mode 100644 index 000000000..cf50d058e --- /dev/null +++ b/src/identity-attribute/identity_attribute.c | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2010-2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file identity-attribute/identity_attribute.c | ||
23 | * @brief helper library to manage identity attributes | ||
24 | * @author Martin Schanzenbach | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "identity_attribute.h" | ||
29 | #include "gnunet_identity_attribute_plugin.h" | ||
30 | |||
31 | /** | ||
32 | * Handle for a plugin | ||
33 | */ | ||
34 | struct Plugin | ||
35 | { | ||
36 | /** | ||
37 | * Name of the plugin | ||
38 | */ | ||
39 | char *library_name; | ||
40 | |||
41 | /** | ||
42 | * Plugin API | ||
43 | */ | ||
44 | struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api; | ||
45 | }; | ||
46 | |||
47 | /** | ||
48 | * Plugins | ||
49 | */ | ||
50 | static struct Plugin **attr_plugins; | ||
51 | |||
52 | /** | ||
53 | * Number of plugins | ||
54 | */ | ||
55 | static unsigned int num_plugins; | ||
56 | |||
57 | /** | ||
58 | * Init canary | ||
59 | */ | ||
60 | static int initialized; | ||
61 | |||
62 | /** | ||
63 | * Add a plugin | ||
64 | */ | ||
65 | static void | ||
66 | add_plugin (void* cls, | ||
67 | const char *library_name, | ||
68 | void *lib_ret) | ||
69 | { | ||
70 | struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api = lib_ret; | ||
71 | struct Plugin *plugin; | ||
72 | |||
73 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
74 | "Loading attribute plugin `%s'\n", | ||
75 | library_name); | ||
76 | plugin = GNUNET_new (struct Plugin); | ||
77 | plugin->api = api; | ||
78 | plugin->library_name = GNUNET_strdup (library_name); | ||
79 | GNUNET_array_append (attr_plugins, num_plugins, plugin); | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * Load plugins | ||
84 | */ | ||
85 | static void | ||
86 | init() | ||
87 | { | ||
88 | if (GNUNET_YES == initialized) | ||
89 | return; | ||
90 | initialized = GNUNET_YES; | ||
91 | GNUNET_PLUGIN_load_all ("libgnunet_plugin_identity_attribute_", NULL, | ||
92 | &add_plugin, NULL); | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * Convert a type name to the corresponding number | ||
97 | * | ||
98 | * @param typename name to convert | ||
99 | * @return corresponding number, UINT32_MAX on error | ||
100 | */ | ||
101 | uint32_t | ||
102 | GNUNET_IDENTITY_ATTRIBUTE_typename_to_number (const char *typename) | ||
103 | { | ||
104 | unsigned int i; | ||
105 | struct Plugin *plugin; | ||
106 | uint32_t ret; | ||
107 | |||
108 | init (); | ||
109 | for (i = 0; i < num_plugins; i++) | ||
110 | { | ||
111 | plugin = attr_plugins[i]; | ||
112 | if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls, | ||
113 | typename))) | ||
114 | return ret; | ||
115 | } | ||
116 | return UINT32_MAX; | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * Convert a type number to the corresponding type string | ||
121 | * | ||
122 | * @param type number of a type | ||
123 | * @return corresponding typestring, NULL on error | ||
124 | */ | ||
125 | const char* | ||
126 | GNUNET_IDENTITY_ATTRIBUTE_number_to_typename (uint32_t type) | ||
127 | { | ||
128 | unsigned int i; | ||
129 | struct Plugin *plugin; | ||
130 | const char *ret; | ||
131 | |||
132 | init (); | ||
133 | for (i = 0; i < num_plugins; i++) | ||
134 | { | ||
135 | plugin = attr_plugins[i]; | ||
136 | if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls, | ||
137 | type))) | ||
138 | return ret; | ||
139 | } | ||
140 | return NULL; | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * Convert human-readable version of a 'claim' of an attribute to the binary | ||
145 | * representation | ||
146 | * | ||
147 | * @param type type of the claim | ||
148 | * @param s human-readable string | ||
149 | * @param data set to value in binary encoding (will be allocated) | ||
150 | * @param data_size set to number of bytes in @a data | ||
151 | * @return #GNUNET_OK on success | ||
152 | */ | ||
153 | int | ||
154 | GNUNET_IDENTITY_ATTRIBUTE_string_to_value (uint32_t type, | ||
155 | const char *s, | ||
156 | void **data, | ||
157 | size_t *data_size) | ||
158 | { | ||
159 | unsigned int i; | ||
160 | struct Plugin *plugin; | ||
161 | |||
162 | init (); | ||
163 | for (i = 0; i < num_plugins; i++) | ||
164 | { | ||
165 | plugin = attr_plugins[i]; | ||
166 | if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls, | ||
167 | type, | ||
168 | s, | ||
169 | data, | ||
170 | data_size)) | ||
171 | return GNUNET_OK; | ||
172 | } | ||
173 | return GNUNET_SYSERR; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * Convert the 'claim' of an attribute to a string | ||
178 | * | ||
179 | * @param type the type of attribute | ||
180 | * @param data claim in binary encoding | ||
181 | * @param data_size number of bytes in @a data | ||
182 | * @return NULL on error, otherwise human-readable representation of the claim | ||
183 | */ | ||
184 | char * | ||
185 | GNUNET_IDENTITY_ATTRIBUTE_value_to_string (uint32_t type, | ||
186 | const void* data, | ||
187 | size_t data_size) | ||
188 | { | ||
189 | unsigned int i; | ||
190 | struct Plugin *plugin; | ||
191 | char *ret; | ||
192 | |||
193 | init(); | ||
194 | for (i = 0; i < num_plugins; i++) | ||
195 | { | ||
196 | plugin = attr_plugins[i]; | ||
197 | if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls, | ||
198 | type, | ||
199 | data, | ||
200 | data_size))) | ||
201 | return ret; | ||
202 | } | ||
203 | return NULL; | ||
204 | } | ||
205 | |||
206 | /** | ||
207 | * Create a new attribute. | ||
208 | * | ||
209 | * @param attr_name the attribute name | ||
210 | * @param type the attribute type | ||
211 | * @param data the attribute value | ||
212 | * @param data_size the attribute value size | ||
213 | * @return the new attribute | ||
214 | */ | ||
215 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim * | ||
216 | GNUNET_IDENTITY_ATTRIBUTE_claim_new (const char* attr_name, | ||
217 | uint32_t type, | ||
218 | const void* data, | ||
219 | size_t data_size) | ||
220 | { | ||
221 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr; | ||
222 | char *write_ptr; | ||
223 | |||
224 | attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim) + | ||
225 | strlen (attr_name) + 1 + | ||
226 | data_size); | ||
227 | attr->type = type; | ||
228 | attr->data_size = data_size; | ||
229 | attr->version = 0; | ||
230 | write_ptr = (char*)&attr[1]; | ||
231 | GNUNET_memcpy (write_ptr, | ||
232 | attr_name, | ||
233 | strlen (attr_name) + 1); | ||
234 | attr->name = write_ptr; | ||
235 | write_ptr += strlen (attr->name) + 1; | ||
236 | GNUNET_memcpy (write_ptr, | ||
237 | data, | ||
238 | data_size); | ||
239 | attr->data = write_ptr; | ||
240 | return attr; | ||
241 | } | ||
242 | |||
243 | size_t | ||
244 | GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) | ||
245 | { | ||
246 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
247 | size_t len = 0; | ||
248 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
249 | len += GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (le->claim); | ||
250 | return len; | ||
251 | } | ||
252 | |||
253 | size_t | ||
254 | GNUNET_IDENTITY_ATTRIBUTE_list_serialize (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, | ||
255 | char *result) | ||
256 | { | ||
257 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
258 | size_t len; | ||
259 | size_t total_len; | ||
260 | char* write_ptr; | ||
261 | |||
262 | write_ptr = result; | ||
263 | total_len = 0; | ||
264 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
265 | { | ||
266 | len = GNUNET_IDENTITY_ATTRIBUTE_serialize (le->claim, | ||
267 | write_ptr); | ||
268 | total_len += len; | ||
269 | write_ptr += len; | ||
270 | } | ||
271 | return total_len; | ||
272 | } | ||
273 | |||
274 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList * | ||
275 | GNUNET_IDENTITY_ATTRIBUTE_list_deserialize (const char* data, | ||
276 | size_t data_size) | ||
277 | { | ||
278 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs; | ||
279 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
280 | size_t attr_len; | ||
281 | const char* read_ptr; | ||
282 | |||
283 | if (data_size < sizeof (struct Attribute)) | ||
284 | return NULL; | ||
285 | |||
286 | attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList); | ||
287 | read_ptr = data; | ||
288 | while (((data + data_size) - read_ptr) >= sizeof (struct Attribute)) | ||
289 | { | ||
290 | |||
291 | le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry); | ||
292 | le->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize (read_ptr, | ||
293 | data_size - (read_ptr - data)); | ||
294 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
295 | "Deserialized attribute %s\n", le->claim->name); | ||
296 | GNUNET_CONTAINER_DLL_insert (attrs->list_head, | ||
297 | attrs->list_tail, | ||
298 | le); | ||
299 | attr_len = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (le->claim); | ||
300 | read_ptr += attr_len; | ||
301 | } | ||
302 | return attrs; | ||
303 | } | ||
304 | |||
305 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList* | ||
306 | GNUNET_IDENTITY_ATTRIBUTE_list_dup (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) | ||
307 | { | ||
308 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
309 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *result_le; | ||
310 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *result; | ||
311 | size_t len; | ||
312 | |||
313 | result = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList); | ||
314 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
315 | { | ||
316 | result_le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry); | ||
317 | len = sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim) + le->claim->data_size; | ||
318 | result_le->claim = GNUNET_malloc (len); | ||
319 | GNUNET_memcpy (result_le->claim, | ||
320 | le->claim, | ||
321 | len); | ||
322 | result_le->claim->name = (const char*)&result_le->claim[1]; | ||
323 | GNUNET_CONTAINER_DLL_insert (result->list_head, | ||
324 | result->list_tail, | ||
325 | result_le); | ||
326 | } | ||
327 | return result; | ||
328 | } | ||
329 | |||
330 | |||
331 | void | ||
332 | GNUNET_IDENTITY_ATTRIBUTE_list_destroy (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) | ||
333 | { | ||
334 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
335 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *tmp_le; | ||
336 | |||
337 | for (le = attrs->list_head; NULL != le;) | ||
338 | { | ||
339 | GNUNET_free (le->claim); | ||
340 | tmp_le = le; | ||
341 | le = le->next; | ||
342 | GNUNET_free (tmp_le); | ||
343 | } | ||
344 | GNUNET_free (attrs); | ||
345 | |||
346 | } | ||
347 | |||
348 | size_t | ||
349 | GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr) | ||
350 | { | ||
351 | return sizeof (struct Attribute) | ||
352 | + strlen (attr->name) | ||
353 | + attr->data_size; | ||
354 | } | ||
355 | |||
356 | size_t | ||
357 | GNUNET_IDENTITY_ATTRIBUTE_serialize (const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr, | ||
358 | char *result) | ||
359 | { | ||
360 | size_t data_len_ser; | ||
361 | size_t name_len; | ||
362 | struct Attribute *attr_ser; | ||
363 | char* write_ptr; | ||
364 | |||
365 | attr_ser = (struct Attribute*)result; | ||
366 | attr_ser->attribute_type = htons (attr->type); | ||
367 | attr_ser->attribute_version = htonl (attr->version); | ||
368 | name_len = strlen (attr->name); | ||
369 | attr_ser->name_len = htons (name_len); | ||
370 | write_ptr = (char*)&attr_ser[1]; | ||
371 | GNUNET_memcpy (write_ptr, attr->name, name_len); | ||
372 | write_ptr += name_len; | ||
373 | //TODO plugin-ize | ||
374 | //data_len_ser = plugin->serialize_attribute_value (attr, | ||
375 | // &attr_ser[1]); | ||
376 | data_len_ser = attr->data_size; | ||
377 | GNUNET_memcpy (write_ptr, attr->data, attr->data_size); | ||
378 | attr_ser->data_size = htons (data_len_ser); | ||
379 | |||
380 | return sizeof (struct Attribute) + strlen (attr->name) + attr->data_size; | ||
381 | } | ||
382 | |||
383 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim * | ||
384 | GNUNET_IDENTITY_ATTRIBUTE_deserialize (const char* data, | ||
385 | size_t data_size) | ||
386 | { | ||
387 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr; | ||
388 | struct Attribute *attr_ser; | ||
389 | size_t data_len; | ||
390 | size_t name_len; | ||
391 | char* write_ptr; | ||
392 | |||
393 | if (data_size < sizeof (struct Attribute)) | ||
394 | return NULL; | ||
395 | |||
396 | attr_ser = (struct Attribute*)data; | ||
397 | data_len = ntohs (attr_ser->data_size); | ||
398 | name_len = ntohs (attr_ser->name_len); | ||
399 | attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim) | ||
400 | + data_len + name_len + 1); | ||
401 | attr->type = ntohs (attr_ser->attribute_type); | ||
402 | attr->version = ntohl (attr_ser->attribute_version); | ||
403 | attr->data_size = ntohs (attr_ser->data_size); | ||
404 | |||
405 | write_ptr = (char*)&attr[1]; | ||
406 | GNUNET_memcpy (write_ptr, | ||
407 | &attr_ser[1], | ||
408 | name_len); | ||
409 | write_ptr[name_len] = '\0'; | ||
410 | attr->name = write_ptr; | ||
411 | |||
412 | write_ptr += name_len + 1; | ||
413 | GNUNET_memcpy (write_ptr, | ||
414 | (char*)&attr_ser[1] + name_len, | ||
415 | attr->data_size); | ||
416 | attr->data = write_ptr; | ||
417 | return attr; | ||
418 | |||
419 | } | ||
420 | |||
421 | /* end of identity_attribute.c */ | ||