GNUnet  0.20.0
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 "identity.h"
32 #include "gnunet_util_lib.h"
33 #include "microhttpd.h"
34 #include <jansson.h>
35 
39 #define GNUNET_REST_API_NS_IDENTITY "/identity"
40 
44 #define GNUNET_REST_API_NS_IDENTITY_PUBKEY "/identity/pubkey"
45 
49 #define GNUNET_REST_API_NS_IDENTITY_NAME "/identity/name"
50 
54 #define GNUNET_REST_API_NS_SIGN "/sign"
55 
59 #define GNUNET_REST_IDENTITY_PARAM_PUBKEY "pubkey"
60 
64 #define GNUNET_REST_IDENTITY_PARAM_PRIVKEY "privkey"
65 
69 #define GNUNET_REST_IDENTITY_PARAM_NAME "name"
70 
74 #define GNUNET_REST_IDENTITY_PARAM_NEWNAME "newname"
75 
79 #define GNUNET_REST_IDENTITY_MISSING_NAME "Missing identity name"
80 
84 #define GNUNET_REST_IDENTITY_MISSING_PUBKEY "Missing identity public key"
85 
89 #define GNUNET_REST_ERROR_NO_DATA "No data"
90 
94 #define GNUNET_REST_ERROR_DATA_INVALID "Data invalid"
95 
99 #define ID_REST_STATE_INIT 0
100 
104 #define ID_REST_STATE_POST_INIT 1
105 
110 
114 static char *allow_methods;
115 
119 static struct EgoEntry *ego_head;
120 
124 static struct EgoEntry *ego_tail;
125 
129 static int state;
130 
135 
139 struct Plugin
140 {
141  const struct GNUNET_CONFIGURATION_Handle *cfg;
142 };
143 
147 struct EgoEntry
148 {
152  struct EgoEntry *next;
153 
157  struct EgoEntry *prev;
158 
162  char *identifier;
163 
167  char *keystring;
168 
173 };
174 
178 struct RequestHandle
179 {
183  struct RequestHandle *next;
184 
188  struct RequestHandle *prev;
189 
193  const char *data;
194 
198  char *name;
199 
203  size_t data_size;
204 
209 
214 
219 
224 
229 
233  void *proc_cls;
234 
238  char *url;
239 
243  enum GNUNET_ErrorCode ec;
244 };
245 
250 
255 
260 static void
261 cleanup_handle (void *cls)
262 {
263  struct RequestHandle *handle = cls;
264 
265  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
266  if (NULL != handle->timeout_task)
267  {
268  GNUNET_SCHEDULER_cancel (handle->timeout_task);
269  handle->timeout_task = NULL;
270  }
271 
272  if (NULL != handle->url)
273  GNUNET_free (handle->url);
274  if (NULL != handle->name)
275  GNUNET_free (handle->name);
278  handle);
280 }
281 
282 
288 static void
289 do_error (void *cls)
290 {
291  struct RequestHandle *handle = cls;
292  struct MHD_Response *resp;
293  json_t *json_error = json_object ();
294  char *response;
295  int response_code;
296 
297  json_object_set_new (json_error, "error",
298  json_string (GNUNET_ErrorCode_get_hint (handle->ec)));
299  json_object_set_new (json_error, "error_code", json_integer (handle->ec));
300  response_code = GNUNET_ErrorCode_get_http_status (handle->ec);
301  if (0 == response_code)
302  response_code = MHD_HTTP_OK;
303  response = json_dumps (json_error, 0);
305  GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
306  "Content-Type",
307  "application/json"));
308  handle->proc (handle->proc_cls, resp, response_code);
309  json_decref (json_error);
312 }
313 
314 
324 struct EgoEntry *
325 get_egoentry (struct RequestHandle *handle, char *pubkey, char *name)
326 {
327  struct EgoEntry *ego_entry;
328 
329  if (NULL != pubkey)
330  {
331  for (ego_entry = ego_head; NULL != ego_entry;
332  ego_entry = ego_entry->next)
333  {
334  if (0 != strcasecmp (pubkey, ego_entry->keystring))
335  continue;
336  return ego_entry;
337  }
338  }
339  if (NULL != name)
340  {
341  for (ego_entry = ego_head; NULL != ego_entry;
342  ego_entry = ego_entry->next)
343  {
344  if (0 != strcasecmp (name, ego_entry->identifier))
345  continue;
346  return ego_entry;
347  }
348  }
349  return NULL;
350 }
351 
352 
360 void
362  const char *url,
363  void *cls)
364 {
365  struct RequestHandle *handle = cls;
366  struct EgoEntry *ego_entry;
367  struct MHD_Response *resp;
368  struct GNUNET_HashCode key;
369  json_t *json_root;
370  json_t *json_ego;
371  char *result_str;
372  char *privkey_str;
373 
374  json_root = json_array ();
375  // Return ego/egos
376  for (ego_entry = ego_head; NULL != ego_entry;
377  ego_entry = ego_entry->next)
378  {
379  json_ego = json_object ();
380  json_object_set_new (json_ego,
382  json_string (ego_entry->keystring));
383  GNUNET_CRYPTO_hash ("private", strlen ("private"), &key);
384  if (GNUNET_YES ==
386  handle->rest_handle->url_param_map, &key))
387  {
390  json_object_set_new (json_ego,
392  json_string (privkey_str));
393  GNUNET_free (privkey_str);
394  }
395 
396  json_object_set_new (json_ego,
398  json_string (ego_entry->identifier));
399  json_array_append (json_root, json_ego);
400  json_decref (json_ego);
401  }
402 
403  result_str = json_dumps (json_root, 0);
404  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
405  resp = GNUNET_REST_create_response (result_str);
406  GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
407  "Content-Type",
408  "application/json"));
409  json_decref (json_root);
410  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
411  GNUNET_free (result_str);
413 }
414 
415 
422 void
423 ego_get_response (struct RequestHandle *handle, struct EgoEntry *ego_entry)
424 {
425  struct MHD_Response *resp;
426  struct GNUNET_HashCode key;
427  json_t *json_ego;
428  char *result_str;
429  char *privkey_str;
430 
431  json_ego = json_object ();
432  json_object_set_new (json_ego,
434  json_string (ego_entry->keystring));
435  json_object_set_new (json_ego,
437  json_string (ego_entry->identifier));
438  GNUNET_CRYPTO_hash ("private", strlen ("private"), &key);
439  if (GNUNET_YES ==
441  handle->rest_handle->url_param_map, &key))
442  {
445  json_object_set_new (json_ego,
447  json_string (privkey_str));
448  GNUNET_free (privkey_str);
449  }
450 
451  result_str = json_dumps (json_ego, 0);
452  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
453  resp = GNUNET_REST_create_response (result_str);
454  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
455  GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
456  "Content-Type",
457  "application/json"));
458  json_decref (json_ego);
459  GNUNET_free (result_str);
461 }
462 
463 
471 void
473  const char *url,
474  void *cls)
475 {
476  struct RequestHandle *handle = cls;
477  struct EgoEntry *ego_entry;
478  char *keystring;
479 
480  keystring = NULL;
481 
482  if (strlen (GNUNET_REST_API_NS_IDENTITY_PUBKEY) >= strlen (handle->url))
483  {
486  return;
487  }
489  ego_entry = get_egoentry (handle, keystring, NULL);
490 
491  if (NULL == ego_entry)
492  {
495  return;
496  }
497 
498  ego_get_response (handle, ego_entry);
499 }
500 
501 
509 void
511  const char *url,
512  void *cls)
513 {
514  struct RequestHandle *handle = cls;
515  struct EgoEntry *ego_entry;
516  char *egoname;
517 
518  egoname = NULL;
519 
520  if (strlen (GNUNET_REST_API_NS_IDENTITY_NAME) >= strlen (handle->url))
521  {
524  return;
525  }
526  egoname = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_NAME) + 1];
527  ego_entry = get_egoentry (handle, NULL, egoname);
528 
529  if (NULL == ego_entry)
530  {
533  return;
534  }
535 
536  ego_get_response (handle, ego_entry);
537 }
538 
539 
546 static void
547 do_finished (void *cls, enum GNUNET_ErrorCode ec)
548 {
549  struct RequestHandle *handle = cls;
550  struct MHD_Response *resp;
551  int response_code;
552 
553  handle->op = NULL;
554  handle->ec = ec;
555  if (GNUNET_EC_NONE != ec)
556  {
558  return;
559  }
560  if (GNUNET_EC_NONE == handle->ec)
561  response_code = MHD_HTTP_NO_CONTENT;
562  else
563  response_code = GNUNET_ErrorCode_get_http_status (ec);
564  resp = GNUNET_REST_create_response (NULL);
565  handle->proc (handle->proc_cls, resp, response_code);
567 }
568 
569 
577 static void
579  const struct GNUNET_IDENTITY_PrivateKey *pk,
580  enum GNUNET_ErrorCode ec)
581 {
582  struct RequestHandle *handle = cls;
583 
584  (void) pk;
585  do_finished (handle, ec);
586 }
587 
588 
595 void
597 {
598  json_t *data_js;
599  json_error_t err;
600  char *newname;
601  char term_data[handle->data_size + 1];
602  int json_state;
603 
604  // if no data
605  if (0 >= handle->data_size)
606  {
609  return;
610  }
611  // if not json
612  term_data[handle->data_size] = '\0';
613  GNUNET_memcpy (term_data, handle->data, handle->data_size);
614  data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
615 
616  if (NULL == data_js)
617  {
620  return;
621  }
622 
623  newname = NULL;
624  // NEW NAME
625  json_state = 0;
626  json_state = json_unpack (data_js,
627  "{s:s!}",
629  &newname);
630  // Change name with pubkey or name identifier
631  if (0 != json_state)
632  {
635  json_decref (data_js);
636  return;
637  }
638 
639  if (NULL == newname)
640  {
643  json_decref (data_js);
644  return;
645  }
646 
647  if (0 >= strlen (newname))
648  {
651  json_decref (data_js);
652  return;
653  }
654 
657  newname,
658  &do_finished,
659  handle);
660  if (NULL == handle->op)
661  {
664  json_decref (data_js);
665  return;
666  }
667  json_decref (data_js);
668  return;
669 }
670 
671 
679 void
681  const char *url,
682  void *cls)
683 {
684  struct RequestHandle *handle = cls;
685  struct EgoEntry *ego_entry;
686  char *keystring;
687 
688  keystring = NULL;
689 
690  if (strlen (GNUNET_REST_API_NS_IDENTITY_PUBKEY) >= strlen (handle->url))
691  {
694  return;
695  }
697  ego_entry = get_egoentry (handle, keystring, NULL);
698 
699  if (NULL == ego_entry)
700  {
703  return;
704  }
705 
706  ego_edit (handle, ego_entry);
707 }
708 
709 
717 void
719  const char *url,
720  void *cls)
721 {
722  struct RequestHandle *handle = cls;
723  struct EgoEntry *ego_entry;
724  char *name;
725 
726  name = NULL;
727 
728  if (strlen (GNUNET_REST_API_NS_IDENTITY_NAME) >= strlen (handle->url))
729  {
732  return;
733  }
734  name = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_NAME) + 1];
735  ego_entry = get_egoentry (handle, NULL, name);
736 
737  if (NULL == ego_entry)
738  {
741  return;
742  }
743 
744  ego_edit (handle, ego_entry);
745 }
746 
747 
755 void
757  const char *url,
758  void *cls)
759 {
760  struct RequestHandle *handle = cls;
761  json_t *data_js;
762  json_error_t err;
763  char *egoname;
764  char *privkey;
766  struct GNUNET_IDENTITY_PrivateKey *pk_ptr;
767  int json_unpack_state;
768  char term_data[handle->data_size + 1];
769 
770  if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url))
771  {
773  return;
774  }
775 
776  if (0 >= handle->data_size)
777  {
780  return;
781  }
782  term_data[handle->data_size] = '\0';
783  GNUNET_memcpy (term_data, handle->data, handle->data_size);
784  data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
785  if (NULL == data_js)
786  {
789  json_decref (data_js);
790  return;
791  }
792  json_unpack_state = 0;
793  privkey = NULL;
794  json_unpack_state =
795  json_unpack (data_js, "{s:s, s?:s!}",
798  if (0 != json_unpack_state)
799  {
802  json_decref (data_js);
803  return;
804  }
805 
806  if (NULL == egoname)
807  {
810  json_decref (data_js);
811  return;
812  }
813  if (0 >= strlen (egoname))
814  {
816  json_decref (data_js);
818  return;
819  }
821  handle->name = GNUNET_strdup (egoname);
822  if (NULL != privkey)
823  {
825  strlen (privkey),
826  &pk,
827  sizeof(struct
829  pk_ptr = &pk;
830  }
831  else
832  pk_ptr = NULL;
833  json_decref (data_js);
835  handle->name,
836  pk_ptr,
839  handle);
840 }
841 
842 
850 void
852  const char *url,
853  void *cls)
854 {
855  struct RequestHandle *handle = cls;
856  struct EgoEntry *ego_entry;
857  char *keystring;
858 
859  keystring = NULL;
860 
861  if (strlen (GNUNET_REST_API_NS_IDENTITY_PUBKEY) >= strlen (handle->url))
862  {
865  return;
866  }
868  ego_entry = get_egoentry (handle, keystring, NULL);
869 
870  if (NULL == ego_entry)
871  {
874  return;
875  }
876 
878  ego_entry->identifier,
879  &do_finished,
880  handle);
881 }
882 
883 
891 void
893  const char *url,
894  void *cls)
895 {
896  struct RequestHandle *handle = cls;
897  struct EgoEntry *ego_entry;
898  char *name;
899 
900  name = NULL;
901 
902  if (strlen (GNUNET_REST_API_NS_IDENTITY_NAME) >= strlen (handle->url))
903  {
906  return;
907  }
908  name = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY_NAME) + 1];
909  ego_entry = get_egoentry (handle, NULL, name);
910 
911  if (NULL == ego_entry)
912  {
915  return;
916  }
917 
919  ego_entry->identifier,
920  &do_finished,
921  handle);
922 }
923 
925 {
926  void *data;
928 };
929 
930 void
931 ego_sign_data_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
932 {
933  struct RequestHandle *handle = ((struct ego_sign_data_cls *) cls)->handle;
934  unsigned char *data
935  = (unsigned char *) ((struct ego_sign_data_cls *) cls)->data; // data is url decoded
936  struct MHD_Response *resp;
937  struct GNUNET_CRYPTO_EddsaSignature sig;
938  char *sig_str;
939  char *result;
940 
941  if (ego == NULL)
942  {
945  return;
946  }
947 
948  if (ntohl (ego->pk.type) != GNUNET_IDENTITY_TYPE_EDDSA)
949  {
952  return;
953  }
954 
956  (void *) data,
957  strlen ( (char*) data),
958  &sig))
959  {
962  return;
963  }
964 
966  sizeof (struct GNUNET_CRYPTO_EddsaSignature),
967  &sig_str);
968 
970  "{\"signature\": \"%s\"}",
971  sig_str);
972 
974  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
975 
976  free (data);
977  free (sig_str);
978  free (result);
979  free (cls);
981 }
982 
989 void
991  const char *url,
992  void *cls)
993 {
994  // TODO: replace with precompiler #define
995  const char *username_key = "user";
996  const char *data_key = "data";
997 
998  struct RequestHandle *handle = cls;
999  struct GNUNET_HashCode cache_key_username;
1000  struct GNUNET_HashCode cache_key_data;
1001  char *username;
1002  char *data;
1003 
1004  struct ego_sign_data_cls *cls2;
1005 
1006  GNUNET_CRYPTO_hash (username_key, strlen (username_key), &cache_key_username);
1007  GNUNET_CRYPTO_hash (data_key, strlen (data_key), &cache_key_data);
1008 
1010  handle->rest_handle->url_param_map,
1011  &cache_key_username)) ||
1013  handle->rest_handle->url_param_map,
1014  &cache_key_data)))
1015  {
1016  handle->ec = GNUNET_EC_UNKNOWN;
1018  return;
1019  }
1020 
1021  username = (char *) GNUNET_CONTAINER_multihashmap_get (
1022  handle->rest_handle->url_param_map,
1023  &cache_key_username);
1024 
1026  handle->rest_handle->url_param_map,
1027  &cache_key_data);
1028 
1029  cls2 = malloc (sizeof(struct ego_sign_data_cls));
1030  cls2->data = (void *) GNUNET_strdup (data);
1031  cls2->handle = handle;
1032 
1034  username,
1036  cls2);
1037 }
1038 
1046 static void
1048  const char *url,
1049  void *cls)
1050 {
1051  struct MHD_Response *resp;
1052  struct RequestHandle *handle = cls;
1053 
1054  // For now, independent of path return all options
1055  resp = GNUNET_REST_create_response (NULL);
1056  GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
1057  "Access-Control-Allow-Methods",
1058  allow_methods));
1059  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1061  return;
1062 }
1063 
1064 
1065 static void
1066 list_ego (void *cls,
1067  struct GNUNET_IDENTITY_Ego *ego,
1068  void **ctx,
1069  const char *identifier)
1070 {
1071  struct EgoEntry *ego_entry;
1073 
1074  if ((NULL == ego) && (ID_REST_STATE_INIT == state))
1075  {
1077  return;
1078  }
1079  if (NULL == ego)
1080  {
1082  "Called with NULL ego\n");
1083  return;
1084  }
1085  if (ID_REST_STATE_INIT == state)
1086  {
1087  ego_entry = GNUNET_new (struct EgoEntry);
1090  ego_entry->ego = ego;
1091  ego_entry->identifier = GNUNET_strdup (identifier);
1093  ego_tail,
1094  ego_entry);
1095  }
1096  /* Ego renamed or added */
1097  if (identifier != NULL)
1098  {
1099  for (ego_entry = ego_head; NULL != ego_entry;
1100  ego_entry = ego_entry->next)
1101  {
1102  if (ego_entry->ego == ego)
1103  {
1104  /* Rename */
1105  GNUNET_free (ego_entry->identifier);
1106  ego_entry->identifier = GNUNET_strdup (identifier);
1107  break;
1108  }
1109  }
1110  if (NULL == ego_entry)
1111  {
1112  /* Add */
1113  ego_entry = GNUNET_new (struct EgoEntry);
1116  ego_entry->ego = ego;
1117  ego_entry->identifier = GNUNET_strdup (identifier);
1119  ego_tail,
1120  ego_entry);
1121  }
1122  }
1123  else
1124  {
1125  /* Delete */
1126  for (ego_entry = ego_head; NULL != ego_entry;
1127  ego_entry = ego_entry->next)
1128  {
1129  if (ego_entry->ego == ego)
1130  break;
1131  }
1132  if (NULL == ego_entry)
1133  return; /* Not found */
1134 
1136  ego_tail,
1137  ego_entry);
1138  GNUNET_free (ego_entry->identifier);
1139  GNUNET_free (ego_entry->keystring);
1140  GNUNET_free (ego_entry);
1141  return;
1142  }
1143 
1144 }
1145 
1146 
1158 static enum GNUNET_GenericReturnValue
1159 rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1161  void *proc_cls)
1162 {
1163  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1165  static const struct GNUNET_REST_RequestHandler handlers[] =
1166  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY,
1167  &ego_get_pubkey },
1168  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name },
1169  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all },
1170  { MHD_HTTP_METHOD_PUT,
1172  &ego_edit_pubkey },
1173  { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name },
1174  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create },
1175  { MHD_HTTP_METHOD_DELETE,
1177  &ego_delete_pubkey },
1178  { MHD_HTTP_METHOD_DELETE,
1180  &ego_delete_name },
1181  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont },
1182  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_SIGN, &ego_sign_data},
1184 
1185 
1187  handle->proc_cls = proc_cls;
1188  handle->proc = proc;
1189  handle->rest_handle = rest_handle;
1190  handle->data = rest_handle->data;
1191  handle->data_size = rest_handle->data_size;
1192 
1193  handle->url = GNUNET_strdup (rest_handle->url);
1194  if (handle->url[strlen (handle->url) - 1] == '/')
1195  handle->url[strlen (handle->url) - 1] = '\0';
1196  handle->timeout_task =
1199  requests_tail,
1200  handle);
1201  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1202  if (GNUNET_NO ==
1203  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
1204  {
1206  return GNUNET_NO;
1207  }
1208 
1209  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1210  return GNUNET_YES;
1211 }
1212 
1213 
1220 void *
1222 {
1223  static struct Plugin plugin;
1224  struct GNUNET_REST_Plugin *api;
1225 
1226  cfg = cls;
1227  if (NULL != plugin.cfg)
1228  return NULL; /* can only initialize once! */
1229  memset (&plugin, 0, sizeof(struct Plugin));
1230  plugin.cfg = cfg;
1231  api = GNUNET_new (struct GNUNET_REST_Plugin);
1232  api->cls = &plugin;
1236  "%s, %s, %s, %s, %s",
1237  MHD_HTTP_METHOD_GET,
1238  MHD_HTTP_METHOD_POST,
1239  MHD_HTTP_METHOD_PUT,
1240  MHD_HTTP_METHOD_DELETE,
1241  MHD_HTTP_METHOD_OPTIONS);
1244 
1245  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity REST API initialized\n"));
1246  return api;
1247 }
1248 
1249 
1256 void *
1258 {
1259  struct GNUNET_REST_Plugin *api = cls;
1260  struct Plugin *plugin = api->cls;
1261  struct EgoEntry *ego_entry;
1262  struct EgoEntry *ego_tmp;
1263 
1264  plugin->cfg = NULL;
1265  while (NULL != requests_head)
1267  if (NULL != identity_handle)
1269 
1270  for (ego_entry = ego_head; NULL != ego_entry;)
1271  {
1272  ego_tmp = ego_entry;
1273  ego_entry = ego_entry->next;
1274  GNUNET_free (ego_tmp->identifier);
1275  GNUNET_free (ego_tmp->keystring);
1276  GNUNET_free (ego_tmp);
1277  }
1278 
1280  GNUNET_free (api);
1281  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Identity REST plugin is finished\n");
1282  return NULL;
1283 }
1284 
1285 
1286 /* end of plugin_rest_identity.c */
const char * GNUNET_ErrorCode_get_hint(enum GNUNET_ErrorCode ec)
Returns a hint for a given error code.
unsigned int GNUNET_ErrorCode_get_http_status(enum GNUNET_ErrorCode ec)
Return HTTP status for a given error code.
GNUNET_ErrorCode
Taler error codes.
@ GNUNET_EC_IDENTITY_NOT_FOUND
Ego not found.
@ GNUNET_EC_UNKNOWN
Unknown and unspecified error.
@ GNUNET_EC_NONE
No error (success).
@ GNUNET_EC_IDENTITY_INVALID
The given ego is invalid or malformed.
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
struct TestcasePlugin * plugin
The process handle to the testbed service.
static struct MHD_Response * response
Our canonical response.
struct GNUNET_HashCode key
The key used in the DHT.
static char * egoname
Ego Attribut String.
Definition: gnunet-did.c:96
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
uint32_t data
The data value.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
static struct GNUNET_IDENTITY_PublicKey pubkey
Public key of the zone to look in.
static int result
Global testing status.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
Identity service; implements identity management for GNUnet.
API for helper library to parse/create REST.
GNUnet service REST plugin header.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
const struct GNUNET_IDENTITY_PrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:560
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:646
char * GNUNET_IDENTITY_private_key_to_string(const struct GNUNET_IDENTITY_PrivateKey *key)
Creates a (Base32) string representation of the private key.
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_create(struct GNUNET_IDENTITY_Handle *h, const char *name, const struct GNUNET_IDENTITY_PrivateKey *privkey, enum GNUNET_IDENTITY_KeyType ktype, GNUNET_IDENTITY_CreateContinuation cont, void *cont_cls)
Create a new ego with the given name.
Definition: identity_api.c:586
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_IDENTITY_PublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:573
char * GNUNET_IDENTITY_public_key_to_string(const struct GNUNET_IDENTITY_PublicKey *key)
Creates a (Base32) string representation of the public key.
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:531
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:757
struct GNUNET_IDENTITY_EgoLookup * GNUNET_IDENTITY_ego_lookup(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *name, GNUNET_IDENTITY_EgoCallback cb, void *cb_cls)
Lookup an ego by name.
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:699
@ GNUNET_IDENTITY_TYPE_ECDSA
The identity type.
@ GNUNET_IDENTITY_TYPE_EDDSA
EDDSA identity.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_raw(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, void *data, size_t size, struct GNUNET_CRYPTO_EddsaSignature *sig)
Definition: crypto_ecc.c:586
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:44
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:64
void(* GNUNET_REST_ResultProcessor)(void *cls, struct MHD_Response *resp, int status)
Iterator called on obtained result for a REST result.
#define GNUNET_REST_HANDLER_END
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:1299
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:1272
enum GNUNET_GenericReturnValue 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:788
size_t GNUNET_STRINGS_base64url_encode(const void *in, size_t len, char **output)
Encode into Base64url.
Definition: strings.c:1656
enum GNUNET_GenericReturnValue GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
Convert the utf-8 input string to lower case.
Definition: strings.c:449
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
@ MHD_HTTP_OK
OK [RFC7231, Section 6.3.1].
@ MHD_HTTP_NO_CONTENT
No Content [RFC7231, Section 6.3.5].
Common type definitions for the identity service and API.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
const char * name
static struct EgoEntry * ego_tail
Ego list.
#define GNUNET_REST_IDENTITY_PARAM_NAME
Parameter name.
void ego_get_pubkey(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity GET request with a public key.
void ego_sign_data(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
#define GNUNET_REST_API_NS_IDENTITY
Identity Namespace.
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_delete_pubkey(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity DELETE request with public key.
static void do_finished(void *cls, enum GNUNET_ErrorCode ec)
Processing finished.
#define GNUNET_REST_IDENTITY_PARAM_PRIVKEY
Parameter private key.
void * libgnunet_plugin_rest_identity_done(void *cls)
Exit point from the plugin.
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
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_INIT
State while collecting all egos.
void * libgnunet_plugin_rest_identity_init(void *cls)
Entry point for the plugin.
static struct RequestHandle * requests_head
DLL.
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
static enum GNUNET_GenericReturnValue rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
static void do_finished_create(void *cls, const struct GNUNET_IDENTITY_PrivateKey *pk, enum GNUNET_ErrorCode ec)
Processing finished, when creating an ego.
#define GNUNET_REST_API_NS_SIGN
Identity Namespace with sign specifier.
static int state
The processing state.
static struct EgoEntry * ego_head
Ego list.
#define GNUNET_REST_API_NS_IDENTITY_NAME
Identity Namespace with public key specifier.
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,...
static void list_ego(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
static char * allow_methods
HTTP methods allows for this plugin.
void ego_edit(struct RequestHandle *handle, struct EgoEntry *ego_entry)
Processing edit ego with EgoEntry ego_entry.
void ego_delete_name(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity DELETE request with name.
static struct RequestHandle * requests_tail
DLL.
#define GNUNET_REST_IDENTITY_PARAM_NEWNAME
Parameter new name.
void ego_get_name(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity GET request with a name.
static struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
void ego_get_response(struct RequestHandle *handle, struct EgoEntry *ego_entry)
Responds with the ego_entry identity.
void ego_edit_pubkey(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity PUT request with public key.
void ego_sign_data_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego)
#define ID_REST_STATE_POST_INIT
Done collecting egos.
#define GNUNET_REST_API_NS_IDENTITY_PUBKEY
Identity Namespace with public key specifier.
#define GNUNET_REST_IDENTITY_PARAM_PUBKEY
Parameter public key.
void ego_create(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle identity POST request.
static void do_error(void *cls)
Task run on errors.
static void cleanup_handle(void *cls)
Cleanup lookup handle.
The ego list.
char * identifier
Ego Identifier.
struct EgoEntry * prev
DLL.
char * keystring
Public key string.
struct EgoEntry * next
DLL.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
void * cls
Closure for all of the callbacks.
an ECC signature using EdDSA.
A 512-bit hashcode.
Handle for an ego.
Definition: identity.h:37
struct GNUNET_IDENTITY_PrivateKey pk
The identity key pair.
Definition: identity.h:51
Handle for the service.
Definition: identity_api.c:97
Handle for an operation with the identity service.
Definition: identity_api.c:41
A private key for an identity as per LSD0001.
uint32_t type
Type of public key.
struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_key
AN EdDSA identtiy key.
An identity key as per LSD0001.
struct returned by the initialization function of the plugin
char * name
Plugin name.
void * cls
The closure of the plugin.
enum GNUNET_GenericReturnValue(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
const char * data
The POST data.
const char * url
The url as string.
size_t data_size
The POST data size.
void(* proc)(struct GNUNET_REST_RequestHandle *handle, const char *url, void *cls)
Namespace to handle.
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for relative time used by GNUnet, in microseconds.
Handle for a plugin.
Definition: block.c:38
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
The request handle.
enum GNUNET_ErrorCode ec
Error code.
struct GNUNET_IDENTITY_Operation * op
IDENTITY Operation.
struct RequestHandle * prev
DLL.
size_t data_size
the length of the REST data
struct EgoEntry * ego_entry
IDENTITY Operation.
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
void * proc_cls
The closure of the result processor.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
struct RequestHandle * next
DLL.
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
char * name
Name to look up.
char * url
The url.
const char * data
The data from the REST request.
struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
struct RequestHandle * handle