GNUnet  0.10.x
plugin_rest_identity.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 "gnunet_rest_plugin.h"
30 #include "gnunet_rest_lib.h"
31 #include "microhttpd.h"
32 #include <jansson.h>
33 
37 #define GNUNET_REST_API_NS_IDENTITY "/identity"
38 
42 #define GNUNET_REST_API_NS_IDENTITY_ALL "/identity/all"
43 
47 #define GNUNET_REST_API_NS_IDENTITY_PUBKEY "/identity/pubkey"
48 
52 #define GNUNET_REST_API_NS_IDENTITY_NAME "/identity/name"
53 
57 #define GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM "/identity/subsystem"
58 
62 #define GNUNET_REST_IDENTITY_PARAM_PUBKEY "pubkey"
63 
67 #define GNUNET_REST_IDENTITY_PARAM_SUBSYSTEM "subsystem"
68 
72 #define GNUNET_REST_IDENTITY_PARAM_NAME "name"
73 
77 #define GNUNET_REST_IDENTITY_PARAM_NEWNAME "newname"
78 
82 #define GNUNET_REST_IDENTITY_ERROR_UNKNOWN "Unknown Error"
83 
87 #define GNUNET_REST_IDENTITY_NOT_FOUND "No identity found"
88 
92 #define GNUNET_REST_IDENTITY_MISSING_NAME "Missing identity name"
93 
97 #define GNUNET_REST_IDENTITY_MISSING_PUBKEY "Missing identity public key"
98 
102 #define GNUNET_REST_ERROR_NO_DATA "No data"
103 
107 #define GNUNET_REST_ERROR_DATA_INVALID "Data invalid"
108 
112 #define ID_REST_STATE_INIT 0
113 
117 #define ID_REST_STATE_POST_INIT 1
118 
123 
127 static char *allow_methods;
128 
132 struct Plugin
133 {
134  const struct GNUNET_CONFIGURATION_Handle *cfg;
135 };
136 
140 struct EgoEntry
141 {
145  struct EgoEntry *next;
146 
150  struct EgoEntry *prev;
151 
155  char *identifier;
156 
160  char *keystring;
161 
166 };
167 
171 struct RequestHandle
172 {
176  const char *data;
177 
181  char *name;
182 
186  size_t data_size;
187 
188 
193 
198 
202  int state;
203 
208 
213 
217  struct GNUNET_REST_RequestHandle *rest_handle;
218 
223 
228 
233 
237  void *proc_cls;
238 
242  char *url;
243 
247  char *emsg;
248 
252  int response_code;
253 };
254 
259 static void
260 cleanup_handle (void *cls)
261 {
262  struct RequestHandle *handle = cls;
263  struct EgoEntry *ego_entry;
264  struct EgoEntry *ego_tmp;
265 
266  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
267  if (NULL != handle->timeout_task)
268  {
270  handle->timeout_task = NULL;
271  }
272 
273  if (NULL != handle->url)
274  GNUNET_free (handle->url);
275  if (NULL != handle->emsg)
276  GNUNET_free (handle->emsg);
277  if (NULL != handle->name)
278  GNUNET_free (handle->name);
279  if (NULL != handle->identity_handle)
281 
282  for (ego_entry = handle->ego_head; NULL != ego_entry;)
283  {
284  ego_tmp = ego_entry;
285  ego_entry = ego_entry->next;
286  GNUNET_free (ego_tmp->identifier);
287  GNUNET_free (ego_tmp->keystring);
288  GNUNET_free (ego_tmp);
289  }
290 
291  GNUNET_free (handle);
292 }
293 
299 static void
300 do_error (void *cls)
301 {
302  struct RequestHandle *handle = cls;
303  struct MHD_Response *resp;
304  json_t *json_error = json_object ();
305  char *response;
306 
307  if (NULL == handle->emsg)
309 
310  json_object_set_new (json_error, "error", json_string (handle->emsg));
311 
312  if (0 == handle->response_code)
313  handle->response_code = MHD_HTTP_OK;
314  response = json_dumps (json_error, 0);
315  resp = GNUNET_REST_create_response (response);
316  handle->proc (handle->proc_cls, resp, handle->response_code);
317  json_decref (json_error);
318  GNUNET_free (response);
320 }
321 
322 
332 struct EgoEntry *
333 get_egoentry (struct RequestHandle *handle, char *pubkey, char *name)
334 {
335  struct EgoEntry *ego_entry;
336  if (NULL != pubkey)
337  {
338  for (ego_entry = handle->ego_head; NULL != ego_entry;
339  ego_entry = ego_entry->next)
340  {
341  if (0 != strcasecmp (pubkey, ego_entry->keystring))
342  continue;
343  return ego_entry;
344  }
345  }
346  if (NULL != name)
347  {
348  for (ego_entry = handle->ego_head; NULL != ego_entry;
349  ego_entry = ego_entry->next)
350  {
351  if (0 != strcasecmp (name, ego_entry->identifier))
352  continue;
353  return ego_entry;
354  }
355  }
356  return NULL;
357 }
358 
359 
368 static void
370  struct GNUNET_IDENTITY_Ego *ego,
371  void **ctx,
372  const char *name)
373 {
374  struct RequestHandle *handle = cls;
375  struct MHD_Response *resp;
376  struct GNUNET_CRYPTO_EcdsaPublicKey public_key;
377  json_t *json_root;
378  char *result_str;
379  char *public_key_string;
380 
381  if (NULL == ego)
382  {
383  handle->response_code = MHD_HTTP_NOT_FOUND;
386  return;
387  }
388 
389  GNUNET_IDENTITY_ego_get_public_key (ego, &public_key);
390  public_key_string = GNUNET_CRYPTO_ecdsa_public_key_to_string (&public_key);
391 
392  // create json with subsystem identity
393  json_root = json_object ();
394  json_object_set_new (json_root,
396  json_string (public_key_string));
397  json_object_set_new (json_root,
399  json_string (name));
400 
401  result_str = json_dumps (json_root, 0);
402  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
403  resp = GNUNET_REST_create_response (result_str);
404 
405  json_decref (json_root);
406  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
407  GNUNET_free (result_str);
408  GNUNET_free (public_key_string);
410 }
411 
419 void
421  const char *url,
422  void *cls)
423 {
424  struct RequestHandle *handle = cls;
425  char *subsystem;
426 
427  if (strlen (GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM) >= strlen (handle->url))
428  {
429  handle->emsg = GNUNET_strdup ("Missing subsystem name");
431  return;
432  }
433  subsystem = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM) + 1];
434  //requested default identity of subsystem
435  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsystem);
436 
437  handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
438  subsystem,
440  handle);
441 
442  if (NULL == handle->op)
443  {
444  handle->response_code = MHD_HTTP_NOT_FOUND;
447  return;
448  }
449 }
450 
451 
459 void
461  const char *url,
462  void *cls)
463 {
464  struct RequestHandle *handle = cls;
465  struct EgoEntry *ego_entry;
466  struct MHD_Response *resp;
467  json_t *json_root;
468  json_t *json_ego;
469  char *result_str;
470 
471  json_root = json_array ();
472  //Return ego/egos
473  for (ego_entry = handle->ego_head; NULL != ego_entry;
474  ego_entry = ego_entry->next)
475  {
476  json_ego = json_object ();
477  json_object_set_new (json_ego,
479  json_string (ego_entry->keystring));
480  json_object_set_new (json_ego,
482  json_string (ego_entry->identifier));
483  json_array_append (json_root, json_ego);
484  json_decref (json_ego);
485  }
486 
487  result_str = json_dumps (json_root, 0);
488  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
489  resp = GNUNET_REST_create_response (result_str);
490 
491  json_decref (json_root);
492  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
493  GNUNET_free (result_str);
495 }
496 
497 
504 void
505 ego_get_response (struct RequestHandle *handle, struct EgoEntry *ego_entry)
506 {
507  struct MHD_Response *resp;
508  json_t *json_ego;
509  char *result_str;
510 
511  json_ego = json_object ();
512  json_object_set_new (json_ego,
514  json_string (ego_entry->keystring));
515  json_object_set_new (json_ego,
517  json_string (ego_entry->identifier));
518 
519  result_str = json_dumps (json_ego, 0);
520  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
521  resp = GNUNET_REST_create_response (result_str);
522  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
523 
524  json_decref (json_ego);
525  GNUNET_free (result_str);
527 }
528 
529 
537 void
539  const char *url,
540  void *cls)
541 {
542  struct RequestHandle *handle = cls;
543  struct EgoEntry *ego_entry;
544  char *keystring;
545 
546  keystring = NULL;
547 
548  if (strlen (GNUNET_REST_API_NS_IDENTITY_PUBKEY) >= strlen (handle->url))
549  {
550  handle->response_code = MHD_HTTP_NOT_FOUND;
553  return;
554  }
555  keystring = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_PUBKEY) + 1];
556  ego_entry = get_egoentry (handle, keystring, NULL);
557 
558  if (NULL == ego_entry)
559  {
560  handle->response_code = MHD_HTTP_NOT_FOUND;
563  return;
564  }
565 
566  ego_get_response (handle, ego_entry);
567 }
568 
576 void
578  const char *url,
579  void *cls)
580 {
581  struct RequestHandle *handle = cls;
582  struct EgoEntry *ego_entry;
583  char *egoname;
584 
585  egoname = NULL;
586 
587  if (strlen (GNUNET_REST_API_NS_IDENTITY_NAME) >= strlen (handle->url))
588  {
589  handle->response_code = MHD_HTTP_NOT_FOUND;
592  return;
593  }
594  egoname = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_NAME) + 1];
595  ego_entry = get_egoentry (handle, NULL, egoname);
596 
597  if (NULL == ego_entry)
598  {
599  handle->response_code = MHD_HTTP_NOT_FOUND;
602  return;
603  }
604 
605  ego_get_response (handle, ego_entry);
606 }
607 
608 
615 static void
616 do_finished (void *cls, const char *emsg)
617 {
618  struct RequestHandle *handle = cls;
619  struct MHD_Response *resp;
620 
621  handle->op = NULL;
622  if (NULL != emsg)
623  {
624  handle->emsg = GNUNET_strdup (emsg);
626  return;
627  }
628  if (0 == handle->response_code)
629  {
630  handle->response_code = MHD_HTTP_NO_CONTENT;
631  }
632  resp = GNUNET_REST_create_response (NULL);
633  handle->proc (handle->proc_cls, resp, handle->response_code);
635 }
636 
637 
645 static void
647  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk,
648  const char *emsg)
649 {
650  struct RequestHandle *handle = cls;
651 
652  (void) pk;
653  do_finished (handle, emsg);
654 }
655 
656 
663 void
665 {
666  struct EgoEntry *ego_entry_tmp;
667  struct MHD_Response *resp;
668  json_t *data_js;
669  json_error_t err;
670  char *newname;
671  char term_data[handle->data_size + 1];
672  int json_state;
673 
674  //if no data
675  if (0 >= handle->data_size)
676  {
679  return;
680  }
681  //if not json
682  term_data[handle->data_size] = '\0';
683  GNUNET_memcpy (term_data, handle->data, handle->data_size);
684  data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
685 
686  if (NULL == data_js)
687  {
690  return;
691  }
692 
693  newname = NULL;
694  //NEW NAME
695  json_state = 0;
696  json_state = json_unpack (data_js,
697  "{s:s!}",
699  &newname);
700  //Change name with pubkey or name identifier
701  if (0 != json_state)
702  {
703 
706  json_decref (data_js);
707  return;
708  }
709 
710  if (NULL == newname)
711  {
714  json_decref (data_js);
715  return;
716  }
717 
718  if (0 >= strlen (newname))
719  {
722  json_decref (data_js);
723  return;
724  }
725 
726  ego_entry_tmp = get_egoentry (handle, NULL, newname);
727  if (NULL != ego_entry_tmp)
728  {
729  //Ego with same name not allowed (even if its the ego we change)
730  resp = GNUNET_REST_create_response (NULL);
731  handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
733  json_decref (data_js);
734  return;
735  }
736  handle->op = GNUNET_IDENTITY_rename (handle->identity_handle,
737  ego_entry->identifier,
738  newname,
739  &do_finished,
740  handle);
741  if (NULL == handle->op)
742  {
743  handle->emsg = GNUNET_strdup ("Rename failed");
745  json_decref (data_js);
746  return;
747  }
748  json_decref (data_js);
749  return;
750 }
751 
752 
760 void
762  const char *url,
763  void *cls)
764 {
765  struct RequestHandle *handle = cls;
766  struct EgoEntry *ego_entry;
767  char *keystring;
768 
769  keystring = NULL;
770 
771  if (strlen (GNUNET_REST_API_NS_IDENTITY_PUBKEY) >= strlen (handle->url))
772  {
773  handle->response_code = MHD_HTTP_NOT_FOUND;
776  return;
777  }
778  keystring = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_PUBKEY) + 1];
779  ego_entry = get_egoentry (handle, keystring, NULL);
780 
781  if (NULL == ego_entry)
782  {
783  handle->response_code = MHD_HTTP_NOT_FOUND;
786  return;
787  }
788 
789  ego_edit (handle, ego_entry);
790 }
791 
799 void
801  const char *url,
802  void *cls)
803 {
804  struct RequestHandle *handle = cls;
805  struct EgoEntry *ego_entry;
806  char *name;
807 
808  name = NULL;
809 
810  if (strlen (GNUNET_REST_API_NS_IDENTITY_NAME) >= strlen (handle->url))
811  {
812  handle->response_code = MHD_HTTP_NOT_FOUND;
815  return;
816  }
817  name = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_NAME) + 1];
818  ego_entry = get_egoentry (handle, NULL, name);
819 
820  if (NULL == ego_entry)
821  {
822  handle->response_code = MHD_HTTP_NOT_FOUND;
825  return;
826  }
827 
828  ego_edit (handle, ego_entry);
829 }
830 
838 void
840  const char *url,
841  void *cls)
842 {
843  struct RequestHandle *handle = cls;
844  struct EgoEntry *ego_entry;
845  json_t *data_js;
846  json_error_t err;
847  char *newsubsys;
848  char *name;
849  char term_data[handle->data_size + 1];
850  int json_state;
851 
852  name = NULL;
853 
854  if (strlen (GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM) >= strlen (handle->url))
855  {
856  handle->response_code = MHD_HTTP_NOT_FOUND;
859  return;
860  }
861  name = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM) + 1];
862  ego_entry = get_egoentry (handle, NULL, name);
863 
864  if (NULL == ego_entry)
865  {
866  handle->response_code = MHD_HTTP_NOT_FOUND;
869  return;
870  }
871 
872  //if no data
873  if (0 >= handle->data_size)
874  {
877  return;
878  }
879  //if not json
880  term_data[handle->data_size] = '\0';
881  GNUNET_memcpy (term_data, handle->data, handle->data_size);
882  data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
883 
884  if (NULL == data_js)
885  {
888  return;
889  }
890 
891  newsubsys = NULL;
892  //SUBSYSTEM
893  json_state = 0;
894  json_state = json_unpack (data_js,
895  "{s:s!}",
897  &newsubsys);
898  //Change subsystem with pubkey or name identifier
899  if (0 != json_state)
900  {
903  json_decref (data_js);
904  return;
905  }
906 
907  if (NULL == newsubsys)
908  {
911  json_decref (data_js);
912  return;
913  }
914 
915  if (0 >= strlen (newsubsys))
916  {
919  json_decref (data_js);
920  return;
921  }
922 
923  handle->response_code = MHD_HTTP_NO_CONTENT;
924  handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
925  newsubsys,
926  ego_entry->ego,
927  &do_finished,
928  handle);
929  if (NULL == handle->op)
930  {
931  handle->emsg = GNUNET_strdup ("Setting subsystem failed");
933  return;
934  }
935  json_decref (data_js);
936  return;
937 }
938 
946 void
948  const char *url,
949  void *cls)
950 {
951  struct RequestHandle *handle = cls;
952  struct EgoEntry *ego_entry;
953  struct MHD_Response *resp;
954  json_t *data_js;
955  json_error_t err;
956  char *egoname;
957  int json_unpack_state;
958  char term_data[handle->data_size + 1];
959 
960  if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url))
961  {
963  return;
964  }
965 
966  if (0 >= handle->data_size)
967  {
970  return;
971  }
972  term_data[handle->data_size] = '\0';
973  GNUNET_memcpy (term_data, handle->data, handle->data_size);
974  data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
975  if (NULL == data_js)
976  {
979  json_decref (data_js);
980  return;
981  }
982  json_unpack_state = 0;
983  json_unpack_state =
984  json_unpack (data_js, "{s:s!}", GNUNET_REST_IDENTITY_PARAM_NAME, &egoname);
985  if (0 != json_unpack_state)
986  {
989  json_decref (data_js);
990  return;
991  }
992 
993  if (NULL == egoname)
994  {
997  json_decref (data_js);
998  return;
999  }
1000  if (0 >= strlen (egoname))
1001  {
1002  json_decref (data_js);
1005  return;
1006  }
1007  GNUNET_STRINGS_utf8_tolower (egoname, egoname);
1008  for (ego_entry = handle->ego_head; NULL != ego_entry;
1009  ego_entry = ego_entry->next)
1010  {
1011  if (0 == strcasecmp (egoname, ego_entry->identifier))
1012  {
1013  resp = GNUNET_REST_create_response (NULL);
1014  handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
1016  json_decref (data_js);
1017  return;
1018  }
1019  }
1020  handle->name = GNUNET_strdup (egoname);
1021  json_decref (data_js);
1022  handle->response_code = MHD_HTTP_CREATED;
1023  handle->op = GNUNET_IDENTITY_create (handle->identity_handle,
1024  handle->name,
1026  handle);
1027 }
1028 
1036 void
1038  const char *url,
1039  void *cls)
1040 {
1041  struct RequestHandle *handle = cls;
1042  struct EgoEntry *ego_entry;
1043  char *keystring;
1044 
1045  keystring = NULL;
1046 
1047  if (strlen (GNUNET_REST_API_NS_IDENTITY_PUBKEY) >= strlen (handle->url))
1048  {
1049  handle->response_code = MHD_HTTP_NOT_FOUND;
1052  return;
1053  }
1054  keystring = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_PUBKEY) + 1];
1055  ego_entry = get_egoentry (handle, keystring, NULL);
1056 
1057  if (NULL == ego_entry)
1058  {
1059  handle->response_code = MHD_HTTP_NOT_FOUND;
1062  return;
1063  }
1064 
1065  handle->response_code = MHD_HTTP_NO_CONTENT;
1066  handle->op = GNUNET_IDENTITY_delete (handle->identity_handle,
1067  ego_entry->identifier,
1068  &do_finished,
1069  handle);
1070 }
1071 
1072 
1080 void
1082  const char *url,
1083  void *cls)
1084 {
1085  struct RequestHandle *handle = cls;
1086  struct EgoEntry *ego_entry;
1087  char *name;
1088 
1089  name = NULL;
1090 
1091  if (strlen (GNUNET_REST_API_NS_IDENTITY_NAME) >= strlen (handle->url))
1092  {
1093  handle->response_code = MHD_HTTP_NOT_FOUND;
1096  return;
1097  }
1098  name = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_NAME) + 1];
1099  ego_entry = get_egoentry (handle, NULL, name);
1100 
1101  if (NULL == ego_entry)
1102  {
1103  handle->response_code = MHD_HTTP_NOT_FOUND;
1106  return;
1107  }
1108 
1109  handle->response_code = MHD_HTTP_NO_CONTENT;
1110  handle->op = GNUNET_IDENTITY_delete (handle->identity_handle,
1111  ego_entry->identifier,
1112  &do_finished,
1113  handle);
1114 }
1115 
1116 
1124 static void
1126  const char *url,
1127  void *cls)
1128 {
1129  struct MHD_Response *resp;
1130  struct RequestHandle *handle = cls;
1131 
1132  //For now, independent of path return all options
1133  resp = GNUNET_REST_create_response (NULL);
1134  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
1135  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1137  return;
1138 }
1139 
1145 static void
1147 {
1149  static const struct GNUNET_REST_RequestHandler handlers[] =
1150  {{MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_ALL, &ego_get_all},
1151  {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY, &ego_get_pubkey},
1152  {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name},
1153  {MHD_HTTP_METHOD_GET,
1156  {MHD_HTTP_METHOD_PUT,
1158  &ego_edit_pubkey},
1159  {MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name},
1160  {MHD_HTTP_METHOD_PUT,
1163  {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create},
1164  {MHD_HTTP_METHOD_DELETE,
1167  {MHD_HTTP_METHOD_DELETE,
1169  &ego_delete_name},
1170  {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont},
1172 
1173  if (GNUNET_NO ==
1174  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
1175  {
1176  handle->response_code = err.error_code;
1178  }
1179 }
1180 
1214 static void
1215 init_egos (void *cls,
1216  struct GNUNET_IDENTITY_Ego *ego,
1217  void **ctx,
1218  const char *identifier)
1219 {
1220  struct RequestHandle *handle = cls;
1221  struct EgoEntry *ego_entry;
1222  struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1223 
1224  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
1225  {
1226  handle->state = ID_REST_STATE_POST_INIT;
1227  init_cont (handle);
1228  return;
1229  }
1230  if (ID_REST_STATE_INIT == handle->state)
1231  {
1232  ego_entry = GNUNET_new (struct EgoEntry);
1235  ego_entry->ego = ego;
1236  GNUNET_asprintf (&ego_entry->identifier, "%s", identifier);
1238  handle->ego_tail,
1239  ego_entry);
1240  }
1241 }
1242 
1254 static void
1257  void *proc_cls)
1258 {
1259  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1260 
1261  handle->response_code = 0;
1263  handle->proc_cls = proc_cls;
1264  handle->proc = proc;
1265  handle->rest_handle = rest_handle;
1266  handle->data = rest_handle->data;
1267  handle->data_size = rest_handle->data_size;
1268 
1269  handle->url = GNUNET_strdup (rest_handle->url);
1270  if (handle->url[strlen (handle->url) - 1] == '/')
1271  handle->url[strlen (handle->url) - 1] = '\0';
1272  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1273 
1274  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &init_egos, handle);
1275 
1276  handle->timeout_task =
1277  GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle);
1278 
1279  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1280 }
1281 
1288 void *
1290 {
1291  static struct Plugin plugin;
1292  struct GNUNET_REST_Plugin *api;
1293 
1294  cfg = cls;
1295  if (NULL != plugin.cfg)
1296  return NULL; /* can only initialize once! */
1297  memset (&plugin, 0, sizeof (struct Plugin));
1298  plugin.cfg = cfg;
1299  api = GNUNET_new (struct GNUNET_REST_Plugin);
1300  api->cls = &plugin;
1304  "%s, %s, %s, %s, %s",
1305  MHD_HTTP_METHOD_GET,
1306  MHD_HTTP_METHOD_POST,
1307  MHD_HTTP_METHOD_PUT,
1308  MHD_HTTP_METHOD_DELETE,
1309  MHD_HTTP_METHOD_OPTIONS);
1310 
1311  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity REST API initialized\n"));
1312  return api;
1313 }
1314 
1321 void *
1323 {
1324  struct GNUNET_REST_Plugin *api = cls;
1325  struct Plugin *plugin = api->cls;
1326  plugin->cfg = NULL;
1327 
1329  GNUNET_free (api);
1330  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Identity REST plugin is finished\n");
1331  return NULL;
1332 }
1333 
1334 /* end of plugin_rest_identity.c */
1335 
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 ego_edit_name(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity PUT request with name.
#define ID_REST_STATE_POST_INIT
Done collecting egos.
char * name
Plugin name.
#define GNUNET_REST_IDENTITY_PARAM_SUBSYSTEM
Parameter subsystem.
void(* GNUNET_REST_ResultProcessor)(void *cls, struct MHD_Response *resp, int status)
Iterator called on obtained result for a REST result.
static void init_egos(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
If listing is enabled, prints information about the egos.
static struct GNUNET_CRYPTO_EddsaPrivateKey * pk
Private key of this peer.
static char * subsystem
Set to subsystem that we&#39;re going to get stats for (or NULL for all).
static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey
Public key of the zone to look in.
struct EgoEntry * ego_tail
Ego list.
#define GNUNET_REST_API_NS_IDENTITY_ALL
Identity Namespace with public key specifier.
#define GNUNET_REST_ERROR_NO_DATA
Error message No data.
void * libgnunet_plugin_rest_identity_init(void *cls)
Entry point for the plugin.
void * cls
The closure of the plugin.
size_t data_size
The POST data size.
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_delete(struct GNUNET_IDENTITY_Handle *h, const char *name, GNUNET_IDENTITY_Continuation cb, void *cb_cls)
Delete an existing identity.
Definition: identity_api.c:778
#define GNUNET_REST_API_NS_IDENTITY_NAME
Identity Namespace with public key specifier.
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_create(struct GNUNET_IDENTITY_Handle *h, const char *name, GNUNET_IDENTITY_CreateContinuation cont, void *cont_cls)
Create a new identity with the given name.
Definition: identity_api.c:678
GNUNET_REST_ResultProcessor proc
The plugin result processor.
static void do_finished_create(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, const char *emsg)
Processing finished, when creating an ego.
struct EgoEntry * get_egoentry(struct RequestHandle *handle, char *pubkey, char *name)
Get EgoEntry from list with either a public key or a name If public key and name are not NULL...
void ego_delete_name(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity DELETE request with name.
void ego_get_subsystem(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity GET request for subsystem.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_set(struct GNUNET_IDENTITY_Handle *h, const char *service_name, struct GNUNET_IDENTITY_Ego *ego, GNUNET_IDENTITY_Continuation cont, void *cont_cls)
Set the preferred/default identity for a service.
Definition: identity_api.c:632
size_t data_size
the length of the REST data
struct returned by the initialization function of the plugin
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_get(struct GNUNET_IDENTITY_Handle *h, const char *service_name, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Obtain the identity that is currently preferred/default for a service.
Definition: identity_api.c:587
static void init_cont(struct RequestHandle *handle)
Handle rest request.
static void do_finished(void *cls, const char *emsg)
Processing finished.
#define GNUNET_NO
Definition: gnunet_common.h:81
#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.
#define GNUNET_REST_API_NS_IDENTITY_PUBKEY
Identity Namespace with public key specifier.
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 ego_delete_pubkey(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity DELETE request with public key.
void * proc_cls
The closure of the result processor.
#define GNUNET_REST_IDENTITY_ERROR_UNKNOWN
Error message Unknown Error.
Handle for an operation with the identity service.
Definition: identity_api.c:39
#define GNUNET_REST_HANDLER_END
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
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
The ego list.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
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
#define GNUNET_REST_ERROR_DATA_INVALID
Error message Data invalid.
char * name
Name to look up.
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
#define GNUNET_memcpy(dst, src, n)
char * emsg
Error response message.
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.
#define GNUNET_REST_IDENTITY_MISSING_NAME
Error message Missing identity name.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:838
static void rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
#define GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM
Identity Subsystem Namespace.
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.
void ego_edit(struct RequestHandle *handle, struct EgoEntry *ego_entry)
Processing edit ego with EgoEntry ego_entry.
int response_code
HTTP response code.
int state
The processing state.
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
const char * data
The POST data.
char * keystring
Public key string.
void ego_get_response(struct RequestHandle *handle, struct EgoEntry *ego_entry)
Responds with the ego_entry identity.
void ego_get_all(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity GET request - responds with all identities.
void ego_get_name(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity GET request with a name.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static struct GNUNET_SCHEDULER_Task * timeout_task
Task to be run on timeout.
Definition: gnunet-arm.c:119
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 cleanup_handle(void *cls)
Cleanup lookup handle.
static char * allow_methods
HTTP methods allows for this plugin.
#define GNUNET_REST_IDENTITY_PARAM_PUBKEY
Parameter public key.
char * identifier
Ego Identifier.
static void ego_get_for_subsystem(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name)
Callback for GET Request with subsystem.
#define GNUNET_REST_IDENTITY_PARAM_NEWNAME
Parameter new name.
#define GNUNET_REST_IDENTITY_MISSING_PUBKEY
Error message Missing identity name.
void ego_edit_pubkey(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity PUT request with public key.
configuration data
Definition: configuration.c:85
struct EgoEntry * ego_head
Ego list.
Handle for a plugin.
Definition: block.c:37
const char * data
The data from the REST request.
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
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...
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
#define GNUNET_REST_API_NS_IDENTITY
Identity Namespace.
static void do_error(void *cls)
Task run on errors.
static struct MHD_Response * response
Our canonical response.
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_rename(struct GNUNET_IDENTITY_Handle *h, const char *old_name, const char *new_name, GNUNET_IDENTITY_Continuation cb, void *cb_cls)
Renames an existing identity.
Definition: identity_api.c:725
struct EgoEntry * prev
DLL.
void ego_create(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity POST request.
void * libgnunet_plugin_rest_identity_done(void *cls)
Exit point from the plugin.
struct EgoEntry * ego_entry
IDENTITY Operation.
#define GNUNET_REST_IDENTITY_PARAM_NAME
Parameter name.
void ego_edit_subsystem(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity subsystem PUT request with name.
struct EgoEntry * next
DLL.
void ego_get_pubkey(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity GET request with a public key.
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
struct GNUNET_IDENTITY_Operation * op
IDENTITY Operation.
#define GNUNET_free(ptr)
Wrapper around free.
#define ID_REST_STATE_INIT
State while collecting all egos.
Time for relative time used by GNUnet, in microseconds.
void GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
Convert the utf-8 input string to lower case.
Definition: strings.c:558
#define GNUNET_REST_IDENTITY_NOT_FOUND
Error message No identity found.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
char * url
The url.