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/>.
19 * @author Martin Schanzenbach
20 * @author Philippe Buschmann
21 * @file reclaim/plugin_rest_reclaim.c
22 * @brief GNUnet reclaim REST plugin
27 #include "gnunet_rest_plugin.h"
28 #include "gnunet_identity_service.h"
29 #include "gnunet_gns_service.h"
30 #include "gnunet_gnsrecord_lib.h"
31 #include "gnunet_namestore_service.h"
32 #include "gnunet_rest_lib.h"
33 #include "gnunet_jsonapi_lib.h"
34 #include "gnunet_jsonapi_util.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 handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
596 GNUNET_JSON_parse_free (attrspec);
602 * Collect all attributes for an ego
606 attr_collect (void *cls,
607 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
608 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
610 struct RequestHandle *handle = cls;
615 if ((NULL == attr->name) || (NULL == attr->data))
617 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
621 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n",
624 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
628 attr_obj = json_object ();
629 json_object_set_new (attr_obj,
631 json_string (tmp_value));
632 json_object_set_new (attr_obj,
634 json_string (attr->name));
635 type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
636 json_object_set_new (attr_obj,
639 json_array_append (handle->resp_object,
641 json_decref (attr_obj);
642 GNUNET_free(tmp_value);
643 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
649 * List attributes for identity request
651 * @param con_handle the connection handle
653 * @param cls the RequestHandle
656 list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
660 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
661 struct RequestHandle *handle = cls;
662 struct EgoEntry *ego_entry;
665 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting attributes for %s.\n",
667 if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >=
668 strlen (handle->url))
670 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
671 GNUNET_SCHEDULER_add_now (&do_error, handle);
674 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
676 for (ego_entry = handle->ego_head;
678 ego_entry = ego_entry->next)
679 if (0 == strcmp (identity, ego_entry->identifier))
681 handle->resp_object = json_array ();
684 if (NULL == ego_entry)
687 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n",
689 GNUNET_SCHEDULER_add_now (&return_response, handle);
692 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
693 handle->idp = GNUNET_RECLAIM_connect (cfg);
694 handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
700 &collect_finished_cb,
706 revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
710 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
711 struct RequestHandle *handle = cls;
712 struct EgoEntry *ego_entry;
713 struct GNUNET_RECLAIM_Ticket *ticket;
714 struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
715 char term_data[handle->rest_handle->data_size+1];
718 struct GNUNET_JSON_Specification tktspec[] = {
719 GNUNET_RECLAIM_JSON_spec_ticket (&ticket),
720 GNUNET_JSON_spec_end()
723 if (0 >= handle->rest_handle->data_size)
725 GNUNET_SCHEDULER_add_now (&do_error, handle);
729 term_data[handle->rest_handle->data_size] = '\0';
730 GNUNET_memcpy (term_data,
731 handle->rest_handle->data,
732 handle->rest_handle->data_size);
733 data_json = json_loads (term_data,
736 GNUNET_assert (GNUNET_OK ==
737 GNUNET_JSON_parse (data_json, tktspec,
739 json_decref (data_json);
742 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
743 "Unable to parse ticket from %s\n",
745 GNUNET_SCHEDULER_add_now (&do_error, handle);
748 if (GNUNET_OK != GNUNET_JSON_parse (data_json,
752 handle->emsg = GNUNET_strdup ("Not a ticket!\n");
753 GNUNET_SCHEDULER_add_now (&do_error, handle);
754 GNUNET_JSON_parse_free (tktspec);
755 json_decref (data_json);
759 for (ego_entry = handle->ego_head;
761 ego_entry = ego_entry->next)
763 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
765 if (0 == memcmp (&ticket->identity,
767 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
770 if (NULL == ego_entry)
772 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
773 "Identity unknown\n");
774 GNUNET_JSON_parse_free (tktspec);
777 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
779 handle->idp = GNUNET_RECLAIM_connect (cfg);
780 handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp,
785 GNUNET_JSON_parse_free (tktspec);
789 consume_cont (void *cls,
790 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
791 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
793 struct RequestHandle *handle = cls;
797 if (NULL == identity)
799 GNUNET_SCHEDULER_add_now (&return_response, handle);
803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n",
805 val_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
810 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to parse value for: %s\n",
814 value = json_string(val_str);
815 json_object_set_new (handle->resp_object,
819 GNUNET_free (val_str);
823 consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
827 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
828 struct RequestHandle *handle = cls;
829 struct EgoEntry *ego_entry;
830 struct GNUNET_RECLAIM_Ticket *ticket;
831 struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
832 char term_data[handle->rest_handle->data_size+1];
835 struct GNUNET_JSON_Specification tktspec[] = {
836 GNUNET_RECLAIM_JSON_spec_ticket (&ticket),
837 GNUNET_JSON_spec_end ()
840 if (0 >= handle->rest_handle->data_size)
842 GNUNET_SCHEDULER_add_now (&do_error, handle);
846 term_data[handle->rest_handle->data_size] = '\0';
847 GNUNET_memcpy (term_data,
848 handle->rest_handle->data,
849 handle->rest_handle->data_size);
850 data_json = json_loads (term_data,
853 if (NULL == data_json)
855 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
856 "Unable to parse JSON Object from %s\n",
858 GNUNET_SCHEDULER_add_now (&do_error, handle);
861 if (GNUNET_OK != GNUNET_JSON_parse (data_json,
865 handle->emsg = GNUNET_strdup ("Not a ticket!\n");
866 GNUNET_SCHEDULER_add_now (&do_error, handle);
867 GNUNET_JSON_parse_free(tktspec);
868 json_decref (data_json);
871 for (ego_entry = handle->ego_head;
873 ego_entry = ego_entry->next)
875 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
877 if (0 == memcmp (&ticket->audience,
879 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
882 if (NULL == ego_entry)
884 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
885 "Identity unknown\n");
886 GNUNET_JSON_parse_free (tktspec);
889 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
890 handle->resp_object = json_object ();
891 handle->idp = GNUNET_RECLAIM_connect (cfg);
892 handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
897 GNUNET_JSON_parse_free (tktspec);
903 * Respond to OPTIONS request
905 * @param con_handle the connection handle
907 * @param cls the RequestHandle
910 options_cont (struct GNUNET_REST_RequestHandle *con_handle,
914 struct MHD_Response *resp;
915 struct RequestHandle *handle = cls;
917 //For now, independent of path return all options
918 resp = GNUNET_REST_create_response (NULL);
919 MHD_add_response_header (resp,
920 "Access-Control-Allow-Methods",
922 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
923 cleanup_handle (handle);
928 * Handle rest request
930 * @param handle the request handle
933 init_cont (struct RequestHandle *handle)
935 struct GNUNET_REST_RequestHandlerError err;
936 static const struct GNUNET_REST_RequestHandler handlers[] = {
937 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont},
938 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont},
939 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont},
940 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont},
941 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont},
942 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM,
944 GNUNET_REST_HANDLER_END
947 if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle,
952 handle->response_code = err.error_code;
953 GNUNET_SCHEDULER_add_now (&do_error, handle);
958 * If listing is enabled, prints information about the egos.
960 * This function is initially called for all egos and then again
961 * whenever a ego's identifier changes or if it is deleted. At the
962 * end of the initial pass over all egos, the function is once called
963 * with 'NULL' for 'ego'. That does NOT mean that the callback won't
964 * be invoked in the future or that there was an error.
966 * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get',
967 * this function is only called ONCE, and 'NULL' being passed in
968 * 'ego' does indicate an error (i.e. name is taken or no default
969 * value is known). If 'ego' is non-NULL and if '*ctx'
970 * is set in those callbacks, the value WILL be passed to a subsequent
971 * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
972 * that one was not NULL).
974 * When an identity is renamed, this function is called with the
975 * (known) ego but the NEW identifier.
977 * When an identity is deleted, this function is called with the
978 * (known) ego and "NULL" for the 'identifier'. In this case,
979 * the 'ego' is henceforth invalid (and the 'ctx' should also be
983 * @param ego ego handle
984 * @param ctx context for application to store data for this ego
985 * (during the lifetime of this process, initially NULL)
986 * @param identifier identifier assigned by the user for this ego,
987 * NULL if the user just deleted the ego and it
988 * must thus no longer be used
992 struct GNUNET_IDENTITY_Ego *ego,
994 const char *identifier)
996 struct RequestHandle *handle = cls;
997 struct EgoEntry *ego_entry;
998 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1000 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
1002 handle->state = ID_REST_STATE_POST_INIT;
1006 if (ID_REST_STATE_INIT == handle->state) {
1007 ego_entry = GNUNET_new (struct EgoEntry);
1008 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1009 ego_entry->keystring =
1010 GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1011 ego_entry->ego = ego;
1012 ego_entry->identifier = GNUNET_strdup (identifier);
1013 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry);
1019 rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
1020 GNUNET_REST_ResultProcessor proc,
1023 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1024 handle->response_code = 0;
1025 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1026 handle->proc_cls = proc_cls;
1027 handle->proc = proc;
1028 handle->state = ID_REST_STATE_INIT;
1029 handle->rest_handle = rest_handle;
1031 handle->url = GNUNET_strdup (rest_handle->url);
1032 if (handle->url[strlen (handle->url)-1] == '/')
1033 handle->url[strlen (handle->url)-1] = '\0';
1034 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1036 handle->identity_handle = GNUNET_IDENTITY_connect (cfg,
1039 handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg);
1040 handle->timeout_task =
1041 GNUNET_SCHEDULER_add_delayed (handle->timeout,
1044 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1049 * Entry point for the plugin.
1051 * @param cls Config info
1052 * @return NULL on error, otherwise the plugin context
1055 libgnunet_plugin_rest_reclaim_init (void *cls)
1057 static struct Plugin plugin;
1058 struct GNUNET_REST_Plugin *api;
1061 if (NULL != plugin.cfg)
1062 return NULL; /* can only initialize once! */
1063 memset (&plugin, 0, sizeof (struct Plugin));
1065 api = GNUNET_new (struct GNUNET_REST_Plugin);
1067 api->name = GNUNET_REST_API_NS_RECLAIM;
1068 api->process_request = &rest_identity_process_request;
1069 GNUNET_asprintf (&allow_methods,
1070 "%s, %s, %s, %s, %s",
1071 MHD_HTTP_METHOD_GET,
1072 MHD_HTTP_METHOD_POST,
1073 MHD_HTTP_METHOD_PUT,
1074 MHD_HTTP_METHOD_DELETE,
1075 MHD_HTTP_METHOD_OPTIONS);
1077 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1078 _("Identity Provider REST API initialized\n"));
1084 * Exit point from the plugin.
1086 * @param cls the plugin context (as returned by "init")
1087 * @return always NULL
1090 libgnunet_plugin_rest_reclaim_done (void *cls)
1092 struct GNUNET_REST_Plugin *api = cls;
1093 struct Plugin *plugin = api->cls;
1096 GNUNET_free_non_null (allow_methods);
1098 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1099 "Identity Provider REST plugin is finished\n");
1103 /* end of plugin_rest_reclaim.c */