GNUnet  0.11.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 
251  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
252  if (NULL != handle->resp_object)
253  json_decref (handle->resp_object);
254  if (NULL != handle->timeout_task)
256  if (NULL != handle->identity_handle)
258  if (NULL != handle->attr_it)
260  if (NULL != handle->ticket_it)
262  if (NULL != handle->idp)
263  GNUNET_RECLAIM_disconnect (handle->idp);
264  if (NULL != handle->url)
265  GNUNET_free (handle->url);
266  if (NULL != handle->emsg)
267  GNUNET_free (handle->emsg);
268  if (NULL != handle->attr_list)
269  {
270  for (claim_entry = handle->attr_list->list_head; NULL != claim_entry;)
271  {
272  claim_tmp = claim_entry;
273  claim_entry = claim_entry->next;
274  GNUNET_free (claim_tmp->claim);
275  GNUNET_free (claim_tmp);
276  }
277  GNUNET_free (handle->attr_list);
278  }
279  for (ego_entry = handle->ego_head; NULL != ego_entry;)
280  {
281  ego_tmp = ego_entry;
282  ego_entry = ego_entry->next;
283  GNUNET_free (ego_tmp->identifier);
284  GNUNET_free (ego_tmp->keystring);
285  GNUNET_free (ego_tmp);
286  }
287  GNUNET_free (handle);
288 }
289 
290 
291 static void
293 {
294  cleanup_handle (cls);
295 }
296 
297 
303 static void
304 do_error (void *cls)
305 {
306  struct RequestHandle *handle = cls;
307  struct MHD_Response *resp;
308  char *json_error;
309 
310  GNUNET_asprintf (&json_error, "{ \"error\" : \"%s\" }", handle->emsg);
311  if (0 == handle->response_code)
312  {
313  handle->response_code = MHD_HTTP_BAD_REQUEST;
314  }
315  resp = GNUNET_REST_create_response (json_error);
316  MHD_add_response_header (resp, "Content-Type", "application/json");
317  handle->proc (handle->proc_cls, resp, handle->response_code);
319  GNUNET_free (json_error);
320 }
321 
322 
328 static void
329 do_timeout (void *cls)
330 {
331  struct RequestHandle *handle = cls;
332 
333  handle->timeout_task = NULL;
334  do_error (handle);
335 }
336 
337 
338 static void
339 collect_error_cb (void *cls)
340 {
341  struct RequestHandle *handle = cls;
342 
343  do_error (handle);
344 }
345 
346 
347 static void
348 finished_cont (void *cls, int32_t success, const char *emsg)
349 {
350  struct RequestHandle *handle = cls;
351  struct MHD_Response *resp;
352 
353  resp = GNUNET_REST_create_response (emsg);
354  if (GNUNET_OK != success)
355  {
357  return;
358  }
359  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
361 }
362 
363 
369 static void
370 return_response (void *cls)
371 {
372  char *result_str;
373  struct RequestHandle *handle = cls;
374  struct MHD_Response *resp;
375 
376  result_str = json_dumps (handle->resp_object, 0);
377  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
378  resp = GNUNET_REST_create_response (result_str);
379  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
380  GNUNET_free (result_str);
381  cleanup_handle (handle);
382 }
383 
384 
385 static void
387 {
388  struct RequestHandle *handle = cls;
389 
390  // Done
391  handle->attr_it = NULL;
392  handle->ticket_it = NULL;
394 }
395 
396 
401 static void
402 ticket_collect (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
403 {
404  json_t *json_resource;
405  struct RequestHandle *handle = cls;
406  json_t *value;
407  char *tmp;
408 
409  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding ticket\n");
410  tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof(uint64_t));
411  json_resource = json_object ();
412  GNUNET_free (tmp);
413  json_array_append (handle->resp_object, json_resource);
414 
415  tmp =
417  sizeof(struct
419  value = json_string (tmp);
420  json_object_set_new (json_resource, "issuer", value);
421  GNUNET_free (tmp);
422  tmp =
424  sizeof(struct
426  value = json_string (tmp);
427  json_object_set_new (json_resource, "audience", value);
428  GNUNET_free (tmp);
429  tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof(uint64_t));
430  value = json_string (tmp);
431  json_object_set_new (json_resource, "rnd", value);
432  GNUNET_free (tmp);
434 }
435 
436 
444 static void
446  const char *url,
447  void *cls)
448 {
449  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
450  struct RequestHandle *handle = cls;
451  struct EgoEntry *ego_entry;
452  char *identity;
453 
455  "Getting tickets for %s.\n",
456  handle->url);
457  if (strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >= strlen (handle->url))
458  {
459  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
461  return;
462  }
463  identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
464 
465  for (ego_entry = handle->ego_head; NULL != ego_entry;
466  ego_entry = ego_entry->next)
467  if (0 == strcmp (identity, ego_entry->identifier))
468  break;
469  handle->resp_object = json_array ();
470 
471  if (NULL == ego_entry)
472  {
473  // Done
474  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
476  return;
477  }
478  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
479  handle->idp = GNUNET_RECLAIM_connect (cfg);
480  handle->ticket_it =
482  priv_key,
484  handle,
486  handle,
488  handle);
489 }
490 
491 
492 static void
494  const char *url,
495  void *cls)
496 {
497  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
498  const char *identity;
499  struct RequestHandle *handle = cls;
500  struct EgoEntry *ego_entry;
501  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute;
502  struct GNUNET_TIME_Relative exp;
503  char term_data[handle->rest_handle->data_size + 1];
504  json_t *data_json;
505  json_error_t err;
506  struct GNUNET_JSON_Specification attrspec[] =
508 
510  "Adding an attribute for %s.\n",
511  handle->url);
512  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
513  {
514  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
516  return;
517  }
518  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
519 
520  for (ego_entry = handle->ego_head; NULL != ego_entry;
521  ego_entry = ego_entry->next)
522  if (0 == strcmp (identity, ego_entry->identifier))
523  break;
524 
525  if (NULL == ego_entry)
526  {
527  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
528  return;
529  }
530  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
531 
532  if (0 >= handle->rest_handle->data_size)
533  {
535  return;
536  }
537 
538  term_data[handle->rest_handle->data_size] = '\0';
539  GNUNET_memcpy (term_data,
540  handle->rest_handle->data,
541  handle->rest_handle->data_size);
542  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
544  GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
545  json_decref (data_json);
546  if (NULL == attribute)
547  {
549  "Unable to parse attribute from %s\n",
550  term_data);
552  return;
553  }
557  if (0 == attribute->id)
558  attribute->id =
560  handle->idp = GNUNET_RECLAIM_connect (cfg);
562  handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
563  identity_priv,
564  attribute,
565  &exp,
566  &finished_cont,
567  handle);
568  GNUNET_JSON_parse_free (attrspec);
569 }
570 
571 
576 static void
579  const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
580 {
581  struct RequestHandle *handle = cls;
582  json_t *attr_obj;
583  const char *type;
584  char *tmp_value;
585  char *id_str;
586 
587  if ((NULL == attr->name) || (NULL == attr->data))
588  {
590  return;
591  }
592 
593  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name);
594 
596  attr->data,
597  attr->data_size);
598 
599  attr_obj = json_object ();
600  json_object_set_new (attr_obj, "value", json_string (tmp_value));
601  json_object_set_new (attr_obj, "name", json_string (attr->name));
603  json_object_set_new (attr_obj, "type", json_string (type));
604  id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t));
605  json_object_set_new (attr_obj, "id", json_string (id_str));
606  json_array_append (handle->resp_object, attr_obj);
607  json_decref (attr_obj);
608  GNUNET_free (tmp_value);
610 }
611 
612 
620 static void
622  const char *url,
623  void *cls)
624 {
625  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
626  struct RequestHandle *handle = cls;
627  struct EgoEntry *ego_entry;
628  char *identity;
629 
631  "Getting attributes for %s.\n",
632  handle->url);
633  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
634  {
635  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
637  return;
638  }
639  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
640 
641  for (ego_entry = handle->ego_head; NULL != ego_entry;
642  ego_entry = ego_entry->next)
643  if (0 == strcmp (identity, ego_entry->identifier))
644  break;
645  handle->resp_object = json_array ();
646 
647 
648  if (NULL == ego_entry)
649  {
650  // Done
651  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
653  return;
654  }
655  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
656  handle->idp = GNUNET_RECLAIM_connect (cfg);
658  priv_key,
660  handle,
661  &attr_collect,
662  handle,
664  handle);
665 }
666 
667 
668 static void
669 delete_finished_cb (void *cls, int32_t success, const char *emsg)
670 {
671  struct RequestHandle *handle = cls;
672  struct MHD_Response *resp;
673 
674  resp = GNUNET_REST_create_response (emsg);
675  if (GNUNET_OK != success)
676  {
678  return;
679  }
680  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
682 }
683 
684 
692 static void
694  const char *url,
695  void *cls)
696 {
697  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
698  struct RequestHandle *handle = cls;
699  struct GNUNET_RECLAIM_ATTRIBUTE_Claim attr;
700  struct EgoEntry *ego_entry;
701  char *identity_id_str;
702  char *identity;
703  char *id;
704 
705  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attributes.\n");
706  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
707  {
708  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
710  return;
711  }
712  identity_id_str =
713  strdup (handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1);
714  identity = strtok (identity_id_str, "/");
715  id = strtok (NULL, "/");
716  if ((NULL == identity) || (NULL == id))
717  {
718  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
719  GNUNET_free (identity_id_str);
721  return;
722  }
723 
724  for (ego_entry = handle->ego_head; NULL != ego_entry;
725  ego_entry = ego_entry->next)
726  if (0 == strcmp (identity, ego_entry->identifier))
727  break;
728  handle->resp_object = json_array ();
729  if (NULL == ego_entry)
730  {
731  // Done
732  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
733  GNUNET_free (identity_id_str);
735  return;
736  }
737  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
738  handle->idp = GNUNET_RECLAIM_connect (cfg);
739  memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_Claim));
740  GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(uint64_t));
741  attr.name = "";
742  handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp,
743  priv_key,
744  &attr,
746  handle);
747  GNUNET_free (identity_id_str);
748 }
749 
750 
751 static void
753  const char *url,
754  void *cls)
755 {
756  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
757  struct RequestHandle *handle = cls;
758  struct EgoEntry *ego_entry;
759  struct GNUNET_RECLAIM_Ticket *ticket = NULL;
760  struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
761  char term_data[handle->rest_handle->data_size + 1];
762  json_t *data_json;
763  json_error_t err;
764  struct GNUNET_JSON_Specification tktspec[] =
766 
767  if (0 >= handle->rest_handle->data_size)
768  {
770  return;
771  }
772 
773  term_data[handle->rest_handle->data_size] = '\0';
774  GNUNET_memcpy (term_data,
775  handle->rest_handle->data,
776  handle->rest_handle->data_size);
777  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
778  if ((NULL == data_json) ||
779  (GNUNET_OK != GNUNET_JSON_parse (data_json, tktspec, NULL, NULL)))
780  {
781  handle->emsg = GNUNET_strdup ("Not a ticket!\n");
783  GNUNET_JSON_parse_free (tktspec);
784  if (NULL != data_json)
785  json_decref (data_json);
786  return;
787  }
788  json_decref (data_json);
789  if (NULL == ticket)
790  {
792  "Unable to parse ticket from %s\n",
793  term_data);
795  return;
796  }
797 
798  for (ego_entry = handle->ego_head; NULL != ego_entry;
799  ego_entry = ego_entry->next)
800  {
801  GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk);
802  if (0 == memcmp (&ticket->identity,
803  &tmp_pk,
804  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
805  break;
806  }
807  if (NULL == ego_entry)
808  {
809  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown\n");
810  GNUNET_JSON_parse_free (tktspec);
811  return;
812  }
813  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
814 
815  handle->idp = GNUNET_RECLAIM_connect (cfg);
816  handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp,
817  identity_priv,
818  ticket,
819  &finished_cont,
820  handle);
821  GNUNET_JSON_parse_free (tktspec);
822 }
823 
824 
825 static void
828  const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
829 {
830  struct RequestHandle *handle = cls;
831  char *val_str;
832  json_t *value;
833 
834  if (NULL == identity)
835  {
837  return;
838  }
839 
840  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name);
842  attr->data,
843  attr->data_size);
844  if (NULL == val_str)
845  {
847  "Failed to parse value for: %s\n",
848  attr->name);
849  return;
850  }
851  value = json_string (val_str);
852  json_object_set_new (handle->resp_object, attr->name, value);
853  json_decref (value);
854  GNUNET_free (val_str);
855 }
856 
857 
858 static void
860  const char *url,
861  void *cls)
862 {
863  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
864  struct RequestHandle *handle = cls;
865  struct EgoEntry *ego_entry;
867  struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
868  char term_data[handle->rest_handle->data_size + 1];
869  json_t *data_json;
870  json_error_t err;
871  struct GNUNET_JSON_Specification tktspec[] =
873 
874  if (0 >= handle->rest_handle->data_size)
875  {
877  return;
878  }
879 
880  term_data[handle->rest_handle->data_size] = '\0';
881  GNUNET_memcpy (term_data,
882  handle->rest_handle->data,
883  handle->rest_handle->data_size);
884  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
885  if (NULL == data_json)
886  {
888  "Unable to parse JSON Object from %s\n",
889  term_data);
891  return;
892  }
893  if (GNUNET_OK != GNUNET_JSON_parse (data_json, tktspec, NULL, NULL))
894  {
895  handle->emsg = GNUNET_strdup ("Not a ticket!\n");
897  GNUNET_JSON_parse_free (tktspec);
898  json_decref (data_json);
899  return;
900  }
901  for (ego_entry = handle->ego_head; NULL != ego_entry;
902  ego_entry = ego_entry->next)
903  {
904  GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk);
905  if (0 == memcmp (&ticket->audience,
906  &tmp_pk,
907  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
908  break;
909  }
910  if (NULL == ego_entry)
911  {
912  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown\n");
913  GNUNET_JSON_parse_free (tktspec);
914  return;
915  }
916  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
917  handle->resp_object = json_object ();
918  handle->idp = GNUNET_RECLAIM_connect (cfg);
919  handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
920  identity_priv,
921  ticket,
922  &consume_cont,
923  handle);
924  GNUNET_JSON_parse_free (tktspec);
925 }
926 
927 
935 static void
937  const char *url,
938  void *cls)
939 {
940  struct MHD_Response *resp;
941  struct RequestHandle *handle = cls;
942 
943  // For now, independent of path return all options
944  resp = GNUNET_REST_create_response (NULL);
945  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
946  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
947  cleanup_handle (handle);
948  return;
949 }
950 
951 
957 static void
959 {
961  static const struct GNUNET_REST_RequestHandler handlers[] =
962  { { MHD_HTTP_METHOD_GET,
965  { MHD_HTTP_METHOD_POST,
968  { MHD_HTTP_METHOD_DELETE,
971  { MHD_HTTP_METHOD_GET,
974  { MHD_HTTP_METHOD_POST,
977  { MHD_HTTP_METHOD_POST,
980  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont },
982 
983  if (GNUNET_NO ==
984  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
985  {
986  handle->response_code = err.error_code;
988  }
989 }
990 
991 
1025 static void
1026 list_ego (void *cls,
1027  struct GNUNET_IDENTITY_Ego *ego,
1028  void **ctx,
1029  const char *identifier)
1030 {
1031  struct RequestHandle *handle = cls;
1032  struct EgoEntry *ego_entry;
1033  struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1034 
1035  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
1036  {
1037  handle->state = ID_REST_STATE_POST_INIT;
1038  init_cont (handle);
1039  return;
1040  }
1041  if (ID_REST_STATE_INIT == handle->state)
1042  {
1043  ego_entry = GNUNET_new (struct EgoEntry);
1046  ego_entry->ego = ego;
1047  ego_entry->identifier = GNUNET_strdup (identifier);
1049  handle->ego_tail,
1050  ego_entry);
1051  }
1052 }
1053 
1054 
1055 static void
1058  void *proc_cls)
1059 {
1060  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1061 
1062  handle->response_code = 0;
1064  handle->proc_cls = proc_cls;
1065  handle->proc = proc;
1066  handle->state = ID_REST_STATE_INIT;
1067  handle->rest_handle = rest_handle;
1068 
1069  handle->url = GNUNET_strdup (rest_handle->url);
1070  if (handle->url[strlen (handle->url) - 1] == '/')
1071  handle->url[strlen (handle->url) - 1] = '\0';
1072  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1073  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle);
1074  handle->timeout_task =
1075  GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
1076  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1077 }
1078 
1079 
1086 void *
1088 {
1089  static struct Plugin plugin;
1090  struct GNUNET_REST_Plugin *api;
1091 
1092  cfg = cls;
1093  if (NULL != plugin.cfg)
1094  return NULL; /* can only initialize once! */
1095  memset (&plugin, 0, sizeof(struct Plugin));
1096  plugin.cfg = cfg;
1097  api = GNUNET_new (struct GNUNET_REST_Plugin);
1098  api->cls = &plugin;
1102  "%s, %s, %s, %s, %s",
1103  MHD_HTTP_METHOD_GET,
1104  MHD_HTTP_METHOD_POST,
1105  MHD_HTTP_METHOD_PUT,
1106  MHD_HTTP_METHOD_DELETE,
1107  MHD_HTTP_METHOD_OPTIONS);
1108 
1110  _ ("Identity Provider REST API initialized\n"));
1111  return api;
1112 }
1113 
1114 
1121 void *
1123 {
1124  struct GNUNET_REST_Plugin *api = cls;
1125  struct Plugin *plugin = api->cls;
1126 
1127  plugin->cfg = NULL;
1128 
1130  GNUNET_free (api);
1132  "Identity Provider REST plugin is finished\n");
1133  return NULL;
1134 }
1135 
1136 
1137 /* 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:527
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:235
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:954
#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:850
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:1145
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:100
#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:555
void GNUNET_RECLAIM_disconnect(struct GNUNET_RECLAIM_Handle *h)
Disconnect from identity provider service.
Definition: reclaim_api.c:819
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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:1189
static void init_cont(struct RequestHandle *handle)
Handle rest request.
#define GNUNET_NO
Definition: gnunet_common.h:78
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:1209
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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:1000
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:181
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 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:1253
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:1240
Handle for a attribute iterator operation.
Definition: reclaim_api.c:167
static char * allow_methods
HTTP methods allows for this plugin.
enum State state
current state of profiling
json_t * resp_object
Response object.
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:897
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:95
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:1280
char * name
Plugin name.
struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no 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:837
#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:77
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
int response_code
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 char * plugin
Solver plugin name as string.
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:332
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:124
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:568
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:133
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:1021
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:57
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:104
#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:1101
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:920
static struct Ego * ego_tail
Tail of DLL of all egos.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
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:952
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:254
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
High-quality operations are desired.
char * url
The url.