aboutsummaryrefslogtreecommitdiff
path: root/src/identity-attribute/identity_attribute.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/identity-attribute/identity_attribute.c')
-rw-r--r--src/identity-attribute/identity_attribute.c421
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 */
34struct 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 */
50static struct Plugin **attr_plugins;
51
52/**
53 * Number of plugins
54 */
55static unsigned int num_plugins;
56
57/**
58 * Init canary
59 */
60static int initialized;
61
62/**
63 * Add a plugin
64 */
65static void
66add_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 */
85static void
86init()
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 */
101uint32_t
102GNUNET_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 */
125const char*
126GNUNET_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 */
153int
154GNUNET_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 */
184char *
185GNUNET_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 */
215struct GNUNET_IDENTITY_ATTRIBUTE_Claim *
216GNUNET_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
243size_t
244GNUNET_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
253size_t
254GNUNET_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
274struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *
275GNUNET_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
305struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList*
306GNUNET_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
331void
332GNUNET_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
348size_t
349GNUNET_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
356size_t
357GNUNET_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
383struct GNUNET_IDENTITY_ATTRIBUTE_Claim *
384GNUNET_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 */