GNUnet  0.10.x
plugin_rest_reclaim.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012-2015 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  */
27 #include "platform.h"
28 #include "microhttpd.h"
29 #include <inttypes.h>
30 #include <jansson.h>
31 #include "gnunet_gns_service.h"
32 #include "gnunet_gnsrecord_lib.h"
35 #include "gnunet_reclaim_service.h"
36 #include "gnunet_rest_lib.h"
37 #include "gnunet_rest_plugin.h"
38 #include "gnunet_signatures.h"
39 #include "json_reclaim.h"
40 
44 #define GNUNET_REST_API_NS_RECLAIM "/reclaim"
45 
49 #define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes"
50 
54 #define GNUNET_REST_API_NS_IDENTITY_TICKETS "/reclaim/tickets"
55 
59 #define GNUNET_REST_API_NS_IDENTITY_REVOKE "/reclaim/revoke"
60 
64 #define GNUNET_REST_API_NS_IDENTITY_CONSUME "/reclaim/consume"
65 
69 #define ID_REST_STATE_INIT 0
70 
74 #define ID_REST_STATE_POST_INIT 1
75 
80 
84 static char *allow_methods;
85 
89 struct Plugin
90 {
91  const struct GNUNET_CONFIGURATION_Handle *cfg;
92 };
93 
97 struct EgoEntry
98 {
102  struct EgoEntry *next;
103 
107  struct EgoEntry *prev;
108 
112  char *identifier;
113 
117  char *keystring;
118 
122  struct GNUNET_IDENTITY_Ego *ego;
123 };
124 
125 
126 struct RequestHandle
127 {
131  struct EgoEntry *ego_head;
132 
136  struct EgoEntry *ego_tail;
137 
141  struct EgoEntry *ego_entry;
142 
146  struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key;
147 
151  int state;
152 
157 
161  struct GNUNET_REST_RequestHandle *rest_handle;
162 
167 
172 
176  struct GNUNET_RECLAIM_Handle *idp;
177 
181  struct GNUNET_RECLAIM_Operation *idp_op;
182 
186  struct GNUNET_RECLAIM_AttributeIterator *attr_it;
187 
191  struct GNUNET_RECLAIM_TicketIterator *ticket_it;
192 
196  struct GNUNET_RECLAIM_Ticket ticket;
197 
201  struct GNUNET_TIME_Relative timeout;
202 
207 
212 
216  void *proc_cls;
217 
221  char *url;
222 
226  char *emsg;
227 
231  int response_code;
232 
236  json_t *resp_object;
237 };
238 
243 static void
245 {
246  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry;
247  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp;
248  struct EgoEntry *ego_entry;
249  struct EgoEntry *ego_tmp;
250  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
251  if (NULL != handle->resp_object)
252  json_decref (handle->resp_object);
253  if (NULL != handle->timeout_task)
255  if (NULL != handle->identity_handle)
257  if (NULL != handle->attr_it)
259  if (NULL != handle->ticket_it)
261  if (NULL != handle->idp)
262  GNUNET_RECLAIM_disconnect (handle->idp);
263  if (NULL != handle->url)
264  GNUNET_free (handle->url);
265  if (NULL != handle->emsg)
266  GNUNET_free (handle->emsg);
267  if (NULL != handle->attr_list)
268  {
269  for (claim_entry = handle->attr_list->list_head; NULL != claim_entry;)
270  {
271  claim_tmp = claim_entry;
272  claim_entry = claim_entry->next;
273  GNUNET_free (claim_tmp->claim);
274  GNUNET_free (claim_tmp);
275  }
276  GNUNET_free (handle->attr_list);
277  }
278  for (ego_entry = handle->ego_head; NULL != ego_entry;)
279  {
280  ego_tmp = ego_entry;
281  ego_entry = ego_entry->next;
282  GNUNET_free (ego_tmp->identifier);
283  GNUNET_free (ego_tmp->keystring);
284  GNUNET_free (ego_tmp);
285  }
286  GNUNET_free (handle);
287 }
288 
289 static void
291 {
292  cleanup_handle (cls);
293 }
294 
295 
301 static void
302 do_error (void *cls)
303 {
304  struct RequestHandle *handle = cls;
305  struct MHD_Response *resp;
306  char *json_error;
307 
308  GNUNET_asprintf (&json_error, "{ \"error\" : \"%s\" }", handle->emsg);
309  if (0 == handle->response_code)
310  {
311  handle->response_code = MHD_HTTP_BAD_REQUEST;
312  }
313  resp = GNUNET_REST_create_response (json_error);
314  MHD_add_response_header (resp, "Content-Type", "application/json");
315  handle->proc (handle->proc_cls, resp, handle->response_code);
317  GNUNET_free (json_error);
318 }
319 
320 
326 static void
327 do_timeout (void *cls)
328 {
329  struct RequestHandle *handle = cls;
330 
331  handle->timeout_task = NULL;
332  do_error (handle);
333 }
334 
335 
336 static void
337 collect_error_cb (void *cls)
338 {
339  struct RequestHandle *handle = cls;
340 
341  do_error (handle);
342 }
343 
344 static void
345 finished_cont (void *cls, int32_t success, const char *emsg)
346 {
347  struct RequestHandle *handle = cls;
348  struct MHD_Response *resp;
349 
350  resp = GNUNET_REST_create_response (emsg);
351  if (GNUNET_OK != success)
352  {
354  return;
355  }
356  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
358 }
359 
360 
366 static void
367 return_response (void *cls)
368 {
369  char *result_str;
370  struct RequestHandle *handle = cls;
371  struct MHD_Response *resp;
372 
373  result_str = json_dumps (handle->resp_object, 0);
374  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
375  resp = GNUNET_REST_create_response (result_str);
376  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
377  GNUNET_free (result_str);
378  cleanup_handle (handle);
379 }
380 
381 static void
383 {
384  struct RequestHandle *handle = cls;
385  // Done
386  handle->attr_it = NULL;
387  handle->ticket_it = NULL;
389 }
390 
391 
396 static void
397 ticket_collect (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
398 {
399  json_t *json_resource;
400  struct RequestHandle *handle = cls;
401  json_t *value;
402  char *tmp;
403 
404  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding ticket\n");
405  tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof (uint64_t));
406  json_resource = json_object ();
407  GNUNET_free (tmp);
408  json_array_append (handle->resp_object, json_resource);
409 
410  tmp =
412  sizeof (struct
414  value = json_string (tmp);
415  json_object_set_new (json_resource, "issuer", value);
416  GNUNET_free (tmp);
417  tmp =
419  sizeof (struct
421  value = json_string (tmp);
422  json_object_set_new (json_resource, "audience", value);
423  GNUNET_free (tmp);
424  tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof (uint64_t));
425  value = json_string (tmp);
426  json_object_set_new (json_resource, "rnd", value);
427  GNUNET_free (tmp);
429 }
430 
431 
439 static void
441  const char *url,
442  void *cls)
443 {
444  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
445  struct RequestHandle *handle = cls;
446  struct EgoEntry *ego_entry;
447  char *identity;
448 
450  "Getting tickets for %s.\n",
451  handle->url);
452  if (strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >= strlen (handle->url))
453  {
454  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
456  return;
457  }
458  identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
459 
460  for (ego_entry = handle->ego_head; NULL != ego_entry;
461  ego_entry = ego_entry->next)
462  if (0 == strcmp (identity, ego_entry->identifier))
463  break;
464  handle->resp_object = json_array ();
465 
466  if (NULL == ego_entry)
467  {
468  // Done
469  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
471  return;
472  }
473  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
474  handle->idp = GNUNET_RECLAIM_connect (cfg);
475  handle->ticket_it =
477  priv_key,
479  handle,
481  handle,
483  handle);
484 }
485 
486 
487 static void
489  const char *url,
490  void *cls)
491 {
492  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
493  const char *identity;
494  struct RequestHandle *handle = cls;
495  struct EgoEntry *ego_entry;
496  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute;
497  struct GNUNET_TIME_Relative exp;
498  char term_data[handle->rest_handle->data_size + 1];
499  json_t *data_json;
500  json_error_t err;
501  struct GNUNET_JSON_Specification attrspec[] =
503 
505  "Adding an attribute for %s.\n",
506  handle->url);
507  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
508  {
509  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
511  return;
512  }
513  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
514 
515  for (ego_entry = handle->ego_head; NULL != ego_entry;
516  ego_entry = ego_entry->next)
517  if (0 == strcmp (identity, ego_entry->identifier))
518  break;
519 
520  if (NULL == ego_entry)
521  {
522  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
523  return;
524  }
525  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
526 
527  if (0 >= handle->rest_handle->data_size)
528  {
530  return;
531  }
532 
533  term_data[handle->rest_handle->data_size] = '\0';
534  GNUNET_memcpy (term_data,
535  handle->rest_handle->data,
536  handle->rest_handle->data_size);
537  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
539  GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
540  json_decref (data_json);
541  if (NULL == attribute)
542  {
544  "Unable to parse attribute from %s\n",
545  term_data);
547  return;
548  }
552  if (0 == attribute->id)
553  attribute->id =
555  handle->idp = GNUNET_RECLAIM_connect (cfg);
557  handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
558  identity_priv,
559  attribute,
560  &exp,
561  &finished_cont,
562  handle);
563  GNUNET_JSON_parse_free (attrspec);
564 }
565 
566 
571 static void
574  const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
575 {
576  struct RequestHandle *handle = cls;
577  json_t *attr_obj;
578  const char *type;
579  char *tmp_value;
580  char *id_str;
581 
582  if ((NULL == attr->name) || (NULL == attr->data))
583  {
585  return;
586  }
587 
588  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name);
589 
591  attr->data,
592  attr->data_size);
593 
594  attr_obj = json_object ();
595  json_object_set_new (attr_obj, "value", json_string (tmp_value));
596  json_object_set_new (attr_obj, "name", json_string (attr->name));
598  json_object_set_new (attr_obj, "type", json_string (type));
599  id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof (uint64_t));
600  json_object_set_new (attr_obj, "id", json_string (id_str));
601  json_array_append (handle->resp_object, attr_obj);
602  json_decref (attr_obj);
603  GNUNET_free (tmp_value);
605 }
606 
607 
615 static void
617  const char *url,
618  void *cls)
619 {
620  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
621  struct RequestHandle *handle = cls;
622  struct EgoEntry *ego_entry;
623  char *identity;
624 
626  "Getting attributes for %s.\n",
627  handle->url);
628  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
629  {
630  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
632  return;
633  }
634  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
635 
636  for (ego_entry = handle->ego_head; NULL != ego_entry;
637  ego_entry = ego_entry->next)
638  if (0 == strcmp (identity, ego_entry->identifier))
639  break;
640  handle->resp_object = json_array ();
641 
642 
643  if (NULL == ego_entry)
644  {
645  // Done
646  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
648  return;
649  }
650  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
651  handle->idp = GNUNET_RECLAIM_connect (cfg);
653  priv_key,
655  handle,
656  &attr_collect,
657  handle,
659  handle);
660 }
661 
662 
663 static void
664 delete_finished_cb (void *cls, int32_t success, const char *emsg)
665 {
666  struct RequestHandle *handle = cls;
667  struct MHD_Response *resp;
668 
669  resp = GNUNET_REST_create_response (emsg);
670  if (GNUNET_OK != success)
671  {
673  return;
674  }
675  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
677 }
678 
679 
687 static void
689  const char *url,
690  void *cls)
691 {
692  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
693  struct RequestHandle *handle = cls;
694  struct GNUNET_RECLAIM_ATTRIBUTE_Claim attr;
695  struct EgoEntry *ego_entry;
696  char *identity_id_str;
697  char *identity;
698  char *id;
699 
700  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attributes.\n");
701  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
702  {
703  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
705  return;
706  }
707  identity_id_str =
708  strdup (handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1);
709  identity = strtok (identity_id_str, "/");
710  id = strtok (NULL, "/");
711  if ((NULL == identity) || (NULL == id))
712  {
713  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
714  GNUNET_free (identity_id_str);
716  return;
717  }
718 
719  for (ego_entry = handle->ego_head; NULL != ego_entry;
720  ego_entry = ego_entry->next)
721  if (0 == strcmp (identity, ego_entry->identifier))
722  break;
723  handle->resp_object = json_array ();
724  if (NULL == ego_entry)
725  {
726  // Done
727  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
728  GNUNET_free (identity_id_str);
730  return;
731  }
732  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
733  handle->idp = GNUNET_RECLAIM_connect (cfg);
734  memset (&attr, 0, sizeof (struct GNUNET_RECLAIM_ATTRIBUTE_Claim));
735  GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof (uint64_t));
736  attr.name = "";
737  handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp,
738  priv_key,
739  &attr,
741  handle);
742  GNUNET_free (identity_id_str);
743 }
744 
745 
746 static void
748  const char *url,
749  void *cls)
750 {
751  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
752  struct RequestHandle *handle = cls;
753  struct EgoEntry *ego_entry;
754  struct GNUNET_RECLAIM_Ticket *ticket = NULL;
755  struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
756  char term_data[handle->rest_handle->data_size + 1];
757  json_t *data_json;
758  json_error_t err;
759  struct GNUNET_JSON_Specification tktspec[] =
761 
762  if (0 >= handle->rest_handle->data_size)
763  {
765  return;
766  }
767 
768  term_data[handle->rest_handle->data_size] = '\0';
769  GNUNET_memcpy (term_data,
770  handle->rest_handle->data,
771  handle->rest_handle->data_size);
772  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
773  if ((NULL == data_json) ||
774  (GNUNET_OK != GNUNET_JSON_parse (data_json, tktspec, NULL, NULL)))
775  {
776  handle->emsg = GNUNET_strdup ("Not a ticket!\n");
778  GNUNET_JSON_parse_free (tktspec);
779  if (NULL != data_json)
780  json_decref (data_json);
781  return;
782  }
783  json_decref (data_json);
784  if (NULL == ticket)
785  {
787  "Unable to parse ticket from %s\n",
788  term_data);
790  return;
791  }
792 
793  for (ego_entry = handle->ego_head; NULL != ego_entry;
794  ego_entry = ego_entry->next)
795  {
796  GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk);
797  if (0 == memcmp (&ticket->identity,
798  &tmp_pk,
799  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
800  break;
801  }
802  if (NULL == ego_entry)
803  {
804  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown\n");
805  GNUNET_JSON_parse_free (tktspec);
806  return;
807  }
808  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
809 
810  handle->idp = GNUNET_RECLAIM_connect (cfg);
811  handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp,
812  identity_priv,
813  ticket,
814  &finished_cont,
815  handle);
816  GNUNET_JSON_parse_free (tktspec);
817 }
818 
819 static void
822  const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
823 {
824  struct RequestHandle *handle = cls;
825  char *val_str;
826  json_t *value;
827 
828  if (NULL == identity)
829  {
831  return;
832  }
833 
834  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name);
836  attr->data,
837  attr->data_size);
838  if (NULL == val_str)
839  {
841  "Failed to parse value for: %s\n",
842  attr->name);
843  return;
844  }
845  value = json_string (val_str);
846  json_object_set_new (handle->resp_object, attr->name, value);
847  json_decref (value);
848  GNUNET_free (val_str);
849 }
850 
851 static void
853  const char *url,
854  void *cls)
855 {
856  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
857  struct RequestHandle *handle = cls;
858  struct EgoEntry *ego_entry;
860  struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
861  char term_data[handle->rest_handle->data_size + 1];
862  json_t *data_json;
863  json_error_t err;
864  struct GNUNET_JSON_Specification tktspec[] =
866 
867  if (0 >= handle->rest_handle->data_size)
868  {
870  return;
871  }
872 
873  term_data[handle->rest_handle->data_size] = '\0';
874  GNUNET_memcpy (term_data,
875  handle->rest_handle->data,
876  handle->rest_handle->data_size);
877  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
878  if (NULL == data_json)
879  {
881  "Unable to parse JSON Object from %s\n",
882  term_data);
884  return;
885  }
886  if (GNUNET_OK != GNUNET_JSON_parse (data_json, tktspec, NULL, NULL))
887  {
888  handle->emsg = GNUNET_strdup ("Not a ticket!\n");
890  GNUNET_JSON_parse_free (tktspec);
891  json_decref (data_json);
892  return;
893  }
894  for (ego_entry = handle->ego_head; NULL != ego_entry;
895  ego_entry = ego_entry->next)
896  {
897  GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk);
898  if (0 == memcmp (&ticket->audience,
899  &tmp_pk,
900  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
901  break;
902  }
903  if (NULL == ego_entry)
904  {
905  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown\n");
906  GNUNET_JSON_parse_free (tktspec);
907  return;
908  }
909  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
910  handle->resp_object = json_object ();
911  handle->idp = GNUNET_RECLAIM_connect (cfg);
912  handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
913  identity_priv,
914  ticket,
915  &consume_cont,
916  handle);
917  GNUNET_JSON_parse_free (tktspec);
918 }
919 
920 
928 static void
930  const char *url,
931  void *cls)
932 {
933  struct MHD_Response *resp;
934  struct RequestHandle *handle = cls;
935 
936  // For now, independent of path return all options
937  resp = GNUNET_REST_create_response (NULL);
938  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
939  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
940  cleanup_handle (handle);
941  return;
942 }
943 
949 static void
951 {
953  static const struct GNUNET_REST_RequestHandler handlers[] =
954  {{MHD_HTTP_METHOD_GET,
957  {MHD_HTTP_METHOD_POST,
960  {MHD_HTTP_METHOD_DELETE,
963  {MHD_HTTP_METHOD_GET,
966  {MHD_HTTP_METHOD_POST,
969  {MHD_HTTP_METHOD_POST,
972  {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont},
974 
975  if (GNUNET_NO ==
976  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
977  {
978  handle->response_code = err.error_code;
980  }
981 }
982 
1016 static void
1017 list_ego (void *cls,
1018  struct GNUNET_IDENTITY_Ego *ego,
1019  void **ctx,
1020  const char *identifier)
1021 {
1022  struct RequestHandle *handle = cls;
1023  struct EgoEntry *ego_entry;
1024  struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1025 
1026  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
1027  {
1028  handle->state = ID_REST_STATE_POST_INIT;
1029  init_cont (handle);
1030  return;
1031  }
1032  if (ID_REST_STATE_INIT == handle->state)
1033  {
1034  ego_entry = GNUNET_new (struct EgoEntry);
1037  ego_entry->ego = ego;
1038  ego_entry->identifier = GNUNET_strdup (identifier);
1040  handle->ego_tail,
1041  ego_entry);
1042  }
1043 }
1044 
1045 static void
1048  void *proc_cls)
1049 {
1050  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1051  handle->response_code = 0;
1053  handle->proc_cls = proc_cls;
1054  handle->proc = proc;
1055  handle->state = ID_REST_STATE_INIT;
1056  handle->rest_handle = rest_handle;
1057 
1058  handle->url = GNUNET_strdup (rest_handle->url);
1059  if (handle->url[strlen (handle->url) - 1] == '/')
1060  handle->url[strlen (handle->url) - 1] = '\0';
1061  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1062  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle);
1063  handle->timeout_task =
1064  GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
1065  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1066 }
1067 
1074 void *
1076 {
1077  static struct Plugin plugin;
1078  struct GNUNET_REST_Plugin *api;
1079 
1080  cfg = cls;
1081  if (NULL != plugin.cfg)
1082  return NULL; /* can only initialize once! */
1083  memset (&plugin, 0, sizeof (struct Plugin));
1084  plugin.cfg = cfg;
1085  api = GNUNET_new (struct GNUNET_REST_Plugin);
1086  api->cls = &plugin;
1090  "%s, %s, %s, %s, %s",
1091  MHD_HTTP_METHOD_GET,
1092  MHD_HTTP_METHOD_POST,
1093  MHD_HTTP_METHOD_PUT,
1094  MHD_HTTP_METHOD_DELETE,
1095  MHD_HTTP_METHOD_OPTIONS);
1096 
1098  _ ("Identity Provider REST API initialized\n"));
1099  return api;
1100 }
1101 
1102 
1109 void *
1111 {
1112  struct GNUNET_REST_Plugin *api = cls;
1113  struct Plugin *plugin = api->cls;
1114  plugin->cfg = NULL;
1115 
1117  GNUNET_free (api);
1119  "Identity Provider REST plugin is finished\n");
1120  return NULL;
1121 }
1122 
1123 /* end of plugin_rest_reclaim.c */
static void list_attribute_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
List attributes for identity request.
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
Definition: identity_api.c:528
void * cls
Closure for parser and cleaner.
const char * name
The name of the attribute.
struct GNUNET_RECLAIM_ATTRIBUTE_Claim * claim
The attribute claim.
char * GNUNET_RECLAIM_ATTRIBUTE_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the &#39;claim&#39; of an attribute to a string.
#define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES
Attribute namespace.
Handle to the service.
Definition: reclaim_api.c:238
The authorization ticket.
void(* GNUNET_REST_ResultProcessor)(void *cls, struct MHD_Response *resp, int status)
Iterator called on obtained result for a REST result.
static void attr_collect(void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
Collect all attributes for an ego.
static void consume_ticket_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
static void cleanup_handle_delayed(void *cls)
struct GNUNET_RECLAIM_AttributeIterator * GNUNET_RECLAIM_get_attributes_start(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_RECLAIM_AttributeResult proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls)
List all attributes for a local identity.
Definition: reclaim_api.c:953
#define GNUNET_TIME_UNIT_HOURS
One hour.
struct EgoEntry * ego_tail
Ego list.
static void list_ego(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
If listing is enabled, prints information about the egos.
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_attribute_store(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, const struct GNUNET_TIME_Relative *exp_interval, GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls)
Store an attribute.
Definition: reclaim_api.c:849
struct GNUNET_RECLAIM_TicketIterator * GNUNET_RECLAIM_ticket_iteration_start(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_RECLAIM_TicketCallback proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls)
Lists all tickets that have been issued to remote identites (relying parties)
Definition: reclaim_api.c:1143
size_t data_size
Number of bytes in data.
void * cls
The closure of the plugin.
size_t data_size
The POST data size.
static void collect_error_cb(void *cls)
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
static void add_attribute_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
GNUNET_REST_ResultProcessor proc
The plugin result processor.
static struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute list.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_JSON_parse_free(struct GNUNET_JSON_Specification *spec)
Frees all elements allocated during a GNUNET_JSON_parse() operation.
Definition: json.c:87
#define GNUNET_REST_API_NS_IDENTITY_CONSUME
Revoke namespace.
static void finished_cont(void *cls, int32_t success, const char *emsg)
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:556
void GNUNET_RECLAIM_disconnect(struct GNUNET_RECLAIM_Handle *h)
Disconnect from identity provider service.
Definition: reclaim_api.c:819
struct returned by the initialization function of the plugin
void GNUNET_RECLAIM_ticket_iteration_next(struct GNUNET_RECLAIM_TicketIterator *it)
Calls the ticket processor specified in GNUNET_RECLAIM_ticket_iteration_start for the next record...
Definition: reclaim_api.c:1187
static void init_cont(struct RequestHandle *handle)
Handle rest request.
#define GNUNET_NO
Definition: gnunet_common.h:81
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
Entry in parser specification for GNUNET_JSON_parse().
void GNUNET_RECLAIM_ticket_iteration_stop(struct GNUNET_RECLAIM_TicketIterator *it)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1207
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
void GNUNET_RECLAIM_get_attributes_next(struct GNUNET_RECLAIM_AttributeIterator *it)
Calls the record processor specified in GNUNET_RECLAIM_get_attributes_start for the next record...
Definition: reclaim_api.c:999
Handle for an operation with the service.
Definition: reclaim_api.c:41
void(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
static void collect_finished_cb(void *cls)
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
static void consume_cont(void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
Handle for an operation with the identity service.
Definition: identity_api.c:39
#define GNUNET_REST_HANDLER_END
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47
The request handle.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
const void * data
Binary value stored as attribute value.
The ego list.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
#define ID_REST_STATE_INIT
State while collecting all egos.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
static void rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
Handle for an ego.
Definition: identity.h:245
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_revoke(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, const struct GNUNET_RECLAIM_Ticket *ticket, GNUNET_RECLAIM_ContinuationWithStatus cb, void *cb_cls)
Revoked an issued ticket.
Definition: reclaim_api.c:1238
Handle for a attribute iterator operation.
Definition: reclaim_api.c:169
static char * allow_methods
HTTP methods allows for this plugin.
enum State state
current state of profiling
json_t * resp_object
Response object.
#define GNUNET_memcpy(dst, src, n)
const char * GNUNET_RECLAIM_ATTRIBUTE_number_to_typename(uint32_t type)
Convert a type number to the corresponding type string.
static char * value
Value of the record to add/remove.
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_attribute_delete(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls)
Delete an attribute.
Definition: reclaim_api.c:896
char * emsg
Error response message.
int GNUNET_JSON_parse(const json_t *root, struct GNUNET_JSON_Specification *spec, const char **error_json_name, unsigned int *error_line)
Navigate and parse data in a JSON tree.
Definition: json.c:45
const char * url
The url as string.
Handle for the service.
Definition: identity_api.c:96
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
char * name
Plugin name.
struct GNUNET_TIME_Relative timeout
Timeout.
struct GNUNET_RECLAIM_TicketIterator * ticket_it
Ticket iterator.
static struct GNUNET_IDENTITY_Handle * identity_handle
Identity handle.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void list_tickets_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
List tickets for identity request.
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:838
#define ID_REST_STATE_POST_INIT
Done collecting egos.
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
int GNUNET_REST_handle_request(struct GNUNET_REST_RequestHandle *conn, const struct GNUNET_REST_RequestHandler *handlers, struct GNUNET_REST_RequestHandlerError *err, void *cls)
Definition: rest.c:76
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
int response_code
HTTP response code.
#define GNUNET_REST_API_NS_RECLAIM
REST root namespace.
int state
The processing state.
static void ticket_collect(void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
Collect all attributes for an ego.
static void delete_attribute_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
List attributes for identity request.
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:334
static void return_response(void *cls)
Return attributes for identity.
const char * data
The POST data.
struct GNUNET_CRYPTO_EcdsaPublicKey identity
The ticket issuer (= the user)
char * keystring
Public key string.
struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
void * libgnunet_plugin_rest_reclaim_done(void *cls)
Exit point from the plugin.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute claim list.
#define GNUNET_REST_API_NS_IDENTITY_REVOKE
Revoke namespace.
uint64_t rnd
The ticket random (NBO)
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static void delete_finished_cb(void *cls, int32_t success, const char *emsg)
static struct GNUNET_SCHEDULER_Task * timeout_task
Task to be run on timeout.
Definition: gnunet-arm.c:119
static struct Ego * ego_head
Head of DLL of all egos.
void GNUNET_IDENTITY_ego_get_public_key(const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:569
static void do_error(void *cls)
Task run on error, sends error message.
char * identifier
Ego Identifier.
struct GNUNET_JSON_Specification GNUNET_RECLAIM_JSON_spec_claim(struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr)
JSON Specification for Reclaim claims.
Definition: json_reclaim.c:130
static void revoke_ticket_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
configuration data
Definition: configuration.c:85
struct EgoEntry * ego_head
Ego list.
Handle for a plugin.
Definition: block.c:37
void GNUNET_RECLAIM_get_attributes_stop(struct GNUNET_RECLAIM_AttributeIterator *it)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1020
struct GNUNET_CRYPTO_EcdsaPublicKey audience
The ticket audience (= relying party)
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
static void do_timeout(void *cls)
Task run on timeout, sends error message.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
Handle for a ticket iterator operation.
Definition: reclaim_api.c:105
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
void * libgnunet_plugin_rest_reclaim_init(void *cls)
Entry point for the plugin.
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_consume(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, const struct GNUNET_RECLAIM_Ticket *ticket, GNUNET_RECLAIM_AttributeResult cb, void *cb_cls)
Consumes an issued ticket.
Definition: reclaim_api.c:1099
struct EgoEntry * prev
DLL.
struct GNUNET_JSON_Specification GNUNET_JSON_spec_end(void)
End of a parser specification.
Definition: json_helper.c:35
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:988
static struct Ego * ego_tail
Tail of DLL of all egos.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
struct GNUNET_RECLAIM_Handle * GNUNET_RECLAIM_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the re:claimID service.
Definition: reclaim_api.c:779
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * next
DLL.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * list_head
List head.
struct EgoEntry * next
DLL.
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:1021
struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
#define GNUNET_REST_API_NS_IDENTITY_TICKETS
Ticket namespace.
struct GNUNET_JSON_Specification GNUNET_RECLAIM_JSON_spec_ticket(struct GNUNET_RECLAIM_Ticket **ticket)
JSON Specification for Reclaim tickets.
Definition: json_reclaim.c:244
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
High-quality operations are desired.
char * url
The url.