2 This file is part of GNUnet.
3 Copyright (C) 2012-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
21 * @author Martin Schanzenbach
22 * @author Philippe Buschmann
23 * @file reclaim/plugin_rest_reclaim.c
24 * @brief GNUnet reclaim REST plugin
29 #include "gnunet_rest_plugin.h"
30 #include "gnunet_identity_service.h"
31 #include "gnunet_gns_service.h"
32 #include "gnunet_gnsrecord_lib.h"
33 #include "gnunet_namestore_service.h"
34 #include "gnunet_rest_lib.h"
35 #include "microhttpd.h"
38 #include "gnunet_signatures.h"
39 #include "gnunet_reclaim_attribute_lib.h"
40 #include "gnunet_reclaim_service.h"
41 #include "json_reclaim.h"
46 #define GNUNET_REST_API_NS_RECLAIM "/reclaim"
51 #define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes"
56 #define GNUNET_REST_API_NS_IDENTITY_TICKETS "/reclaim/tickets"
61 #define GNUNET_REST_API_NS_IDENTITY_REVOKE "/reclaim/revoke"
66 #define GNUNET_REST_API_NS_IDENTITY_CONSUME "/reclaim/consume"
69 * State while collecting all egos
71 #define ID_REST_STATE_INIT 0
74 * Done collecting egos
76 #define ID_REST_STATE_POST_INIT 1
79 * The configuration handle
81 const struct GNUNET_CONFIGURATION_Handle *cfg;
84 * HTTP methods allows for this plugin
86 static char* allow_methods;
89 * @brief struct returned by the initialization function of the plugin
93 const struct GNUNET_CONFIGURATION_Handle *cfg;
104 struct EgoEntry *next;
109 struct EgoEntry *prev;
124 struct GNUNET_IDENTITY_Ego *ego;
133 struct EgoEntry *ego_head;
138 struct EgoEntry *ego_tail;
143 struct EgoEntry *ego_entry;
146 * Pointer to ego private key
148 struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key;
151 * The processing state
156 * Handle to Identity service.
158 struct GNUNET_IDENTITY_Handle *identity_handle;
163 struct GNUNET_REST_RequestHandle *rest_handle;
166 * Handle to NAMESTORE
168 struct GNUNET_NAMESTORE_Handle *namestore_handle;
171 * Iterator for NAMESTORE
173 struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it;
176 * Attribute claim list
178 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attr_list;
183 struct GNUNET_IDENTITY_Operation *op;
188 struct GNUNET_RECLAIM_Handle *idp;
193 struct GNUNET_RECLAIM_Operation *idp_op;
198 struct GNUNET_RECLAIM_AttributeIterator *attr_it;
203 struct GNUNET_RECLAIM_TicketIterator *ticket_it;
208 struct GNUNET_RECLAIM_Ticket ticket;
211 * Desired timeout for the lookup (default is no timeout).
213 struct GNUNET_TIME_Relative timeout;
216 * ID of a task associated with the resolution process.
218 struct GNUNET_SCHEDULER_Task *timeout_task;
221 * The plugin result processor
223 GNUNET_REST_ResultProcessor proc;
226 * The closure of the result processor
236 * Error response message
253 * Cleanup lookup handle
254 * @param handle Handle to clean up
257 cleanup_handle (struct RequestHandle *handle)
259 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry;
260 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp;
261 struct EgoEntry *ego_entry;
262 struct EgoEntry *ego_tmp;
263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
265 if (NULL != handle->resp_object)
266 json_decref (handle->resp_object);
267 if (NULL != handle->timeout_task)
268 GNUNET_SCHEDULER_cancel (handle->timeout_task);
269 if (NULL != handle->identity_handle)
270 GNUNET_IDENTITY_disconnect (handle->identity_handle);
271 if (NULL != handle->attr_it)
272 GNUNET_RECLAIM_get_attributes_stop (handle->attr_it);
273 if (NULL != handle->ticket_it)
274 GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it);
275 if (NULL != handle->idp)
276 GNUNET_RECLAIM_disconnect (handle->idp);
277 if (NULL != handle->url)
278 GNUNET_free (handle->url);
279 if (NULL != handle->emsg)
280 GNUNET_free (handle->emsg);
281 if (NULL != handle->namestore_handle)
282 GNUNET_NAMESTORE_disconnect (handle->namestore_handle);
283 if ( NULL != handle->attr_list )
285 for (claim_entry = handle->attr_list->list_head;
286 NULL != claim_entry;)
288 claim_tmp = claim_entry;
289 claim_entry = claim_entry->next;
290 GNUNET_free(claim_tmp->claim);
291 GNUNET_free(claim_tmp);
293 GNUNET_free (handle->attr_list);
295 for (ego_entry = handle->ego_head;
299 ego_entry = ego_entry->next;
300 GNUNET_free (ego_tmp->identifier);
301 GNUNET_free (ego_tmp->keystring);
302 GNUNET_free (ego_tmp);
304 if (NULL != handle->attr_it)
306 GNUNET_free(handle->attr_it);
308 GNUNET_free (handle);
312 cleanup_handle_delayed (void *cls)
314 cleanup_handle (cls);
319 * Task run on error, sends error message. Cleans up everything.
321 * @param cls the `struct RequestHandle`
326 struct RequestHandle *handle = cls;
327 struct MHD_Response *resp;
330 GNUNET_asprintf (&json_error, "{ \"error\" : \"%s\" }",
332 if ( 0 == handle->response_code )
334 handle->response_code = MHD_HTTP_BAD_REQUEST;
336 resp = GNUNET_REST_create_response (json_error);
337 MHD_add_response_header (resp, "Content-Type", "application/json");
338 handle->proc (handle->proc_cls, resp, handle->response_code);
339 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
340 GNUNET_free (json_error);
345 * Task run on timeout, sends error message. Cleans up everything.
347 * @param cls the `struct RequestHandle`
350 do_timeout (void *cls)
352 struct RequestHandle *handle = cls;
354 handle->timeout_task = NULL;
360 collect_error_cb (void *cls)
362 struct RequestHandle *handle = cls;
368 finished_cont (void *cls,
372 struct RequestHandle *handle = cls;
373 struct MHD_Response *resp;
375 resp = GNUNET_REST_create_response (emsg);
376 if (GNUNET_OK != success)
378 GNUNET_SCHEDULER_add_now (&do_error, handle);
381 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
382 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
387 * Return attributes for identity
389 * @param cls the request handle
392 return_response (void *cls)
395 struct RequestHandle *handle = cls;
396 struct MHD_Response *resp;
398 result_str = json_dumps (handle->resp_object, 0);
399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
400 resp = GNUNET_REST_create_response (result_str);
401 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
402 GNUNET_free (result_str);
403 cleanup_handle (handle);
407 collect_finished_cb (void *cls)
409 struct RequestHandle *handle = cls;
411 handle->attr_it = NULL;
412 handle->ticket_it = NULL;
413 GNUNET_SCHEDULER_add_now (&return_response, handle);
418 * Collect all attributes for an ego
422 ticket_collect (void *cls,
423 const struct GNUNET_RECLAIM_Ticket *ticket)
425 json_t *json_resource;
426 struct RequestHandle *handle = cls;
430 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding ticket\n");
431 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
433 json_resource = json_object ();
435 json_array_append (handle->resp_object,
438 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->identity,
439 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
440 value = json_string (tmp);
441 json_object_set_new (json_resource,
445 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->audience,
446 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
447 value = json_string (tmp);
448 json_object_set_new (json_resource,
452 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
454 value = json_string (tmp);
455 json_object_set_new (json_resource,
459 GNUNET_RECLAIM_ticket_iteration_next (handle->ticket_it);
465 * List tickets for identity request
467 * @param con_handle the connection handle
469 * @param cls the RequestHandle
472 list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle,
476 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
477 struct RequestHandle *handle = cls;
478 struct EgoEntry *ego_entry;
481 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting tickets for %s.\n",
483 if ( strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >=
484 strlen (handle->url))
486 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
487 GNUNET_SCHEDULER_add_now (&do_error, handle);
490 identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
492 for (ego_entry = handle->ego_head;
494 ego_entry = ego_entry->next)
495 if (0 == strcmp (identity, ego_entry->identifier))
497 handle->resp_object = json_array ();
499 if (NULL == ego_entry)
502 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n",
504 GNUNET_SCHEDULER_add_now (&return_response, handle);
507 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
508 handle->idp = GNUNET_RECLAIM_connect (cfg);
509 handle->ticket_it = GNUNET_RECLAIM_ticket_iteration_start (handle->idp,
515 &collect_finished_cb,
521 add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
525 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
526 const char* identity;
527 struct RequestHandle *handle = cls;
528 struct EgoEntry *ego_entry;
529 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute;
530 struct GNUNET_TIME_Relative exp;
531 char term_data[handle->rest_handle->data_size+1];
534 struct GNUNET_JSON_Specification attrspec[] = {
535 GNUNET_RECLAIM_JSON_spec_claim (&attribute),
536 GNUNET_JSON_spec_end()
539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding an attribute for %s.\n",
541 if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >=
542 strlen (handle->url))
544 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
545 GNUNET_SCHEDULER_add_now (&do_error, handle);
548 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
550 for (ego_entry = handle->ego_head;
552 ego_entry = ego_entry->next)
553 if (0 == strcmp (identity, ego_entry->identifier))
556 if (NULL == ego_entry)
558 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
559 "Identity unknown (%s)\n", identity);
562 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
564 if (0 >= handle->rest_handle->data_size)
566 GNUNET_SCHEDULER_add_now (&do_error, handle);
570 term_data[handle->rest_handle->data_size] = '\0';
571 GNUNET_memcpy (term_data,
572 handle->rest_handle->data,
573 handle->rest_handle->data_size);
574 data_json = json_loads (term_data,
577 GNUNET_assert (GNUNET_OK ==
578 GNUNET_JSON_parse (data_json, attrspec,
580 json_decref (data_json);
581 if (NULL == attribute)
583 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
584 "Unable to parse attribute from %s\n",
586 GNUNET_SCHEDULER_add_now (&do_error, handle);
589 handle->idp = GNUNET_RECLAIM_connect (cfg);
590 exp = GNUNET_TIME_UNIT_HOURS;
591 handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
597 GNUNET_JSON_parse_free (attrspec);
603 * Collect all attributes for an ego
607 attr_collect (void *cls,
608 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
609 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
611 struct RequestHandle *handle = cls;
616 if ((NULL == attr->name) || (NULL == attr->data))
618 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n",
625 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
629 attr_obj = json_object ();
630 json_object_set_new (attr_obj,
632 json_string (tmp_value));
633 json_object_set_new (attr_obj,
635 json_string (attr->name));
636 type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
637 json_object_set_new (attr_obj,
640 json_array_append (handle->resp_object,
642 json_decref (attr_obj);
643 GNUNET_free(tmp_value);
644 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
650 * List attributes for identity request
652 * @param con_handle the connection handle
654 * @param cls the RequestHandle
657 list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
661 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
662 struct RequestHandle *handle = cls;
663 struct EgoEntry *ego_entry;
666 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting attributes for %s.\n",
668 if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >=
669 strlen (handle->url))
671 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
672 GNUNET_SCHEDULER_add_now (&do_error, handle);
675 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
677 for (ego_entry = handle->ego_head;
679 ego_entry = ego_entry->next)
680 if (0 == strcmp (identity, ego_entry->identifier))
682 handle->resp_object = json_array ();
685 if (NULL == ego_entry)
688 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n",
690 GNUNET_SCHEDULER_add_now (&return_response, handle);
693 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
694 handle->idp = GNUNET_RECLAIM_connect (cfg);
695 handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
701 &collect_finished_cb,
707 revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
711 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
712 struct RequestHandle *handle = cls;
713 struct EgoEntry *ego_entry;
714 struct GNUNET_RECLAIM_Ticket *ticket;
715 struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
716 char term_data[handle->rest_handle->data_size+1];
719 struct GNUNET_JSON_Specification tktspec[] = {
720 GNUNET_RECLAIM_JSON_spec_ticket (&ticket),
721 GNUNET_JSON_spec_end()
724 if (0 >= handle->rest_handle->data_size)
726 GNUNET_SCHEDULER_add_now (&do_error, handle);
730 term_data[handle->rest_handle->data_size] = '\0';
731 GNUNET_memcpy (term_data,
732 handle->rest_handle->data,
733 handle->rest_handle->data_size);
734 data_json = json_loads (term_data,
737 GNUNET_assert (GNUNET_OK ==
738 GNUNET_JSON_parse (data_json, tktspec,
740 json_decref (data_json);
743 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
744 "Unable to parse ticket from %s\n",
746 GNUNET_SCHEDULER_add_now (&do_error, handle);
749 if (GNUNET_OK != GNUNET_JSON_parse (data_json,
753 handle->emsg = GNUNET_strdup ("Not a ticket!\n");
754 GNUNET_SCHEDULER_add_now (&do_error, handle);
755 GNUNET_JSON_parse_free (tktspec);
756 json_decref (data_json);
760 for (ego_entry = handle->ego_head;
762 ego_entry = ego_entry->next)
764 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
766 if (0 == memcmp (&ticket->identity,
768 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
771 if (NULL == ego_entry)
773 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
774 "Identity unknown\n");
775 GNUNET_JSON_parse_free (tktspec);
778 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
780 handle->idp = GNUNET_RECLAIM_connect (cfg);
781 handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp,
786 GNUNET_JSON_parse_free (tktspec);
790 consume_cont (void *cls,
791 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
792 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
794 struct RequestHandle *handle = cls;
798 if (NULL == identity)
800 GNUNET_SCHEDULER_add_now (&return_response, handle);
804 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n",
806 val_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
811 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to parse value for: %s\n",
815 value = json_string(val_str);
816 json_object_set_new (handle->resp_object,
820 GNUNET_free (val_str);
824 consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
828 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
829 struct RequestHandle *handle = cls;
830 struct EgoEntry *ego_entry;
831 struct GNUNET_RECLAIM_Ticket *ticket;
832 struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
833 char term_data[handle->rest_handle->data_size+1];
836 struct GNUNET_JSON_Specification tktspec[] = {
837 GNUNET_RECLAIM_JSON_spec_ticket (&ticket),
838 GNUNET_JSON_spec_end ()
841 if (0 >= handle->rest_handle->data_size)
843 GNUNET_SCHEDULER_add_now (&do_error, handle);
847 term_data[handle->rest_handle->data_size] = '\0';
848 GNUNET_memcpy (term_data,
849 handle->rest_handle->data,
850 handle->rest_handle->data_size);
851 data_json = json_loads (term_data,
854 if (NULL == data_json)
856 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
857 "Unable to parse JSON Object from %s\n",
859 GNUNET_SCHEDULER_add_now (&do_error, handle);
862 if (GNUNET_OK != GNUNET_JSON_parse (data_json,
866 handle->emsg = GNUNET_strdup ("Not a ticket!\n");
867 GNUNET_SCHEDULER_add_now (&do_error, handle);
868 GNUNET_JSON_parse_free(tktspec);
869 json_decref (data_json);
872 for (ego_entry = handle->ego_head;
874 ego_entry = ego_entry->next)
876 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
878 if (0 == memcmp (&ticket->audience,
880 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
883 if (NULL == ego_entry)
885 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
886 "Identity unknown\n");
887 GNUNET_JSON_parse_free (tktspec);
890 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
891 handle->resp_object = json_object ();
892 handle->idp = GNUNET_RECLAIM_connect (cfg);
893 handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
898 GNUNET_JSON_parse_free (tktspec);
904 * Respond to OPTIONS request
906 * @param con_handle the connection handle
908 * @param cls the RequestHandle
911 options_cont (struct GNUNET_REST_RequestHandle *con_handle,
915 struct MHD_Response *resp;
916 struct RequestHandle *handle = cls;
918 //For now, independent of path return all options
919 resp = GNUNET_REST_create_response (NULL);
920 MHD_add_response_header (resp,
921 "Access-Control-Allow-Methods",
923 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
924 cleanup_handle (handle);
929 * Handle rest request
931 * @param handle the request handle
934 init_cont (struct RequestHandle *handle)
936 struct GNUNET_REST_RequestHandlerError err;
937 static const struct GNUNET_REST_RequestHandler handlers[] = {
938 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont},
939 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont},
940 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont},
941 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont},
942 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont},
943 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM,
945 GNUNET_REST_HANDLER_END
948 if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle,
953 handle->response_code = err.error_code;
954 GNUNET_SCHEDULER_add_now (&do_error, handle);
959 * If listing is enabled, prints information about the egos.
961 * This function is initially called for all egos and then again
962 * whenever a ego's identifier changes or if it is deleted. At the
963 * end of the initial pass over all egos, the function is once called
964 * with 'NULL' for 'ego'. That does NOT mean that the callback won't
965 * be invoked in the future or that there was an error.
967 * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get',
968 * this function is only called ONCE, and 'NULL' being passed in
969 * 'ego' does indicate an error (i.e. name is taken or no default
970 * value is known). If 'ego' is non-NULL and if '*ctx'
971 * is set in those callbacks, the value WILL be passed to a subsequent
972 * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
973 * that one was not NULL).
975 * When an identity is renamed, this function is called with the
976 * (known) ego but the NEW identifier.
978 * When an identity is deleted, this function is called with the
979 * (known) ego and "NULL" for the 'identifier'. In this case,
980 * the 'ego' is henceforth invalid (and the 'ctx' should also be
984 * @param ego ego handle
985 * @param ctx context for application to store data for this ego
986 * (during the lifetime of this process, initially NULL)
987 * @param identifier identifier assigned by the user for this ego,
988 * NULL if the user just deleted the ego and it
989 * must thus no longer be used
993 struct GNUNET_IDENTITY_Ego *ego,
995 const char *identifier)
997 struct RequestHandle *handle = cls;
998 struct EgoEntry *ego_entry;
999 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1001 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
1003 handle->state = ID_REST_STATE_POST_INIT;
1007 if (ID_REST_STATE_INIT == handle->state) {
1008 ego_entry = GNUNET_new (struct EgoEntry);
1009 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1010 ego_entry->keystring =
1011 GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1012 ego_entry->ego = ego;
1013 ego_entry->identifier = GNUNET_strdup (identifier);
1014 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry);
1020 rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
1021 GNUNET_REST_ResultProcessor proc,
1024 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1025 handle->response_code = 0;
1026 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1027 handle->proc_cls = proc_cls;
1028 handle->proc = proc;
1029 handle->state = ID_REST_STATE_INIT;
1030 handle->rest_handle = rest_handle;
1032 handle->url = GNUNET_strdup (rest_handle->url);
1033 if (handle->url[strlen (handle->url)-1] == '/')
1034 handle->url[strlen (handle->url)-1] = '\0';
1035 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1037 handle->identity_handle = GNUNET_IDENTITY_connect (cfg,
1040 handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg);
1041 handle->timeout_task =
1042 GNUNET_SCHEDULER_add_delayed (handle->timeout,
1045 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1050 * Entry point for the plugin.
1052 * @param cls Config info
1053 * @return NULL on error, otherwise the plugin context
1056 libgnunet_plugin_rest_reclaim_init (void *cls)
1058 static struct Plugin plugin;
1059 struct GNUNET_REST_Plugin *api;
1062 if (NULL != plugin.cfg)
1063 return NULL; /* can only initialize once! */
1064 memset (&plugin, 0, sizeof (struct Plugin));
1066 api = GNUNET_new (struct GNUNET_REST_Plugin);
1068 api->name = GNUNET_REST_API_NS_RECLAIM;
1069 api->process_request = &rest_identity_process_request;
1070 GNUNET_asprintf (&allow_methods,
1071 "%s, %s, %s, %s, %s",
1072 MHD_HTTP_METHOD_GET,
1073 MHD_HTTP_METHOD_POST,
1074 MHD_HTTP_METHOD_PUT,
1075 MHD_HTTP_METHOD_DELETE,
1076 MHD_HTTP_METHOD_OPTIONS);
1078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1079 _("Identity Provider REST API initialized\n"));
1085 * Exit point from the plugin.
1087 * @param cls the plugin context (as returned by "init")
1088 * @return always NULL
1091 libgnunet_plugin_rest_reclaim_done (void *cls)
1093 struct GNUNET_REST_Plugin *api = cls;
1094 struct Plugin *plugin = api->cls;
1097 GNUNET_free_non_null (allow_methods);
1099 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1100 "Identity Provider REST plugin is finished\n");
1104 /* end of plugin_rest_reclaim.c */