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 it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file reclaim-attribute/reclaim_attribute.c
23 * @brief helper library to manage identity attributes
24 * @author Martin Schanzenbach
27 #include "gnunet_util_lib.h"
28 #include "gnunet_reclaim_attribute_plugin.h"
29 #include "reclaim_attribute.h"
45 struct GNUNET_RECLAIM_ATTRIBUTE_PluginFunctions *api;
52 static struct Plugin **attr_plugins;
58 static unsigned int num_plugins;
64 static int initialized;
71 * @param library_name name of the API library
72 * @param lib_ret the plugin API pointer
75 add_plugin (void *cls, const char *library_name, void *lib_ret)
77 struct GNUNET_RECLAIM_ATTRIBUTE_PluginFunctions *api = lib_ret;
78 struct Plugin *plugin;
80 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
81 "Loading attribute plugin `%s'\n",
83 plugin = GNUNET_new (struct Plugin);
85 plugin->library_name = GNUNET_strdup (library_name);
86 GNUNET_array_append (attr_plugins, num_plugins, plugin);
96 if (GNUNET_YES == initialized)
98 initialized = GNUNET_YES;
99 GNUNET_PLUGIN_load_all ("libgnunet_plugin_reclaim_attribute_",
107 * Convert a type name to the corresponding number
109 * @param typename name to convert
110 * @return corresponding number, UINT32_MAX on error
113 GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (const char *typename)
116 struct Plugin *plugin;
120 for (i = 0; i < num_plugins; i++)
122 plugin = attr_plugins[i];
124 (ret = plugin->api->typename_to_number (plugin->api->cls, typename)))
132 * Convert a type number to the corresponding type string
134 * @param type number of a type
135 * @return corresponding typestring, NULL on error
138 GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (uint32_t type)
141 struct Plugin *plugin;
145 for (i = 0; i < num_plugins; i++)
147 plugin = attr_plugins[i];
149 (ret = plugin->api->number_to_typename (plugin->api->cls, type)))
157 * Convert human-readable version of a 'claim' of an attribute to the binary
160 * @param type type of the claim
161 * @param s human-readable string
162 * @param data set to value in binary encoding (will be allocated)
163 * @param data_size set to number of bytes in @a data
164 * @return #GNUNET_OK on success
167 GNUNET_RECLAIM_ATTRIBUTE_string_to_value (uint32_t type,
173 struct Plugin *plugin;
176 for (i = 0; i < num_plugins; i++)
178 plugin = attr_plugins[i];
179 if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
186 return GNUNET_SYSERR;
191 * Convert the 'claim' of an attribute to a string
193 * @param type the type of attribute
194 * @param data claim in binary encoding
195 * @param data_size number of bytes in @a data
196 * @return NULL on error, otherwise human-readable representation of the claim
199 GNUNET_RECLAIM_ATTRIBUTE_value_to_string (uint32_t type,
204 struct Plugin *plugin;
208 for (i = 0; i < num_plugins; i++)
210 plugin = attr_plugins[i];
211 if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
222 * Create a new attribute.
224 * @param attr_name the attribute name
225 * @param type the attribute type
226 * @param data the attribute value
227 * @param data_size the attribute value size
228 * @return the new attribute
230 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *
231 GNUNET_RECLAIM_ATTRIBUTE_claim_new (const char *attr_name,
236 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
238 char *attr_name_tmp = GNUNET_strdup (attr_name);
240 GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
242 attr = GNUNET_malloc (sizeof (struct GNUNET_RECLAIM_ATTRIBUTE_Claim) +
243 strlen (attr_name_tmp) + 1 + data_size);
245 attr->data_size = data_size;
247 write_ptr = (char *) &attr[1];
248 GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
249 attr->name = write_ptr;
250 write_ptr += strlen (attr->name) + 1;
251 GNUNET_memcpy (write_ptr, data, data_size);
252 attr->data = write_ptr;
253 GNUNET_free (attr_name_tmp);
259 * Add a new attribute to a claim list
261 * @param attr_name the name of the new attribute claim
262 * @param type the type of the claim
263 * @param data claim payload
264 * @param data_size claim payload size
267 GNUNET_RECLAIM_ATTRIBUTE_list_add (
268 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *claim_list,
269 const char *attr_name,
274 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
275 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
277 GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr_name, type, data, data_size);
278 GNUNET_CONTAINER_DLL_insert (claim_list->list_head,
279 claim_list->list_tail,
285 * Get required size for serialization buffer
287 * @param attrs the attribute list to serialize
288 * @return the required buffer size
291 GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (
292 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
294 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
296 for (le = attrs->list_head; NULL != le; le = le->next)
297 len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
303 * Serialize an attribute list
305 * @param attrs the attribute list to serialize
306 * @param result the serialized attribute
307 * @return length of serialized data
310 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (
311 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
314 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
321 for (le = attrs->list_head; NULL != le; le = le->next)
323 len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim, write_ptr);
332 * Deserialize an attribute list
334 * @param data the serialized attribute list
335 * @param data_size the length of the serialized data
336 * @return a GNUNET_IDENTITY_PROVIDER_AttributeList, must be free'd by caller
338 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *
339 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char *data, size_t data_size)
341 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
342 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
344 const char *read_ptr;
346 if (data_size < sizeof (struct Attribute))
349 attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
351 while (((data + data_size) - read_ptr) >= sizeof (struct Attribute))
354 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
356 GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr,
357 data_size - (read_ptr - data));
358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
359 "Deserialized attribute %s\n",
361 GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
362 attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
363 read_ptr += attr_len;
370 * Make a (deep) copy of a claim list
371 * @param attrs claim list to copy
372 * @return copied claim list
374 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *
375 GNUNET_RECLAIM_ATTRIBUTE_list_dup (
376 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
378 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
379 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *result_le;
380 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *result;
382 result = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
383 for (le = attrs->list_head; NULL != le; le = le->next)
385 result_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
387 GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name,
390 le->claim->data_size);
391 result_le->claim->version = le->claim->version;
392 result_le->claim->id = le->claim->id;
393 GNUNET_CONTAINER_DLL_insert (result->list_head,
404 * @param attrs list to destroy
407 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (
408 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
410 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
411 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *tmp_le;
413 for (le = attrs->list_head; NULL != le;)
415 GNUNET_free (le->claim);
418 GNUNET_free (tmp_le);
425 * Get required size for serialization buffer
427 * @param attr the attribute to serialize
428 * @return the required buffer size
431 GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (
432 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
434 return sizeof (struct Attribute) + strlen (attr->name) + attr->data_size;
439 * Serialize an attribute
441 * @param attr the attribute to serialize
442 * @param result the serialized attribute
443 * @return length of serialized data
446 GNUNET_RECLAIM_ATTRIBUTE_serialize (
447 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
452 struct Attribute *attr_ser;
455 attr_ser = (struct Attribute *) result;
456 attr_ser->attribute_type = htons (attr->type);
457 attr_ser->attribute_version = htonl (attr->version);
458 attr_ser->attribute_id = GNUNET_htonll (attr->id);
459 name_len = strlen (attr->name);
460 attr_ser->name_len = htons (name_len);
461 write_ptr = (char *) &attr_ser[1];
462 GNUNET_memcpy (write_ptr, attr->name, name_len);
463 write_ptr += name_len;
465 // data_len_ser = plugin->serialize_attribute_value (attr,
467 data_len_ser = attr->data_size;
468 GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
469 attr_ser->data_size = htons (data_len_ser);
471 return sizeof (struct Attribute) + strlen (attr->name) + attr->data_size;
476 * Deserialize an attribute
478 * @param data the serialized attribute
479 * @param data_size the length of the serialized data
481 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
483 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *
484 GNUNET_RECLAIM_ATTRIBUTE_deserialize (const char *data, size_t data_size)
486 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
487 struct Attribute *attr_ser;
492 if (data_size < sizeof (struct Attribute))
495 attr_ser = (struct Attribute *) data;
496 data_len = ntohs (attr_ser->data_size);
497 name_len = ntohs (attr_ser->name_len);
498 attr = GNUNET_malloc (sizeof (struct GNUNET_RECLAIM_ATTRIBUTE_Claim) +
499 data_len + name_len + 1);
500 attr->type = ntohs (attr_ser->attribute_type);
501 attr->version = ntohl (attr_ser->attribute_version);
502 attr->id = GNUNET_ntohll (attr_ser->attribute_id);
503 attr->data_size = ntohs (attr_ser->data_size);
505 write_ptr = (char *) &attr[1];
506 GNUNET_memcpy (write_ptr, &attr_ser[1], name_len);
507 write_ptr[name_len] = '\0';
508 attr->name = write_ptr;
510 write_ptr += name_len + 1;
511 GNUNET_memcpy (write_ptr, (char *) &attr_ser[1] + name_len, attr->data_size);
512 attr->data = write_ptr;
516 /* end of reclaim_attribute.c */