2 This file is part of GNUnet
3 Copyright (C) 2010-2015 GNUnet e.V.
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.
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.
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.
22 * @file identity-attribute/identity_attribute.c
23 * @brief helper library to manage identity attributes
24 * @author Martin Schanzenbach
27 #include "gnunet_util_lib.h"
28 #include "identity_attribute.h"
29 #include "gnunet_identity_attribute_plugin.h"
44 struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api;
50 static struct Plugin **attr_plugins;
55 static unsigned int num_plugins;
60 static int initialized;
66 add_plugin (void* cls,
67 const char *library_name,
70 struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api = lib_ret;
71 struct Plugin *plugin;
73 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
74 "Loading attribute plugin `%s'\n",
76 plugin = GNUNET_new (struct Plugin);
78 plugin->library_name = GNUNET_strdup (library_name);
79 GNUNET_array_append (attr_plugins, num_plugins, plugin);
88 if (GNUNET_YES == initialized)
90 initialized = GNUNET_YES;
91 GNUNET_PLUGIN_load_all ("libgnunet_plugin_identity_attribute_", NULL,
96 * Convert a type name to the corresponding number
98 * @param typename name to convert
99 * @return corresponding number, UINT32_MAX on error
102 GNUNET_IDENTITY_ATTRIBUTE_typename_to_number (const char *typename)
105 struct Plugin *plugin;
109 for (i = 0; i < num_plugins; i++)
111 plugin = attr_plugins[i];
112 if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls,
120 * Convert a type number to the corresponding type string
122 * @param type number of a type
123 * @return corresponding typestring, NULL on error
126 GNUNET_IDENTITY_ATTRIBUTE_number_to_typename (uint32_t type)
129 struct Plugin *plugin;
133 for (i = 0; i < num_plugins; i++)
135 plugin = attr_plugins[i];
136 if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls,
144 * Convert human-readable version of a 'claim' of an attribute to the binary
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
154 GNUNET_IDENTITY_ATTRIBUTE_string_to_value (uint32_t type,
160 struct Plugin *plugin;
163 for (i = 0; i < num_plugins; i++)
165 plugin = attr_plugins[i];
166 if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
173 return GNUNET_SYSERR;
177 * Convert the 'claim' of an attribute to a string
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
185 GNUNET_IDENTITY_ATTRIBUTE_value_to_string (uint32_t type,
190 struct Plugin *plugin;
194 for (i = 0; i < num_plugins; i++)
196 plugin = attr_plugins[i];
197 if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
207 * Create a new attribute.
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
215 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *
216 GNUNET_IDENTITY_ATTRIBUTE_claim_new (const char* attr_name,
221 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr;
224 attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim) +
225 strlen (attr_name) + 1 +
228 attr->data_size = data_size;
230 write_ptr = (char*)&attr[1];
231 GNUNET_memcpy (write_ptr,
233 strlen (attr_name) + 1);
234 attr->name = write_ptr;
235 write_ptr += strlen (attr->name) + 1;
236 GNUNET_memcpy (write_ptr,
239 attr->data = write_ptr;
244 * Add a new claim list entry.
246 * @param claim_list the attribute name
247 * @param attr_name the attribute name
248 * @param type the attribute type
249 * @param data the attribute value
250 * @param data_size the attribute value size
254 GNUNET_IDENTITY_ATTRIBUTE_list_add (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *claim_list,
255 const char* attr_name,
260 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
261 le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
262 le->claim = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr_name,
266 GNUNET_CONTAINER_DLL_insert (claim_list->list_head,
267 claim_list->list_tail,
272 GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
274 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
276 for (le = attrs->list_head; NULL != le; le = le->next)
277 len += GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (le->claim);
282 GNUNET_IDENTITY_ATTRIBUTE_list_serialize (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
285 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
292 for (le = attrs->list_head; NULL != le; le = le->next)
294 len = GNUNET_IDENTITY_ATTRIBUTE_serialize (le->claim,
302 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *
303 GNUNET_IDENTITY_ATTRIBUTE_list_deserialize (const char* data,
306 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
307 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
309 const char* read_ptr;
311 if (data_size < sizeof (struct Attribute))
314 attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
316 while (((data + data_size) - read_ptr) >= sizeof (struct Attribute))
319 le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
320 le->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize (read_ptr,
321 data_size - (read_ptr - data));
322 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
323 "Deserialized attribute %s\n", le->claim->name);
324 GNUNET_CONTAINER_DLL_insert (attrs->list_head,
327 attr_len = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (le->claim);
328 read_ptr += attr_len;
333 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList*
334 GNUNET_IDENTITY_ATTRIBUTE_list_dup (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
336 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
337 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *result_le;
338 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *result;
341 result = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
342 for (le = attrs->list_head; NULL != le; le = le->next)
344 result_le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
345 len = sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim) + le->claim->data_size;
346 result_le->claim = GNUNET_malloc (len);
347 GNUNET_memcpy (result_le->claim,
350 result_le->claim->name = (const char*)&result_le->claim[1];
351 GNUNET_CONTAINER_DLL_insert (result->list_head,
360 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
362 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
363 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *tmp_le;
365 for (le = attrs->list_head; NULL != le;)
367 GNUNET_free (le->claim);
370 GNUNET_free (tmp_le);
377 GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr)
379 return sizeof (struct Attribute)
380 + strlen (attr->name)
385 GNUNET_IDENTITY_ATTRIBUTE_serialize (const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr,
390 struct Attribute *attr_ser;
393 attr_ser = (struct Attribute*)result;
394 attr_ser->attribute_type = htons (attr->type);
395 attr_ser->attribute_version = htonl (attr->version);
396 name_len = strlen (attr->name);
397 attr_ser->name_len = htons (name_len);
398 write_ptr = (char*)&attr_ser[1];
399 GNUNET_memcpy (write_ptr, attr->name, name_len);
400 write_ptr += name_len;
402 //data_len_ser = plugin->serialize_attribute_value (attr,
404 data_len_ser = attr->data_size;
405 GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
406 attr_ser->data_size = htons (data_len_ser);
408 return sizeof (struct Attribute) + strlen (attr->name) + attr->data_size;
411 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *
412 GNUNET_IDENTITY_ATTRIBUTE_deserialize (const char* data,
415 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr;
416 struct Attribute *attr_ser;
421 if (data_size < sizeof (struct Attribute))
424 attr_ser = (struct Attribute*)data;
425 data_len = ntohs (attr_ser->data_size);
426 name_len = ntohs (attr_ser->name_len);
427 attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim)
428 + data_len + name_len + 1);
429 attr->type = ntohs (attr_ser->attribute_type);
430 attr->version = ntohl (attr_ser->attribute_version);
431 attr->data_size = ntohs (attr_ser->data_size);
433 write_ptr = (char*)&attr[1];
434 GNUNET_memcpy (write_ptr,
437 write_ptr[name_len] = '\0';
438 attr->name = write_ptr;
440 write_ptr += name_len + 1;
441 GNUNET_memcpy (write_ptr,
442 (char*)&attr_ser[1] + name_len,
444 attr->data = write_ptr;
449 /* end of identity_attribute.c */