gnunet_reclaim_lib.h (21938B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2017 GNUnet e.V. 4 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. 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 Affero General Public License for more details. 14 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/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 21 /** 22 * @addtogroup reclaim_suite RECLAIM services and libraries 23 * @{ 24 * 25 * @author Martin Schanzenbach 26 * 27 * @file 28 * Identity attribute definitions 29 * 30 * @defgroup reclaim-attribute Reclaim attributes 31 * @{ 32 */ 33 #ifndef GNUNET_RECLAIM_ATTRIBUTE_LIB_H 34 #define GNUNET_RECLAIM_ATTRIBUTE_LIB_H 35 36 #ifdef __cplusplus 37 extern "C" { 38 #if 0 /* keep Emacsens' auto-indent happy */ 39 } 40 #endif 41 #endif 42 43 44 #include "gnunet_util_lib.h" 45 46 enum GNUNET_RECLAIM_AttributeType { 47 /** 48 * No value attribute. 49 */ 50 GNUNET_RECLAIM_ATTRIBUTE_TYPE_NONE = 0, 51 52 /** 53 * String attribute. 54 */ 55 GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING = 1 56 }; 57 58 enum GNUNET_RECLAIM_CredentialType { 59 /** 60 * No value credential. 61 */ 62 GNUNET_RECLAIM_CREDENTIAL_TYPE_NONE = 0, 63 64 /** 65 * A JSON Web Token credential. 66 */ 67 GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT = 1, 68 69 /** 70 * libpabc credential 71 */ 72 GNUNET_RECLAIM_CREDENTIAL_TYPE_PABC = 2 73 }; 74 75 /** 76 * We want an ID to be a 256-bit symmetric key 77 */ 78 #define GNUNET_RECLAIM_ID_LENGTH (256 / 8) 79 80 GNUNET_NETWORK_STRUCT_BEGIN 81 /** 82 * A reclaim identifier 83 * FIXME maybe put this in a different namespace 84 */ 85 struct GNUNET_RECLAIM_Identifier 86 { 87 char id[GNUNET_RECLAIM_ID_LENGTH]; 88 }; 89 90 GNUNET_NETWORK_STRUCT_END 91 92 static const struct GNUNET_RECLAIM_Identifier GNUNET_RECLAIM_ID_ZERO; 93 94 #define GNUNET_RECLAIM_id_is_equal(a,b) ((0 == \ 95 memcmp (a, \ 96 b, \ 97 sizeof (GNUNET_RECLAIM_ID_ZERO))) \ 98 ? \ 99 GNUNET_YES : GNUNET_NO) 100 101 102 #define GNUNET_RECLAIM_id_is_zero(a) GNUNET_RECLAIM_id_is_equal (a, \ 103 & \ 104 GNUNET_RECLAIM_ID_ZERO) 105 106 #define GNUNET_RECLAIM_id_generate(id) \ 107 (GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, \ 108 id, \ 109 sizeof (GNUNET_RECLAIM_ID_ZERO))) 110 111 /** 112 * An attribute. 113 */ 114 struct GNUNET_RECLAIM_Attribute 115 { 116 /** 117 * ID 118 */ 119 struct GNUNET_RECLAIM_Identifier id; 120 121 /** 122 * Referenced ID of credential 123 * (may be GNUNET_RECLAIM_ID_ZERO if self-creded) 124 */ 125 struct GNUNET_RECLAIM_Identifier credential; 126 127 /** 128 * Type of Claim 129 */ 130 uint32_t type; 131 132 /** 133 * Flags 134 */ 135 uint32_t flag; 136 137 /** 138 * The name of the attribute. Note "name" must never be individually 139 * free'd 140 */ 141 const char *name; 142 143 /** 144 * Number of bytes in @e data. 145 */ 146 size_t data_size; 147 148 /** 149 * Binary value stored as attribute value. Note: "data" must never 150 * be individually 'malloc'ed, but instead always points into some 151 * existing data area. 152 */ 153 const void *data; 154 }; 155 156 /** 157 * A credential. 158 */ 159 struct GNUNET_RECLAIM_Credential 160 { 161 /** 162 * ID 163 */ 164 struct GNUNET_RECLAIM_Identifier id; 165 166 /** 167 * Type/Format of Claim 168 */ 169 uint32_t type; 170 171 /** 172 * Flag 173 */ 174 uint32_t flag; 175 176 /** 177 * The name of the credential. Note: must never be individually 178 * free'd 179 */ 180 const char *name; 181 182 /** 183 * Number of bytes in @e data. 184 */ 185 size_t data_size; 186 187 /** 188 * Binary value stored as credential value. Note: "data" must never 189 * be individually 'malloc'ed, but instead always points into some 190 * existing data area. 191 */ 192 const void *data; 193 }; 194 195 196 /** 197 * A credential presentation. 198 */ 199 struct GNUNET_RECLAIM_Presentation 200 { 201 /** 202 * The credential id of which this is a presentation. 203 */ 204 struct GNUNET_RECLAIM_Identifier credential_id; 205 206 /** 207 * Type/Format of Claim 208 */ 209 uint32_t type; 210 211 /** 212 * Number of bytes in @e data. 213 */ 214 size_t data_size; 215 216 /** 217 * Binary value stored as presentation value. Note: "data" must never 218 * be individually 'malloc'ed, but instead always points into some 219 * existing data area. 220 */ 221 const void *data; 222 }; 223 224 225 226 /** 227 * A list of GNUNET_RECLAIM_Attribute structures. 228 */ 229 struct GNUNET_RECLAIM_AttributeList 230 { 231 /** 232 * List head 233 */ 234 struct GNUNET_RECLAIM_AttributeListEntry *list_head; 235 236 /** 237 * List tail 238 */ 239 struct GNUNET_RECLAIM_AttributeListEntry *list_tail; 240 }; 241 242 243 struct GNUNET_RECLAIM_AttributeListEntry 244 { 245 /** 246 * DLL 247 */ 248 struct GNUNET_RECLAIM_AttributeListEntry *prev; 249 250 /** 251 * DLL 252 */ 253 struct GNUNET_RECLAIM_AttributeListEntry *next; 254 255 /** 256 * The attribute claim 257 */ 258 struct GNUNET_RECLAIM_Attribute *attribute; 259 260 }; 261 262 /** 263 * A list of GNUNET_RECLAIM_Credential structures. 264 */ 265 struct GNUNET_RECLAIM_CredentialList 266 { 267 /** 268 * List head 269 */ 270 struct GNUNET_RECLAIM_CredentialListEntry *list_head; 271 272 /** 273 * List tail 274 */ 275 struct GNUNET_RECLAIM_CredentialListEntry *list_tail; 276 }; 277 278 279 struct GNUNET_RECLAIM_CredentialListEntry 280 { 281 /** 282 * DLL 283 */ 284 struct GNUNET_RECLAIM_CredentialListEntry *prev; 285 286 /** 287 * DLL 288 */ 289 struct GNUNET_RECLAIM_CredentialListEntry *next; 290 291 /** 292 * The credential 293 */ 294 struct GNUNET_RECLAIM_Credential *credential; 295 296 }; 297 298 299 /** 300 * A list of GNUNET_RECLAIM_Presentation structures. 301 */ 302 struct GNUNET_RECLAIM_PresentationList 303 { 304 /** 305 * List head 306 */ 307 struct GNUNET_RECLAIM_PresentationListEntry *list_head; 308 309 /** 310 * List tail 311 */ 312 struct GNUNET_RECLAIM_PresentationListEntry *list_tail; 313 }; 314 315 316 struct GNUNET_RECLAIM_PresentationListEntry 317 { 318 /** 319 * DLL 320 */ 321 struct GNUNET_RECLAIM_PresentationListEntry *prev; 322 323 /** 324 * DLL 325 */ 326 struct GNUNET_RECLAIM_PresentationListEntry *next; 327 328 /** 329 * The credential 330 */ 331 struct GNUNET_RECLAIM_Presentation *presentation; 332 333 }; 334 335 336 337 /** 338 * Create a new attribute claim. 339 * 340 * @param attr_name the attribute name 341 * @param credential ID of the credential (may be NULL) 342 * @param type the attribute type 343 * @param data the attribute value. Must be #attr_name if credential not NULL 344 * @param data_size the attribute value size 345 * @return the new attribute 346 */ 347 struct GNUNET_RECLAIM_Attribute * 348 GNUNET_RECLAIM_attribute_new (const char *attr_name, 349 const struct 350 GNUNET_RECLAIM_Identifier *credential, 351 uint32_t type, 352 const void *data, 353 size_t data_size); 354 355 356 /** 357 * Get required size for serialization buffer 358 * 359 * @param attrs the attribute list to serialize 360 * @return the required buffer size 361 */ 362 size_t 363 GNUNET_RECLAIM_attribute_list_serialize_get_size ( 364 const struct GNUNET_RECLAIM_AttributeList *attrs); 365 366 367 /** 368 * Destroy claim list 369 * 370 * @param attrs list to destroy 371 */ 372 void 373 GNUNET_RECLAIM_attribute_list_destroy ( 374 struct GNUNET_RECLAIM_AttributeList *attrs); 375 376 377 /** 378 * Add a new attribute to a claim list 379 * 380 * @param attrs the attribute list to add to 381 * @param attr_name the name of the new attribute claim 382 * @param credential credential ID (may be NULL) 383 * @param type the type of the claim 384 * @param data claim payload 385 * @param data_size claim payload size 386 */ 387 void 388 GNUNET_RECLAIM_attribute_list_add ( 389 struct GNUNET_RECLAIM_AttributeList *attrs, 390 const char *attr_name, 391 const struct GNUNET_RECLAIM_Identifier *credential, 392 uint32_t type, 393 const void *data, 394 size_t data_size); 395 396 397 /** 398 * Serialize an attribute list 399 * 400 * @param attrs the attribute list to serialize 401 * @param result the serialized attribute 402 * @return length of serialized data 403 */ 404 size_t 405 GNUNET_RECLAIM_attribute_list_serialize ( 406 const struct GNUNET_RECLAIM_AttributeList *attrs, 407 char *result); 408 409 410 /** 411 * Deserialize an attribute list 412 * 413 * @param data the serialized attribute list 414 * @param data_size the length of the serialized data 415 * @return a GNUNET_IDENTITY_PROVIDER_AttributeList, must be free'd by caller 416 */ 417 struct GNUNET_RECLAIM_AttributeList * 418 GNUNET_RECLAIM_attribute_list_deserialize (const char *data, size_t data_size); 419 420 /** 421 * Get required size for serialization buffer 422 * 423 * @param attr the attribute to serialize 424 * @return the required buffer size 425 */ 426 size_t 427 GNUNET_RECLAIM_attribute_serialize_get_size ( 428 const struct GNUNET_RECLAIM_Attribute *attr); 429 430 431 /** 432 * Serialize an attribute 433 * 434 * @param attr the attribute to serialize 435 * @param result the serialized attribute 436 * @return length of serialized data 437 */ 438 size_t 439 GNUNET_RECLAIM_attribute_serialize (const struct GNUNET_RECLAIM_Attribute *attr, 440 char *result); 441 442 443 /** 444 * Deserialize an attribute 445 * 446 * @param data the serialized attribute 447 * @param data_size the length of the serialized data 448 * @param attr deserialized attribute. Will be allocated. Must be free'd 449 * 450 * @return number of bytes read or -1 for error 451 */ 452 ssize_t 453 GNUNET_RECLAIM_attribute_deserialize (const char *data, size_t data_size, 454 struct GNUNET_RECLAIM_Attribute **attr); 455 456 457 /** 458 * Make a (deep) copy of a claim list 459 * @param attrs claim list to copy 460 * @return copied claim list 461 */ 462 struct GNUNET_RECLAIM_AttributeList * 463 GNUNET_RECLAIM_attribute_list_dup ( 464 const struct GNUNET_RECLAIM_AttributeList *attrs); 465 466 467 /** 468 * Convert a type name to the corresponding number 469 * 470 * @param typename name to convert 471 * @return corresponding number, UINT32_MAX on error 472 */ 473 uint32_t 474 GNUNET_RECLAIM_attribute_typename_to_number (const char *typename); 475 476 /** 477 * Convert human-readable version of a 'claim' of an attribute to the binary 478 * representation 479 * 480 * @param type type of the claim 481 * @param s human-readable string 482 * @param data set to value in binary encoding (will be allocated) 483 * @param data_size set to number of bytes in @a data 484 * @return #GNUNET_OK on success 485 */ 486 int 487 GNUNET_RECLAIM_attribute_string_to_value (uint32_t type, 488 const char *s, 489 void **data, 490 size_t *data_size); 491 492 493 /** 494 * Convert the 'claim' of an attribute to a string 495 * 496 * @param type the type of attribute 497 * @param data claim in binary encoding 498 * @param data_size number of bytes in @a data 499 * @return NULL on error, otherwise human-readable representation of the claim 500 */ 501 char * 502 GNUNET_RECLAIM_attribute_value_to_string (uint32_t type, 503 const void *data, 504 size_t data_size); 505 506 /** 507 * Convert a type number to the corresponding type string 508 * 509 * @param type number of a type 510 * @return corresponding typestring, NULL on error 511 */ 512 const char * 513 GNUNET_RECLAIM_attribute_number_to_typename (uint32_t type); 514 515 516 /** 517 * Get required size for serialization buffer 518 * 519 * @param credentials the attribute list to serialize 520 * @return the required buffer size 521 */ 522 size_t 523 GNUNET_RECLAIM_credential_list_serialize_get_size ( 524 const struct GNUNET_RECLAIM_CredentialList *credentials); 525 526 527 /** 528 * Destroy credential list 529 * 530 * @param credentials list to destroy 531 */ 532 void 533 GNUNET_RECLAIM_credential_list_destroy ( 534 struct GNUNET_RECLAIM_CredentialList *credentials); 535 536 537 /** 538 * Add a new attribute to a claim list 539 * 540 * @param attr_name the name of the new attribute claim 541 * @param type the type of the claim 542 * @param data claim payload 543 * @param data_size claim payload size 544 */ 545 void 546 GNUNET_RECLAIM_credential_list_add ( 547 struct GNUNET_RECLAIM_CredentialList *attrs, 548 const char *att_name, 549 uint32_t type, 550 const void *data, 551 size_t data_size); 552 553 554 /** 555 * Serialize a credential list 556 * 557 * @param credentials the credential list to serialize 558 * @param result the serialized credential 559 * @return length of serialized data 560 */ 561 size_t 562 GNUNET_RECLAIM_credential_list_serialize ( 563 const struct GNUNET_RECLAIM_CredentialList *credentials, 564 char *result); 565 566 567 /** 568 * Deserialize an attribute list 569 * 570 * @param data the serialized attribute list 571 * @param data_size the length of the serialized data 572 * @return a GNUNET_IDENTITY_PROVIDER_AttributeList, must be free'd by caller 573 */ 574 struct GNUNET_RECLAIM_CredentialList * 575 GNUNET_RECLAIM_credential_list_deserialize (const char *data, 576 size_t data_size); 577 578 579 /** 580 * @param credential the credential to serialize 581 * @return the required buffer size 582 */ 583 size_t 584 GNUNET_RECLAIM_credential_serialize_get_size ( 585 const struct GNUNET_RECLAIM_Credential *credential); 586 587 588 /** 589 * Serialize an credential 590 * 591 * @param credential the credential to serialize 592 * @param result the serialized credential 593 * @return length of serialized data 594 */ 595 size_t 596 GNUNET_RECLAIM_credential_serialize ( 597 const struct GNUNET_RECLAIM_Credential *credential, 598 char *result); 599 600 601 /** 602 * Deserialize an credential 603 * 604 * @param data the serialized credential 605 * @param data_size the length of the serialized data 606 * 607 * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller 608 */ 609 struct GNUNET_RECLAIM_Credential * 610 GNUNET_RECLAIM_credential_deserialize (const char *data, size_t data_size); 611 612 613 /** 614 * Create a new credential. 615 * 616 * @param name the credential name 617 * @param type the credential type 618 * @param data the credential value 619 * @param data_size the credential value size 620 * @return the new credential 621 */ 622 struct GNUNET_RECLAIM_Credential * 623 GNUNET_RECLAIM_credential_new (const char *name, 624 uint32_t type, 625 const void *data, 626 size_t data_size); 627 628 /** 629 * Convert the 'claim' of an credential to a string 630 * 631 * @param type the type of credential 632 * @param data claim in binary encoding 633 * @param data_size number of bytes in @a data 634 * @return NULL on error, otherwise human-readable representation of the claim 635 */ 636 char * 637 GNUNET_RECLAIM_credential_value_to_string (uint32_t type, 638 const void *data, 639 size_t data_size); 640 641 /** 642 * Convert human-readable version of a 'claim' of an credential to the binary 643 * representation 644 * 645 * @param type type of the claim 646 * @param s human-readable string 647 * @param data set to value in binary encoding (will be allocated) 648 * @param data_size set to number of bytes in @a data 649 * @return #GNUNET_OK on success 650 */ 651 int 652 GNUNET_RECLAIM_credential_string_to_value (uint32_t type, 653 const char *s, 654 void **data, 655 size_t *data_size); 656 657 /** 658 * Convert an credential type number to the corresponding credential type string 659 * 660 * @param type number of a type 661 * @return corresponding typestring, NULL on error 662 */ 663 const char * 664 GNUNET_RECLAIM_credential_number_to_typename (uint32_t type); 665 666 /** 667 * Convert an credential type name to the corresponding number 668 * 669 * @param typename name to convert 670 * @return corresponding number, UINT32_MAX on error 671 */ 672 uint32_t 673 GNUNET_RECLAIM_credential_typename_to_number (const char *typename); 674 675 /** 676 * Convert an credential type name to the corresponding number 677 * 678 * @param typename name to convert 679 * @return corresponding number, UINT32_MAX on error 680 */ 681 struct GNUNET_RECLAIM_AttributeList* 682 GNUNET_RECLAIM_credential_get_attributes (const struct 683 GNUNET_RECLAIM_Credential *cred); 684 685 char* 686 GNUNET_RECLAIM_credential_get_issuer (const struct 687 GNUNET_RECLAIM_Credential *cred); 688 689 int 690 GNUNET_RECLAIM_credential_get_expiration (const struct 691 GNUNET_RECLAIM_Credential *cred, 692 struct GNUNET_TIME_Absolute *exp); 693 694 /** 695 * Get required size for serialization buffer 696 * 697 * @param presentations the presentation list to serialize 698 * @return the required buffer size 699 */ 700 size_t 701 GNUNET_RECLAIM_presentation_list_serialize_get_size ( 702 const struct GNUNET_RECLAIM_PresentationList *presentations); 703 704 705 /** 706 * Destroy presentations list 707 * 708 * @param presentations list to destroy 709 */ 710 void 711 GNUNET_RECLAIM_presentation_list_destroy ( 712 struct GNUNET_RECLAIM_PresentationList *presentations); 713 714 715 /** 716 * Serialize a presentation list 717 * 718 * @param presentations the attribute list to serialize 719 * @param result the serialized list 720 * @return length of serialized data 721 */ 722 size_t 723 GNUNET_RECLAIM_presentation_list_serialize ( 724 const struct GNUNET_RECLAIM_PresentationList *presentations, 725 char *result); 726 727 728 /** 729 * Deserialize a presentation list 730 * 731 * @param data the serialized list 732 * @param data_size the length of the serialized data 733 * @return a GNUNET_RECLAIM_PresentationList, must be free'd by caller 734 */ 735 struct GNUNET_RECLAIM_PresentationList * 736 GNUNET_RECLAIM_presentation_list_deserialize (const char *data, 737 size_t data_size); 738 739 740 /** 741 * @param presentation the presentation to serialize 742 * @return the required buffer size 743 */ 744 size_t 745 GNUNET_RECLAIM_presentation_serialize_get_size ( 746 const struct GNUNET_RECLAIM_Presentation *presentation); 747 748 749 /** 750 * Serialize a presentation. 751 * 752 * @param presentation the presentation to serialize 753 * @param result the serialized presentation 754 * @return length of serialized data 755 */ 756 size_t 757 GNUNET_RECLAIM_presentation_serialize ( 758 const struct GNUNET_RECLAIM_Presentation *presentation, 759 char *result); 760 761 762 /** 763 * Deserialize a presentation 764 * 765 * @param data the serialized presentation 766 * @param data_size the length of the serialized data 767 * 768 * @return a GNUNET_RECLAIM_Presentation, must be free'd by caller 769 */ 770 struct GNUNET_RECLAIM_Presentation * 771 GNUNET_RECLAIM_presentation_deserialize (const char *data, size_t data_size); 772 773 774 /** 775 * Convert the 'claim' of a presentation to a string 776 * 777 * @param type the type of presentation 778 * @param data presentation in binary encoding 779 * @param data_size number of bytes in @a data 780 * @return NULL on error, otherwise human-readable representation of the claim 781 */ 782 char * 783 GNUNET_RECLAIM_presentation_value_to_string (uint32_t type, 784 const void *data, 785 size_t data_size); 786 787 struct GNUNET_RECLAIM_Presentation * 788 GNUNET_RECLAIM_presentation_new (uint32_t type, 789 const void *data, 790 size_t data_size); 791 792 /** 793 * Convert human-readable version of a 'claim' of a presentation to the binary 794 * representation 795 * 796 * @param type type of the presentation 797 * @param s human-readable string 798 * @param data set to value in binary encoding (will be allocated) 799 * @param data_size set to number of bytes in @a data 800 * @return #GNUNET_OK on success 801 */ 802 int 803 GNUNET_RECLAIM_presentation_string_to_value (uint32_t type, 804 const char *s, 805 void **data, 806 size_t *data_size); 807 808 /** 809 * Convert a presentation type number to the corresponding credential type 810 * string. 811 * 812 * @param type number of a type 813 * @return corresponding typestring, NULL on error 814 */ 815 const char * 816 GNUNET_RECLAIM_presentation_number_to_typename (uint32_t type); 817 818 /** 819 * Convert an presentation type name to the corresponding number 820 * 821 * @param typename name to convert 822 * @return corresponding number, UINT32_MAX on error 823 */ 824 uint32_t 825 GNUNET_RECLAIM_presentation_typename_to_number (const char *typename); 826 827 struct GNUNET_RECLAIM_AttributeList* 828 GNUNET_RECLAIM_presentation_get_attributes (const struct 829 GNUNET_RECLAIM_Presentation *cred); 830 831 char* 832 GNUNET_RECLAIM_presentation_get_issuer (const struct 833 GNUNET_RECLAIM_Presentation *cred); 834 835 int 836 GNUNET_RECLAIM_presentation_get_expiration (const struct 837 GNUNET_RECLAIM_Presentation *cred, 838 struct GNUNET_TIME_Absolute *exp); 839 840 841 /** 842 * Make a (deep) copy of the presentation list 843 * @param attrs claim list to copy 844 * @return copied claim list 845 */ 846 struct GNUNET_RECLAIM_PresentationList * 847 GNUNET_RECLAIM_presentation_list_dup ( 848 const struct GNUNET_RECLAIM_PresentationList *al); 849 850 /** 851 * Create a presentation from a credential and a lift of (selected) 852 * attributes in the credential. 853 * FIXME not yet implemented 854 * 855 * @param cred the credential to use 856 * @param attrs the attributes to present from the credential 857 * @param presentation the credential presentation presenting the attributes according 858 * to the presentation mechanism of the credential 859 * or NULL on error. 860 * @return GNUNET_OK on success. 861 */ 862 int 863 GNUNET_RECLAIM_credential_get_presentation ( 864 const struct GNUNET_RECLAIM_Credential *cred, 865 const struct GNUNET_RECLAIM_AttributeList *attrs, 866 struct GNUNET_RECLAIM_Presentation **presentation); 867 868 struct GNUNET_RECLAIM_CredentialList * 869 GNUNET_RECLAIM_credential_list_dup ( 870 const struct GNUNET_RECLAIM_CredentialList *al); 871 872 #if 0 /* keep Emacsens' auto-indent happy */ 873 { 874 #endif 875 #ifdef __cplusplus 876 } 877 #endif 878 879 880 /* ifndef GNUNET_RECLAIM_ATTRIBUTE_LIB_H */ 881 #endif 882 883 /** @} */ /* end of group reclaim-attribute */ 884 885 /** @} */ /* end of group addition */ 886 887 /* end of gnunet_reclaim_attribute_lib.h */