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  const struct GNUNET_CONFIGURATION_Handle *cfg;
134 };
135 
139 struct EgoEntry {
143  struct EgoEntry *next;
144 
148  struct EgoEntry *prev;
149 
153  char *identifier;
154 
158  char *keystring;
159 
164 };
165 
169 struct RequestHandle {
173  const char *data;
174 
178  char *name;
179 
183  size_t data_size;
184 
185 
190 
195 
199  int state;
200 
205 
210 
214  struct GNUNET_REST_RequestHandle *rest_handle;
215 
220 
225 
230 
234  void *proc_cls;
235 
239  char *url;
240 
244  char *emsg;
245 
249  int response_code;
250 };
251 
256 static void
257 cleanup_handle(void *cls)
258 {
259  struct RequestHandle *handle = cls;
260  struct EgoEntry *ego_entry;
261  struct EgoEntry *ego_tmp;
262 
263  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
264  if (NULL != handle->timeout_task)
265  {
267  handle->timeout_task = NULL;
268  }
269 
270  if (NULL != handle->url)
271  GNUNET_free(handle->url);
272  if (NULL != handle->emsg)
273  GNUNET_free(handle->emsg);
274  if (NULL != handle->name)
275  GNUNET_free(handle->name);
276  if (NULL != handle->identity_handle)
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 
288  GNUNET_free(handle);
289 }
290 
296 static void
297 do_error(void *cls)
298 {
299  struct RequestHandle *handle = cls;
300  struct MHD_Response *resp;
301  json_t *json_error = json_object();
302  char *response;
303 
304  if (NULL == handle->emsg)
306 
307  json_object_set_new(json_error, "error", json_string(handle->emsg));
308 
309  if (0 == handle->response_code)
310  handle->response_code = MHD_HTTP_OK;
311  response = json_dumps(json_error, 0);
312  resp = GNUNET_REST_create_response(response);
313  handle->proc(handle->proc_cls, resp, handle->response_code);
314  json_decref(json_error);
315  GNUNET_free(response);
317 }
318 
319 
329 struct EgoEntry *
331 {
332  struct EgoEntry *ego_entry;
333 
334  if (NULL != pubkey)
335  {
336  for (ego_entry = handle->ego_head; NULL != ego_entry;
337  ego_entry = ego_entry->next)
338  {
339  if (0 != strcasecmp(pubkey, ego_entry->keystring))
340  continue;
341  return ego_entry;
342  }
343  }
344  if (NULL != name)
345  {
346  for (ego_entry = handle->ego_head; NULL != ego_entry;
347  ego_entry = ego_entry->next)
348  {
349  if (0 != strcasecmp(name, ego_entry->identifier))
350  continue;
351  return ego_entry;
352  }
353  }
354  return NULL;
355 }
356 
357 
366 static void
368  struct GNUNET_IDENTITY_Ego *ego,
369  void **ctx,
370  const char *name)
371 {
372  struct RequestHandle *handle = cls;
373  struct MHD_Response *resp;
374  struct GNUNET_CRYPTO_EcdsaPublicKey public_key;
375  json_t *json_root;
376  char *result_str;
377  char *public_key_string;
378 
379  if (NULL == ego)
380  {
381  handle->response_code = MHD_HTTP_NOT_FOUND;
384  return;
385  }
386 
387  GNUNET_IDENTITY_ego_get_public_key(ego, &public_key);
388  public_key_string = GNUNET_CRYPTO_ecdsa_public_key_to_string(&public_key);
389 
390  // create json with subsystem identity
391  json_root = json_object();
392  json_object_set_new(json_root,
394  json_string(public_key_string));
395  json_object_set_new(json_root,
397  json_string(name));
398 
399  result_str = json_dumps(json_root, 0);
400  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
401  resp = GNUNET_REST_create_response(result_str);
402 
403  json_decref(json_root);
404  handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
405  GNUNET_free(result_str);
406  GNUNET_free(public_key_string);
408 }
409 
417 void
419  const char *url,
420  void *cls)
421 {
422  struct RequestHandle *handle = cls;
423  char *subsystem;
424 
425  if (strlen(GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM) >= strlen(handle->url))
426  {
427  handle->emsg = GNUNET_strdup("Missing subsystem name");
429  return;
430  }
431  subsystem = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM) + 1];
432  //requested default identity of subsystem
433  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsystem);
434 
435  handle->op = GNUNET_IDENTITY_get(handle->identity_handle,
436  subsystem,
438  handle);
439 
440  if (NULL == handle->op)
441  {
442  handle->response_code = MHD_HTTP_NOT_FOUND;
445  return;
446  }
447 }
448 
449 
457 void
459  const char *url,
460  void *cls)
461 {
462  struct RequestHandle *handle = cls;
463  struct EgoEntry *ego_entry;
464  struct MHD_Response *resp;
465  json_t *json_root;
466  json_t *json_ego;
467  char *result_str;
468 
469  json_root = json_array();
470  //Return ego/egos
471  for (ego_entry = handle->ego_head; NULL != ego_entry;
472  ego_entry = ego_entry->next)
473  {
474  json_ego = json_object();
475  json_object_set_new(json_ego,
477  json_string(ego_entry->keystring));
478  json_object_set_new(json_ego,
480  json_string(ego_entry->identifier));
481  json_array_append(json_root, json_ego);
482  json_decref(json_ego);
483  }
484 
485  result_str = json_dumps(json_root, 0);
486  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
487  resp = GNUNET_REST_create_response(result_str);
488 
489  json_decref(json_root);
490  handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
491  GNUNET_free(result_str);
493 }
494 
495 
502 void
503 ego_get_response(struct RequestHandle *handle, struct EgoEntry *ego_entry)
504 {
505  struct MHD_Response *resp;
506  json_t *json_ego;
507  char *result_str;
508 
509  json_ego = json_object();
510  json_object_set_new(json_ego,
512  json_string(ego_entry->keystring));
513  json_object_set_new(json_ego,
515  json_string(ego_entry->identifier));
516 
517  result_str = json_dumps(json_ego, 0);
518  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
519  resp = GNUNET_REST_create_response(result_str);
520  handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
521 
522  json_decref(json_ego);
523  GNUNET_free(result_str);
525 }
526 
527 
535 void
537  const char *url,
538  void *cls)
539 {
540  struct RequestHandle *handle = cls;
541  struct EgoEntry *ego_entry;
542  char *keystring;
543 
544  keystring = NULL;
545 
546  if (strlen(GNUNET_REST_API_NS_IDENTITY_PUBKEY) >= strlen(handle->url))
547  {
548  handle->response_code = MHD_HTTP_NOT_FOUND;
551  return;
552  }
553  keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY_PUBKEY) + 1];
554  ego_entry = get_egoentry(handle, keystring, NULL);
555 
556  if (NULL == ego_entry)
557  {
558  handle->response_code = MHD_HTTP_NOT_FOUND;
561  return;
562  }
563 
564  ego_get_response(handle, ego_entry);
565 }
566 
574 void
576  const char *url,
577  void *cls)
578 {
579  struct RequestHandle *handle = cls;
580  struct EgoEntry *ego_entry;
581  char *egoname;
582 
583  egoname = NULL;
584 
585  if (strlen(GNUNET_REST_API_NS_IDENTITY_NAME) >= strlen(handle->url))
586  {
587  handle->response_code = MHD_HTTP_NOT_FOUND;
590  return;
591  }
592  egoname = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY_NAME) + 1];
593  ego_entry = get_egoentry(handle, NULL, egoname);
594 
595  if (NULL == ego_entry)
596  {
597  handle->response_code = MHD_HTTP_NOT_FOUND;
600  return;
601  }
602 
603  ego_get_response(handle, ego_entry);
604 }
605 
606 
613 static void
614 do_finished(void *cls, const char *emsg)
615 {
616  struct RequestHandle *handle = cls;
617  struct MHD_Response *resp;
618 
619  handle->op = NULL;
620  if (NULL != emsg)
621  {
622  handle->emsg = GNUNET_strdup(emsg);
624  return;
625  }
626  if (0 == handle->response_code)
627  {
628  handle->response_code = MHD_HTTP_NO_CONTENT;
629  }
630  resp = GNUNET_REST_create_response(NULL);
631  handle->proc(handle->proc_cls, resp, handle->response_code);
633 }
634 
635 
643 static void
645  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk,
646  const char *emsg)
647 {
648  struct RequestHandle *handle = cls;
649 
650  (void)pk;
651  do_finished(handle, emsg);
652 }
653 
654 
661 void
663 {
664  struct EgoEntry *ego_entry_tmp;
665  struct MHD_Response *resp;
666  json_t *data_js;
667  json_error_t err;
668  char *newname;
669  char term_data[handle->data_size + 1];
670  int json_state;
671 
672  //if no data
673  if (0 >= handle->data_size)
674  {
677  return;
678  }
679  //if not json
680  term_data[handle->data_size] = '\0';
681  GNUNET_memcpy(term_data, handle->data, handle->data_size);
682  data_js = json_loads(term_data, JSON_DECODE_ANY, &err);
683 
684  if (NULL == data_js)
685  {
688  return;
689  }
690 
691  newname = NULL;
692  //NEW NAME
693  json_state = 0;
694  json_state = json_unpack(data_js,
695  "{s:s!}",
697  &newname);
698  //Change name with pubkey or name identifier
699  if (0 != json_state)
700  {
703  json_decref(data_js);
704  return;
705  }
706 
707  if (NULL == newname)
708  {
711  json_decref(data_js);
712  return;
713  }
714 
715  if (0 >= strlen(newname))
716  {
719  json_decref(data_js);
720  return;
721  }
722 
723  ego_entry_tmp = get_egoentry(handle, NULL, newname);
724  if (NULL != ego_entry_tmp)
725  {
726  //Ego with same name not allowed (even if its the ego we change)
727  resp = GNUNET_REST_create_response(NULL);
728  handle->proc(handle->proc_cls, resp, MHD_HTTP_CONFLICT);
730  json_decref(data_js);
731  return;
732  }
733  handle->op = GNUNET_IDENTITY_rename(handle->identity_handle,
734  ego_entry->identifier,
735  newname,
736  &do_finished,
737  handle);
738  if (NULL == handle->op)
739  {
740  handle->emsg = GNUNET_strdup("Rename failed");
742  json_decref(data_js);
743  return;
744  }
745  json_decref(data_js);
746  return;
747 }
748 
749 
757 void
759  const char *url,
760  void *cls)
761 {
762  struct RequestHandle *handle = cls;
763  struct EgoEntry *ego_entry;
764  char *keystring;
765 
766  keystring = NULL;
767 
768  if (strlen(GNUNET_REST_API_NS_IDENTITY_PUBKEY) >= strlen(handle->url))
769  {
770  handle->response_code = MHD_HTTP_NOT_FOUND;
773  return;
774  }
775  keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY_PUBKEY) + 1];
776  ego_entry = get_egoentry(handle, keystring, NULL);
777 
778  if (NULL == ego_entry)
779  {
780  handle->response_code = MHD_HTTP_NOT_FOUND;
783  return;
784  }
785 
786  ego_edit(handle, ego_entry);
787 }
788 
796 void
798  const char *url,
799  void *cls)
800 {
801  struct RequestHandle *handle = cls;
802  struct EgoEntry *ego_entry;
803  char *name;
804 
805  name = NULL;
806 
807  if (strlen(GNUNET_REST_API_NS_IDENTITY_NAME) >= strlen(handle->url))
808  {
809  handle->response_code = MHD_HTTP_NOT_FOUND;
812  return;
813  }
814  name = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY_NAME) + 1];
815  ego_entry = get_egoentry(handle, NULL, name);
816 
817  if (NULL == ego_entry)
818  {
819  handle->response_code = MHD_HTTP_NOT_FOUND;
822  return;
823  }
824 
825  ego_edit(handle, ego_entry);
826 }
827 
835 void
837  const char *url,
838  void *cls)
839 {
840  struct RequestHandle *handle = cls;
841  struct EgoEntry *ego_entry;
842  json_t *data_js;
843  json_error_t err;
844  char *newsubsys;
845  char *name;
846  char term_data[handle->data_size + 1];
847  int json_state;
848 
849  name = NULL;
850 
851  if (strlen(GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM) >= strlen(handle->url))
852  {
853  handle->response_code = MHD_HTTP_NOT_FOUND;
856  return;
857  }
858  name = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM) + 1];
859  ego_entry = get_egoentry(handle, NULL, name);
860 
861  if (NULL == ego_entry)
862  {
863  handle->response_code = MHD_HTTP_NOT_FOUND;
866  return;
867  }
868 
869  //if no data
870  if (0 >= handle->data_size)
871  {
874  return;
875  }
876  //if not json
877  term_data[handle->data_size] = '\0';
878  GNUNET_memcpy(term_data, handle->data, handle->data_size);
879  data_js = json_loads(term_data, JSON_DECODE_ANY, &err);
880 
881  if (NULL == data_js)
882  {
885  return;
886  }
887 
888  newsubsys = NULL;
889  //SUBSYSTEM
890  json_state = 0;
891  json_state = json_unpack(data_js,
892  "{s:s!}",
894  &newsubsys);
895  //Change subsystem with pubkey or name identifier
896  if (0 != json_state)
897  {
900  json_decref(data_js);
901  return;
902  }
903 
904  if (NULL == newsubsys)
905  {
908  json_decref(data_js);
909  return;
910  }
911 
912  if (0 >= strlen(newsubsys))
913  {
916  json_decref(data_js);
917  return;
918  }
919 
920  handle->response_code = MHD_HTTP_NO_CONTENT;
921  handle->op = GNUNET_IDENTITY_set(handle->identity_handle,
922  newsubsys,
923  ego_entry->ego,
924  &do_finished,
925  handle);
926  if (NULL == handle->op)
927  {
928  handle->emsg = GNUNET_strdup("Setting subsystem failed");
930  return;
931  }
932  json_decref(data_js);
933  return;
934 }
935 
943 void
945  const char *url,
946  void *cls)
947 {
948  struct RequestHandle *handle = cls;
949  struct EgoEntry *ego_entry;
950  struct MHD_Response *resp;
951  json_t *data_js;
952  json_error_t err;
953  char *egoname;
954  int json_unpack_state;
955  char term_data[handle->data_size + 1];
956 
957  if (strlen(GNUNET_REST_API_NS_IDENTITY) != strlen(handle->url))
958  {
960  return;
961  }
962 
963  if (0 >= handle->data_size)
964  {
967  return;
968  }
969  term_data[handle->data_size] = '\0';
970  GNUNET_memcpy(term_data, handle->data, handle->data_size);
971  data_js = json_loads(term_data, JSON_DECODE_ANY, &err);
972  if (NULL == data_js)
973  {
976  json_decref(data_js);
977  return;
978  }
979  json_unpack_state = 0;
980  json_unpack_state =
981  json_unpack(data_js, "{s:s!}", GNUNET_REST_IDENTITY_PARAM_NAME, &egoname);
982  if (0 != json_unpack_state)
983  {
986  json_decref(data_js);
987  return;
988  }
989 
990  if (NULL == egoname)
991  {
994  json_decref(data_js);
995  return;
996  }
997  if (0 >= strlen(egoname))
998  {
999  json_decref(data_js);
1002  return;
1003  }
1004  GNUNET_STRINGS_utf8_tolower(egoname, egoname);
1005  for (ego_entry = handle->ego_head; NULL != ego_entry;
1006  ego_entry = ego_entry->next)
1007  {
1008  if (0 == strcasecmp(egoname, ego_entry->identifier))
1009  {
1010  resp = GNUNET_REST_create_response(NULL);
1011  handle->proc(handle->proc_cls, resp, MHD_HTTP_CONFLICT);
1013  json_decref(data_js);
1014  return;
1015  }
1016  }
1017  handle->name = GNUNET_strdup(egoname);
1018  json_decref(data_js);
1019  handle->response_code = MHD_HTTP_CREATED;
1020  handle->op = GNUNET_IDENTITY_create(handle->identity_handle,
1021  handle->name,
1023  handle);
1024 }
1025 
1033 void
1035  const char *url,
1036  void *cls)
1037 {
1038  struct RequestHandle *handle = cls;
1039  struct EgoEntry *ego_entry;
1040  char *keystring;
1041 
1042  keystring = NULL;
1043 
1044  if (strlen(GNUNET_REST_API_NS_IDENTITY_PUBKEY) >= strlen(handle->url))
1045  {
1046  handle->response_code = MHD_HTTP_NOT_FOUND;
1049  return;
1050  }
1051  keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY_PUBKEY) + 1];
1052  ego_entry = get_egoentry(handle, keystring, NULL);
1053 
1054  if (NULL == ego_entry)
1055  {
1056  handle->response_code = MHD_HTTP_NOT_FOUND;
1059  return;
1060  }
1061 
1062  handle->response_code = MHD_HTTP_NO_CONTENT;
1063  handle->op = GNUNET_IDENTITY_delete(handle->identity_handle,
1064  ego_entry->identifier,
1065  &do_finished,
1066  handle);
1067 }
1068 
1069 
1077 void
1079  const char *url,
1080  void *cls)
1081 {
1082  struct RequestHandle *handle = cls;
1083  struct EgoEntry *ego_entry;
1084  char *name;
1085 
1086  name = NULL;
1087 
1088  if (strlen(GNUNET_REST_API_NS_IDENTITY_NAME) >= strlen(handle->url))
1089  {
1090  handle->response_code = MHD_HTTP_NOT_FOUND;
1093  return;
1094  }
1095  name = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY_NAME) + 1];
1096  ego_entry = get_egoentry(handle, NULL, name);
1097 
1098  if (NULL == ego_entry)
1099  {
1100  handle->response_code = MHD_HTTP_NOT_FOUND;
1103  return;
1104  }
1105 
1106  handle->response_code = MHD_HTTP_NO_CONTENT;
1107  handle->op = GNUNET_IDENTITY_delete(handle->identity_handle,
1108  ego_entry->identifier,
1109  &do_finished,
1110  handle);
1111 }
1112 
1113 
1121 static void
1123  const char *url,
1124  void *cls)
1125 {
1126  struct MHD_Response *resp;
1127  struct RequestHandle *handle = cls;
1128 
1129  //For now, independent of path return all options
1130  resp = GNUNET_REST_create_response(NULL);
1131  MHD_add_response_header(resp, "Access-Control-Allow-Methods", allow_methods);
1132  handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
1134  return;
1135 }
1136 
1142 static void
1144 {
1146  static const struct GNUNET_REST_RequestHandler handlers[] =
1147  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_ALL, &ego_get_all },
1148  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY, &ego_get_pubkey },
1149  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name },
1150  { MHD_HTTP_METHOD_GET,
1152  &ego_get_subsystem },
1153  { MHD_HTTP_METHOD_PUT,
1155  &ego_edit_pubkey },
1156  { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name },
1157  { MHD_HTTP_METHOD_PUT,
1159  &ego_edit_subsystem },
1160  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create },
1161  { MHD_HTTP_METHOD_DELETE,
1163  &ego_delete_pubkey },
1164  { MHD_HTTP_METHOD_DELETE,
1166  &ego_delete_name },
1167  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont },
1169 
1170  if (GNUNET_NO ==
1171  GNUNET_REST_handle_request(handle->rest_handle, handlers, &err, handle))
1172  {
1173  handle->response_code = err.error_code;
1175  }
1176 }
1177 
1211 static void
1212 init_egos(void *cls,
1213  struct GNUNET_IDENTITY_Ego *ego,
1214  void **ctx,
1215  const char *identifier)
1216 {
1217  struct RequestHandle *handle = cls;
1218  struct EgoEntry *ego_entry;
1219  struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1220 
1221  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
1222  {
1223  handle->state = ID_REST_STATE_POST_INIT;
1224  init_cont(handle);
1225  return;
1226  }
1227  if (ID_REST_STATE_INIT == handle->state)
1228  {
1229  ego_entry = GNUNET_new(struct EgoEntry);
1232  ego_entry->ego = ego;
1233  GNUNET_asprintf(&ego_entry->identifier, "%s", identifier);
1235  handle->ego_tail,
1236  ego_entry);
1237  }
1238 }
1239 
1251 static void
1254  void *proc_cls)
1255 {
1256  struct RequestHandle *handle = GNUNET_new(struct RequestHandle);
1257 
1258  handle->response_code = 0;
1260  handle->proc_cls = proc_cls;
1261  handle->proc = proc;
1262  handle->rest_handle = rest_handle;
1263  handle->data = rest_handle->data;
1264  handle->data_size = rest_handle->data_size;
1265 
1266  handle->url = GNUNET_strdup(rest_handle->url);
1267  if (handle->url[strlen(handle->url) - 1] == '/')
1268  handle->url[strlen(handle->url) - 1] = '\0';
1269  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1270 
1271  handle->identity_handle = GNUNET_IDENTITY_connect(cfg, &init_egos, handle);
1272 
1273  handle->timeout_task =
1274  GNUNET_SCHEDULER_add_delayed(handle->timeout, &do_error, handle);
1275 
1276  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1277 }
1278 
1285 void *
1287 {
1288  static struct Plugin plugin;
1289  struct GNUNET_REST_Plugin *api;
1290 
1291  cfg = cls;
1292  if (NULL != plugin.cfg)
1293  return NULL; /* can only initialize once! */
1294  memset(&plugin, 0, sizeof(struct Plugin));
1295  plugin.cfg = cfg;
1296  api = GNUNET_new(struct GNUNET_REST_Plugin);
1297  api->cls = &plugin;
1301  "%s, %s, %s, %s, %s",
1302  MHD_HTTP_METHOD_GET,
1303  MHD_HTTP_METHOD_POST,
1304  MHD_HTTP_METHOD_PUT,
1305  MHD_HTTP_METHOD_DELETE,
1306  MHD_HTTP_METHOD_OPTIONS);
1307 
1308  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, _("Identity REST API initialized\n"));
1309  return api;
1310 }
1311 
1318 void *
1320 {
1321  struct GNUNET_REST_Plugin *api = cls;
1322  struct Plugin *plugin = api->cls;
1323 
1324  plugin->cfg = NULL;
1325 
1327  GNUNET_free(api);
1328  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Identity REST plugin is finished\n");
1329  return NULL;
1330 }
1331 
1332 /* end of plugin_rest_identity.c */
1333 
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:525
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:775
#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:675
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:629
size_t data_size
the length of the REST data
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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:584
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: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.
#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:46
The request handle.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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:1237
Handle for an ego.
Definition: identity.h:237
#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
char * emsg
Error response message.
const char * url
The url as string.
Handle for the service.
Definition: identity_api.c:94
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:1264
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:835
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:75
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:566
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:83
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:131
#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:722
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:552
#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:956
char * url
The url.