GNUnet  0.11.x
gnunet-service-identity.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2013 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  */
20 
33 #include "platform.h"
34 #include "gnunet_util_lib.h"
35 #include "gnunet_constants.h"
36 #include "gnunet_protocols.h"
39 #include "identity.h"
40 
41 
45 struct Ego
46 {
50  struct Ego *next;
51 
55  struct Ego *prev;
56 
61 
65  char *identifier;
66 };
67 
68 
72 static const struct GNUNET_CONFIGURATION_Handle *cfg;
73 
79 
84 
89 
93 static char *ego_directory;
94 
98 static char *subsystem_cfg_file;
99 
103 static struct Ego *ego_head;
104 
108 static struct Ego *ego_tail;
109 
110 
117 static char *
118 get_ego_filename (struct Ego *ego)
119 {
120  char *filename;
121 
122  GNUNET_asprintf (&filename,
123  "%s%s%s",
126  ego->identifier);
127  return filename;
128 }
129 
130 
138 static void
140  struct GNUNET_SERVICE_Client *client,
141  void *app_ctx)
142 {
143  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
144 }
145 
146 
155 static void *
156 client_connect_cb (void *cls,
157  struct GNUNET_SERVICE_Client *client,
158  struct GNUNET_MQ_Handle *mq)
159 {
160  return client;
161 }
162 
163 
169 static void
170 shutdown_task (void *cls)
171 {
172  struct Ego *e;
173 
174  if (NULL != nc)
175  {
177  nc = NULL;
178  }
179  if (NULL != stats)
180  {
182  stats = NULL;
183  }
184  GNUNET_CONFIGURATION_destroy (subsystem_cfg);
185  subsystem_cfg = NULL;
187  subsystem_cfg_file = NULL;
189  ego_directory = NULL;
190  while (NULL != (e = ego_head))
191  {
192  GNUNET_CONTAINER_DLL_remove (ego_head, ego_tail, e);
193  GNUNET_free (e->pk);
194  GNUNET_free (e->identifier);
195  GNUNET_free (e);
196  }
197 }
198 
199 
207 static void
209  uint32_t result_code,
210  const char *emsg)
211 {
212  struct ResultCodeMessage *rcm;
213  struct GNUNET_MQ_Envelope *env;
214  size_t elen;
215 
216  if (NULL == emsg)
217  elen = 0;
218  else
219  elen = strlen (emsg) + 1;
220  env =
222  rcm->result_code = htonl (result_code);
223  if (0 < elen)
224  GNUNET_memcpy (&rcm[1], emsg, elen);
226  "Sending result %d (%s) to client\n",
227  (int) result_code,
228  emsg);
230 }
231 
232 
239 static struct GNUNET_MQ_Envelope *
241 {
242  struct UpdateMessage *um;
243  struct GNUNET_MQ_Envelope *env;
244  size_t name_len;
245 
246  name_len = (NULL == ego->identifier) ? 0 : (strlen (ego->identifier) + 1);
248  um->name_len = htons (name_len);
249  um->end_of_list = htons (GNUNET_NO);
250  um->private_key = *ego->pk;
251  GNUNET_memcpy (&um[1], ego->identifier, name_len);
252  return env;
253 }
254 
255 
263 static struct GNUNET_MQ_Envelope *
264 create_set_default_message (struct Ego *ego, const char *servicename)
265 {
266  struct SetDefaultMessage *sdm;
267  struct GNUNET_MQ_Envelope *env;
268  size_t name_len;
269 
270  name_len = (NULL == servicename) ? 0 : (strlen (servicename) + 1);
271  env = GNUNET_MQ_msg_extra (sdm,
272  name_len,
274  sdm->name_len = htons (name_len);
275  sdm->reserved = htons (0);
276  sdm->private_key = *ego->pk;
277  GNUNET_memcpy (&sdm[1], servicename, name_len);
278  return env;
279 }
280 
281 
291 static void
292 handle_start_message (void *cls, const struct GNUNET_MessageHeader *message)
293 {
294  struct GNUNET_SERVICE_Client *client = cls;
295  struct UpdateMessage *ume;
296  struct GNUNET_MQ_Envelope *env;
297  struct Ego *ego;
298 
299  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n");
303  for (ego = ego_head; NULL != ego; ego = ego->next)
304  {
305  env = create_update_message (ego);
307  }
309  ume->end_of_list = htons (GNUNET_YES);
310  ume->name_len = htons (0);
313 }
314 
315 
324 static int
325 check_lookup_message (void *cls, const struct LookupMessage *message)
326 {
328  return GNUNET_OK;
329 }
330 
331 
339 static void
340 handle_lookup_message (void *cls, const struct LookupMessage *message)
341 {
342  struct GNUNET_SERVICE_Client *client = cls;
343  const char *name;
344  struct GNUNET_MQ_Envelope *env;
345  struct Ego *ego;
346 
347  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received LOOKUP message from client\n");
348  name = (const char *) &message[1];
349  for (ego = ego_head; NULL != ego; ego = ego->next)
350  {
351  if (0 != strcasecmp (name, ego->identifier))
352  continue;
353  env = create_update_message (ego);
356  return;
357  }
358  send_result_code (client, 0, "ego not found");
360 }
361 
362 
371 static int
372 check_lookup_by_suffix_message (void *cls, const struct LookupMessage *message)
373 {
375  return GNUNET_OK;
376 }
377 
378 
386 static void
387 handle_lookup_by_suffix_message (void *cls, const struct LookupMessage *message)
388 {
389  struct GNUNET_SERVICE_Client *client = cls;
390  const char *name;
391  struct GNUNET_MQ_Envelope *env;
392  struct Ego *lprefix;
393 
395  "Received LOOKUP_BY_SUFFIX message from client\n");
396  name = (const char *) &message[1];
397  lprefix = NULL;
398  for (struct Ego *ego = ego_head; NULL != ego; ego = ego->next)
399  {
400  if ((strlen (ego->identifier) <= strlen (name)) &&
401  (0 == strcmp (ego->identifier,
402  &name[strlen (name) - strlen (ego->identifier)])) &&
403  ((strlen (name) == strlen (ego->identifier)) ||
404  ('.' == name[strlen (name) - strlen (ego->identifier) - 1])) &&
405  ((NULL == lprefix) ||
406  (strlen (ego->identifier) > strlen (lprefix->identifier))))
407  {
408  /* found better match, update! */
409  lprefix = ego;
410  }
411  }
412  if (NULL != lprefix)
413  {
414  env = create_update_message (lprefix);
417  return;
418  }
419  send_result_code (client, 0, "ego not found");
421 }
422 
423 
431 static int
433 {
434  uint16_t size;
435  uint16_t name_len;
436  const char *name;
437 
438  size = ntohs (msg->header.size);
439  if (size <= sizeof(struct GetDefaultMessage))
440  {
441  GNUNET_break (0);
442  return GNUNET_SYSERR;
443  }
444  name = (const char *) &msg[1];
445  name_len = ntohs (msg->name_len);
446  if ((name_len + sizeof(struct GetDefaultMessage) != size) ||
447  (0 != ntohs (msg->reserved)) || ('\0' != name[name_len - 1]))
448  {
449  GNUNET_break (0);
450  return GNUNET_SYSERR;
451  }
452  return GNUNET_OK;
453 }
454 
455 
464 static void
465 handle_get_default_message (void *cls, const struct GetDefaultMessage *gdm)
466 {
467  struct GNUNET_MQ_Envelope *env;
468  struct GNUNET_SERVICE_Client *client = cls;
469  struct Ego *ego;
470  char *name;
471  char *identifier;
472 
473 
474  name = GNUNET_strdup ((const char *) &gdm[1]);
475  GNUNET_STRINGS_utf8_tolower ((const char *) &gdm[1], name);
477  "Received GET_DEFAULT for service `%s' from client\n",
478  name);
479  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg,
480  name,
481  "DEFAULT_IDENTIFIER",
482  &identifier))
483  {
484  send_result_code (client, 1, gettext_noop ("no default known"));
486  GNUNET_free (name);
487  return;
488  }
489  for (ego = ego_head; NULL != ego; ego = ego->next)
490  {
491  if (0 == strcmp (ego->identifier, identifier))
492  {
493  env = create_set_default_message (ego, name);
496  GNUNET_free (identifier);
497  GNUNET_free (name);
498  return;
499  }
500  }
501  GNUNET_free (identifier);
502  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to find ego `%s'\n", name);
503  GNUNET_free (name);
504  send_result_code (client,
505  1,
506  gettext_noop (
507  "default configured, but ego unknown (internal error)"));
509 }
510 
511 
519 static int
521  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk2)
522 {
523  return GNUNET_memcmp (pk1, pk2);
524 }
525 
526 
534 static int
536 {
537  uint16_t size;
538  uint16_t name_len;
539  const char *str;
540 
541  size = ntohs (msg->header.size);
542  if (size <= sizeof(struct SetDefaultMessage))
543  {
544  GNUNET_break (0);
545  return GNUNET_SYSERR;
546  }
547  name_len = ntohs (msg->name_len);
548  GNUNET_break (0 == ntohs (msg->reserved));
549  if (name_len + sizeof(struct SetDefaultMessage) != size)
550  {
551  GNUNET_break (0);
552  return GNUNET_SYSERR;
553  }
554  str = (const char *) &msg[1];
555  if ('\0' != str[name_len - 1])
556  {
557  GNUNET_break (0);
558  return GNUNET_SYSERR;
559  }
560  return GNUNET_OK;
561 }
562 
563 
572 static void
573 handle_set_default_message (void *cls, const struct SetDefaultMessage *sdm)
574 {
575  struct Ego *ego;
576  struct GNUNET_SERVICE_Client *client = cls;
577  char *str;
578 
579  str = GNUNET_strdup ((const char *) &sdm[1]);
580  GNUNET_STRINGS_utf8_tolower ((const char *) &sdm[1], str);
581 
583  "Received SET_DEFAULT for service `%s' from client\n",
584  str);
585  for (ego = ego_head; NULL != ego; ego = ego->next)
586  {
587  if (0 == key_cmp (ego->pk, &sdm->private_key))
588  {
590  str,
591  "DEFAULT_IDENTIFIER",
592  ego->identifier);
593  if (GNUNET_OK !=
595  GNUNET_log (
597  _ ("Failed to write subsystem default identifier map to `%s'.\n"),
599  send_result_code (client, 0, NULL);
601  GNUNET_free (str);
602  return;
603  }
604  }
605  send_result_code (client,
606  1,
607  _ ("Unknown ego specified for service (internal error)"));
608  GNUNET_free (str);
610 }
611 
612 
618 static void
619 notify_listeners (struct Ego *ego)
620 {
621  struct UpdateMessage *um;
622  size_t name_len;
623 
624  name_len = (NULL == ego->identifier) ? 0 : (strlen (ego->identifier) + 1);
625  um = GNUNET_malloc (sizeof(struct UpdateMessage) + name_len);
627  um->header.size = htons (sizeof(struct UpdateMessage) + name_len);
628  um->name_len = htons (name_len);
629  um->end_of_list = htons (GNUNET_NO);
630  um->private_key = *ego->pk;
631  GNUNET_memcpy (&um[1], ego->identifier, name_len);
633  GNUNET_free (um);
634 }
635 
636 
644 static int
646 {
647  uint16_t size;
648  uint16_t name_len;
649  const char *str;
650 
651  size = ntohs (msg->header.size);
652  if (size <= sizeof(struct CreateRequestMessage))
653  {
654  GNUNET_break (0);
655  return GNUNET_SYSERR;
656  }
657  name_len = ntohs (msg->name_len);
658  GNUNET_break (0 == ntohs (msg->reserved));
659  if (name_len + sizeof(struct CreateRequestMessage) != size)
660  {
661  GNUNET_break (0);
662  return GNUNET_SYSERR;
663  }
664  str = (const char *) &msg[1];
665  if ('\0' != str[name_len - 1])
666  {
667  GNUNET_break (0);
668  return GNUNET_SYSERR;
669  }
670  return GNUNET_OK;
671 }
672 
673 
682 static void
683 handle_create_message (void *cls, const struct CreateRequestMessage *crm)
684 {
685  struct GNUNET_SERVICE_Client *client = cls;
686  struct Ego *ego;
687  char *str;
688  char *fn;
689 
690  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CREATE message from client\n");
691  str = GNUNET_strdup ((const char *) &crm[1]);
692  GNUNET_STRINGS_utf8_tolower ((const char *) &crm[1], str);
693  for (ego = ego_head; NULL != ego; ego = ego->next)
694  {
695  if (0 == strcmp (ego->identifier, str))
696  {
697  send_result_code (client,
698  1,
699  gettext_noop (
700  "identifier already in use for another ego"));
702  GNUNET_free (str);
703  return;
704  }
705  }
706  ego = GNUNET_new (struct Ego);
708  *ego->pk = crm->private_key;
709  ego->identifier = GNUNET_strdup (str);
710  GNUNET_CONTAINER_DLL_insert (ego_head, ego_tail, ego);
711  send_result_code (client, 0, NULL);
712  fn = get_ego_filename (ego);
714  if (sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey) !=
716  &crm->private_key,
717  sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey),
721  GNUNET_free (fn);
722  GNUNET_free (str);
723  notify_listeners (ego);
725 }
726 
727 
732 {
736  const char *old_name;
737 
741  const char *new_name;
742 };
743 
751 static void
752 handle_ego_rename (void *cls, const char *section)
753 {
754  struct RenameContext *rc = cls;
755  char *id;
756 
757  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg,
758  section,
759  "DEFAULT_IDENTIFIER",
760  &id))
761  return;
762  if (0 != strcmp (id, rc->old_name))
763  {
764  GNUNET_free (id);
765  return;
766  }
768  section,
769  "DEFAULT_IDENTIFIER",
770  rc->new_name);
771  GNUNET_free (id);
772 }
773 
774 
782 static int
783 check_rename_message (void *cls, const struct RenameMessage *msg)
784 {
785  uint16_t size;
786  uint16_t old_name_len;
787  uint16_t new_name_len;
788  const char *old_name;
789  const char *new_name;
790 
791  size = ntohs (msg->header.size);
792  if (size <= sizeof(struct RenameMessage))
793  {
794  GNUNET_break (0);
795  return GNUNET_SYSERR;
796  }
797  old_name_len = ntohs (msg->old_name_len);
798  new_name_len = ntohs (msg->new_name_len);
799  old_name = (const char *) &msg[1];
800  new_name = &old_name[old_name_len];
801  if ((old_name_len + new_name_len + sizeof(struct RenameMessage) != size) ||
802  ('\0' != old_name[old_name_len - 1]) ||
803  ('\0' != new_name[new_name_len - 1]))
804  {
805  GNUNET_break (0);
806  return GNUNET_SYSERR;
807  }
808 
809  return GNUNET_OK;
810 }
811 
812 
821 static void
822 handle_rename_message (void *cls, const struct RenameMessage *rm)
823 {
824  uint16_t old_name_len;
825  struct Ego *ego;
826  char *old_name;
827  char *new_name;
828  struct RenameContext rename_ctx;
829  struct GNUNET_SERVICE_Client *client = cls;
830  char *fn_old;
831  char *fn_new;
832  const char *old_name_tmp;
833 
834  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received RENAME message from client\n");
835  old_name_len = ntohs (rm->old_name_len);
836  old_name_tmp = (const char *) &rm[1];
837  old_name = GNUNET_strdup (old_name_tmp);
838  GNUNET_STRINGS_utf8_tolower (old_name_tmp, old_name);
839  new_name = GNUNET_strdup (&old_name_tmp[old_name_len]);
840  GNUNET_STRINGS_utf8_tolower (&old_name_tmp[old_name_len], new_name);
841 
842  /* check if new name is already in use */
843  for (ego = ego_head; NULL != ego; ego = ego->next)
844  {
845  if (0 == strcmp (ego->identifier, new_name))
846  {
847  send_result_code (client, 1, gettext_noop ("target name already exists"));
849  GNUNET_free (old_name);
850  GNUNET_free (new_name);
851  return;
852  }
853  }
854 
855  /* locate old name and, if found, perform rename */
856  for (ego = ego_head; NULL != ego; ego = ego->next)
857  {
858  if (0 == strcmp (ego->identifier, old_name))
859  {
860  fn_old = get_ego_filename (ego);
861  GNUNET_free (ego->identifier);
862  rename_ctx.old_name = old_name;
863  rename_ctx.new_name = new_name;
866  &rename_ctx);
867  if (GNUNET_OK !=
869  GNUNET_log (
871  _ ("Failed to write subsystem default identifier map to `%s'.\n"),
873  ego->identifier = GNUNET_strdup (new_name);
874  fn_new = get_ego_filename (ego);
875  if (0 != rename (fn_old, fn_new))
877  GNUNET_free (fn_old);
878  GNUNET_free (fn_new);
879  GNUNET_free (old_name);
880  GNUNET_free (new_name);
881  notify_listeners (ego);
882  send_result_code (client, 0, NULL);
884  return;
885  }
886  }
887 
888  /* failed to locate old name */
889  send_result_code (client, 1, gettext_noop ("no matching ego found"));
890  GNUNET_free (old_name);
891  GNUNET_free (new_name);
893 }
894 
895 
903 static void
904 handle_ego_delete (void *cls, const char *section)
905 {
906  const char *identifier = cls;
907  char *id;
908 
909  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg,
910  section,
911  "DEFAULT_IDENTIFIER",
912  &id))
913  return;
914  if (0 != strcmp (id, identifier))
915  {
916  GNUNET_free (id);
917  return;
918  }
920  section,
921  "DEFAULT_IDENTIFIER",
922  NULL);
923  GNUNET_free (id);
924 }
925 
926 
934 static int
935 check_delete_message (void *cls, const struct DeleteMessage *msg)
936 {
937  uint16_t size;
938  uint16_t name_len;
939  const char *name;
940 
941  size = ntohs (msg->header.size);
942  if (size <= sizeof(struct DeleteMessage))
943  {
944  GNUNET_break (0);
945  return GNUNET_SYSERR;
946  }
947  name = (const char *) &msg[1];
948  name_len = ntohs (msg->name_len);
949  if ((name_len + sizeof(struct DeleteMessage) != size) ||
950  (0 != ntohs (msg->reserved)) || ('\0' != name[name_len - 1]))
951  {
952  GNUNET_break (0);
953  return GNUNET_SYSERR;
954  }
955  return GNUNET_OK;
956 }
957 
958 
967 static void
968 handle_delete_message (void *cls, const struct DeleteMessage *dm)
969 {
970  struct Ego *ego;
971  char *name;
972  char *fn;
973  struct GNUNET_SERVICE_Client *client = cls;
974 
975  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received DELETE message from client\n");
976  name = GNUNET_strdup ((const char *) &dm[1]);
977  GNUNET_STRINGS_utf8_tolower ((const char *) &dm[1], name);
978 
979  for (ego = ego_head; NULL != ego; ego = ego->next)
980  {
981  if (0 == strcmp (ego->identifier, name))
982  {
983  GNUNET_CONTAINER_DLL_remove (ego_head, ego_tail, ego);
986  ego->identifier);
987  if (GNUNET_OK !=
989  GNUNET_log (
991  _ ("Failed to write subsystem default identifier map to `%s'.\n"),
993  fn = get_ego_filename (ego);
994  if (0 != unlink (fn))
996  GNUNET_free (fn);
997  GNUNET_free (ego->identifier);
998  ego->identifier = NULL;
999  notify_listeners (ego);
1000  GNUNET_free (ego->pk);
1001  GNUNET_free (ego);
1002  GNUNET_free (name);
1003  send_result_code (client, 0, NULL);
1005  return;
1006  }
1007  }
1008 
1009  send_result_code (client, 1, gettext_noop ("no matching ego found"));
1010  GNUNET_free (name);
1012 }
1013 
1014 
1025 static int
1026 process_ego_file (void *cls, const char *filename)
1027 {
1028  struct Ego *ego;
1029  const char *fn;
1030 
1031  fn = strrchr (filename, (int) DIR_SEPARATOR);
1032  if (NULL == fn)
1033  {
1034  GNUNET_break (0);
1035  return GNUNET_OK;
1036  }
1037  ego = GNUNET_new (struct Ego);
1038  ego->pk = GNUNET_CRYPTO_ecdsa_key_create_from_file (filename);
1039  if (NULL == ego->pk)
1040  {
1041  GNUNET_free (ego);
1043  _ ("Failed to parse ego information in `%s'\n"),
1044  filename);
1045  return GNUNET_OK;
1046  }
1047  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded ego `%s'\n", fn + 1);
1048  ego->identifier = GNUNET_strdup (fn + 1);
1049  GNUNET_CONTAINER_DLL_insert (ego_head, ego_tail, ego);
1050  return GNUNET_OK;
1051 }
1052 
1053 
1061 static void
1062 run (void *cls,
1063  const struct GNUNET_CONFIGURATION_Handle *c,
1065 {
1066  cfg = c;
1069  "identity",
1070  "EGODIR",
1071  &ego_directory))
1072  {
1073  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "EGODIR");
1075  return;
1076  }
1077  if (GNUNET_OK !=
1079  "identity",
1080  "SUBSYSTEM_CFG",
1082  {
1084  "identity",
1085  "SUBSYSTEM_CFG");
1087  return;
1088  }
1090  "Loading subsystem configuration `%s'\n",
1092  subsystem_cfg = GNUNET_CONFIGURATION_create ();
1094  (GNUNET_OK !=
1096  {
1098  _ (
1099  "Failed to parse subsystem identity configuration file `%s'\n"),
1102  return;
1103  }
1104  stats = GNUNET_STATISTICS_create ("identity", cfg);
1106  {
1108  _ ("Failed to create directory `%s' for storing egos\n"),
1109  ego_directory);
1110  }
1113 }
1114 
1115 
1120  "identity",
1122  &run,
1125  NULL,
1126  GNUNET_MQ_hd_fixed_size (start_message,
1128  struct GNUNET_MessageHeader,
1129  NULL),
1130  GNUNET_MQ_hd_var_size (lookup_message,
1132  struct LookupMessage,
1133  NULL),
1134  GNUNET_MQ_hd_var_size (lookup_by_suffix_message,
1136  struct LookupMessage,
1137  NULL),
1138  GNUNET_MQ_hd_var_size (get_default_message,
1140  struct GetDefaultMessage,
1141  NULL),
1142  GNUNET_MQ_hd_var_size (set_default_message,
1144  struct SetDefaultMessage,
1145  NULL),
1146  GNUNET_MQ_hd_var_size (create_message,
1148  struct CreateRequestMessage,
1149  NULL),
1150  GNUNET_MQ_hd_var_size (rename_message,
1152  struct RenameMessage,
1153  NULL),
1154  GNUNET_MQ_hd_var_size (delete_message,
1156  struct DeleteMessage,
1157  NULL),
1159 
1160 
1161 /* end of gnunet-service-identity.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
GNUNET_SERVICE_MAIN("identity", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(start_message, GNUNET_MESSAGE_TYPE_IDENTITY_START, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_var_size(lookup_message, GNUNET_MESSAGE_TYPE_IDENTITY_LOOKUP, struct LookupMessage, NULL), GNUNET_MQ_hd_var_size(lookup_by_suffix_message, GNUNET_MESSAGE_TYPE_IDENTITY_LOOKUP_BY_SUFFIX, struct LookupMessage, NULL), GNUNET_MQ_hd_var_size(get_default_message, GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT, struct GetDefaultMessage, NULL), GNUNET_MQ_hd_var_size(set_default_message, GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT, struct SetDefaultMessage, NULL), GNUNET_MQ_hd_var_size(create_message, GNUNET_MESSAGE_TYPE_IDENTITY_CREATE, struct CreateRequestMessage, NULL), GNUNET_MQ_hd_var_size(rename_message, GNUNET_MESSAGE_TYPE_IDENTITY_RENAME, struct RenameMessage, NULL), GNUNET_MQ_hd_var_size(delete_message, GNUNET_MESSAGE_TYPE_IDENTITY_DELETE, struct DeleteMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
uint16_t reserved
Always zero.
Definition: identity.h:179
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:544
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key.
Definition: identity.h:154
Message from client to GNS service to lookup records.
Definition: gns.h:36
#define GNUNET_MESSAGE_TYPE_IDENTITY_START
First message send from identity client to service (to subscribe to updates).
struct Ego * prev
We keep egos in a DLL.
#define GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT
Client sets default identity; or service informs about default identity.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static int check_delete_message(void *cls, const struct DeleteMessage *msg)
Checks a GNUNET_MESSAGE_TYPE_IDENTITY_DELETE message.
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:75
Used from service to client as a result to the GET_DEFAULT message, used from client to service to SE...
Definition: identity.h:134
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_MESSAGE_TYPE_IDENTITY_DELETE
Delete identity (client->service).
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_IDENTITY_CREATE.
Definition: identity.h:169
struct Ego * next
We keep egos in a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
int GNUNET_CONFIGURATION_write(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Write configuration file.
Common type definitions for the identity service and API.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
Add a client to our list of active clients.
Handle to a service.
Definition: service.c:116
uint16_t reserved
Always zero.
Definition: identity.h:123
static char * get_ego_filename(struct Ego *ego)
Get the name of the file we use to store a given ego.
static void send_result_code(struct GNUNET_SERVICE_Client *client, uint32_t result_code, const char *emsg)
Send a result code back to the client.
static void handle_lookup_message(void *cls, const struct LookupMessage *message)
Handler for LOOKUP message from client, sends information about ONE identity to the client immediatel...
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2437
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:589
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE.
Definition: identity.h:82
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
static int check_create_message(void *cls, const struct CreateRequestMessage *msg)
Checks a GNUNET_MESSAGE_TYPE_IDENTITY_CREATE message.
uint16_t name_len
Number of bytes in service name string including 0-termination, in NBO.
Definition: identity.h:144
static void handle_set_default_message(void *cls, const struct SetDefaultMessage *sdm)
Handler for SET_DEFAULT message from client, updates default identity for some service.
uint16_t name_len
Number of bytes in service name string including 0-termination, in NBO.
Definition: identity.h:118
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT.
Definition: identity.h:113
uint16_t old_name_len
Number of characters in the old name including 0-termination, in NBO.
Definition: identity.h:204
Client requests renaming of an identity.
Definition: identity.h:194
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key.
Definition: identity.h:98
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
uint16_t reserved
Always zero.
Definition: identity.h:235
static struct Experiment * e
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:684
static void handle_lookup_by_suffix_message(void *cls, const struct LookupMessage *message)
Handler for LOOKUP_BY_SUFFIX message from client, sends information about ONE identity to the client ...
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_CRYPTO_EcdsaPrivateKey * pk
Private key of the ego.
#define GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE
Update about identity status from service to clients.
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
int GNUNET_CONFIGURATION_parse(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Parse a configuration file, add all of the options in the file to the configuration environment...
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:912
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
Handle for the service.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
uint16_t name_len
Number of bytes in identity name string including 0-termination, in NBO.
Definition: identity.h:174
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:160
static int check_lookup_message(void *cls, const struct LookupMessage *message)
Handler for LOOKUP message from client, sends information about ONE identity to the client immediatel...
ssize_t GNUNET_DISK_fn_write(const char *fn, const void *buffer, size_t n, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file.
Definition: disk.c:880
Closure for &#39;handle_ego_rename&#39;.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static char * section
Name of the section.
Definition: gnunet-config.c:33
static const struct GNUNET_CONFIGURATION_Handle * cfg
Handle to our current configuration.
Handle to a client that is connected to a service.
Definition: service.c:250
uint16_t reserved
Always zero.
Definition: identity.h:149
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static void handle_create_message(void *cls, const struct CreateRequestMessage *crm)
Handler for CREATE message from client, creates new identity.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static int check_set_default_message(void *cls, const struct SetDefaultMessage *msg)
Checks a GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT message.
#define GNUNET_MQ_check_zero_termination(m)
Insert code for a "check_" function that verifies that a given variable-length message received over ...
static void handle_ego_delete(void *cls, const char *section)
An ego was removed, remove it from all subsystems where it is currently set as the default...
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
static struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Called whenever a client is disconnected.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static char * fn
Filename of the unique file.
static struct GNUNET_MQ_Envelope * create_set_default_message(struct Ego *ego, const char *servicename)
Create a set default message with information about the current state of an ego.
#define GNUNET_MESSAGE_TYPE_IDENTITY_LOOKUP
First message send from identity client to service to lookup a single ego.
Client requests creation of an identity.
Definition: identity.h:164
#define DIR_SEPARATOR_STR
Definition: platform.h:168
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
static char * filename
static int check_rename_message(void *cls, const struct RenameMessage *msg)
Checks a GNUNET_MESSAGE_TYPE_IDENTITY_RENAME message.
char * identifier
String identifier for the ego.
void GNUNET_CONFIGURATION_set_value_string(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Set a configuration value that should be a string.
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the &#39;monitor&#39; flag on this client.
Definition: service.c:2407
static void shutdown_task(void *cls)
Task run during shutdown.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Handle network size estimate clients.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_IDENTITY_DELETE.
Definition: identity.h:225
Client requests deletion of an identity.
Definition: identity.h:220
static void handle_rename_message(void *cls, const struct RenameMessage *rm)
Handler for RENAME message from client, creates new identity.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
const char * new_name
New name.
#define DIR_SEPARATOR
Definition: platform.h:167
#define GNUNET_MESSAGE_TYPE_IDENTITY_LOOKUP_BY_SUFFIX
First message send from identity client to service to lookup a single ego matching the given suffix (...
#define GNUNET_MESSAGE_TYPE_IDENTITY_CREATE
Create new identity (client->service).
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
static void handle_delete_message(void *cls, const struct DeleteMessage *dm)
Handler for DELETE message from client, creates new identity.
struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_key_create_from_file(const char *filename)
Create a new private key by reading it from a file.
static struct GNUNET_NotificationContext * nc
Notification context, simplifies client broadcasts.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct Ego * ego_head
Head of DLL of all egos.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT.
Definition: identity.h:139
static char * subsystem_cfg_file
Configuration file name where subsystem information is kept.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:121
Information we keep about each ego.
uint32_t result_code
Status code for the last operation, in NBO.
Definition: identity.h:53
uint16_t name_len
Number of bytes in ego name string including 0-termination, in NBO; 0 if the ego was deleted...
Definition: identity.h:88
Handle to a message queue.
Definition: mq.c:85
static int check_lookup_by_suffix_message(void *cls, const struct LookupMessage *message)
Handler for LOOKUP message from client, sends information about ONE identity to the client immediatel...
uint16_t new_name_len
Number of characters in the new name including 0-termination, in NBO.
Definition: identity.h:209
void GNUNET_notification_context_broadcast(struct GNUNET_NotificationContext *nc, const struct GNUNET_MessageHeader *msg, int can_drop)
Send a message to all subscribers of this context.
Definition: nc.c:189
static void notify_listeners(struct Ego *ego)
Send an updated message for the given ego to all listeners.
configuration data
Definition: configuration.c:85
static int key_cmp(const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk1, const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk2)
Compare the given two private keys for equality.
const char * name
uint16_t end_of_list
Usually GNUNET_NO, GNUNET_YES to signal end of list.
Definition: identity.h:93
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_Section_Iterator iter, void *iter_cls)
Iterate over all sections in the configuration.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
static void handle_start_message(void *cls, const struct GNUNET_MessageHeader *message)
Handler for START message from client, sends information about all identities to the client immediate...
#define GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT
Client requests to know default identity for a subsystem.
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
#define GNUNET_MESSAGE_TYPE_IDENTITY_RENAME
Rename existing identity (client->service).
static char * ego_directory
Directory where we store the identities.
uint16_t name_len
Number of characters in the name including 0-termination, in NBO.
Definition: identity.h:230
static void handle_get_default_message(void *cls, const struct GetDefaultMessage *gdm)
Handler for GET_DEFAULT message from client, returns default identity for some service.
static int check_get_default_message(void *cls, const struct GetDefaultMessage *msg)
Checks a GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT message.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_IDENTITY_RENAME.
Definition: identity.h:199
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:77
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:137
#define GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE
Generic response from identity service with success and/or error message.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
const char * old_name
Old name.
Client requests knowledge about default identity for a subsystem from identity service.
Definition: identity.h:108
static struct Ego * ego_tail
Tail of DLL of all egos.
static int process_ego_file(void *cls, const char *filename)
Process the given file from the "EGODIR".
static struct GNUNET_CONFIGURATION_Handle * subsystem_cfg
Handle to subsystem configuration which for each subsystem contains the name of the default ego...
void GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c)
Disable the warning the server issues if a message is not acknowledged in a timely fashion...
Definition: service.c:2267
static void handle_ego_rename(void *cls, const char *section)
An ego was renamed; rename it in all subsystems where it is currently set as the default.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static struct GNUNET_MQ_Envelope * create_update_message(struct Ego *ego)
Create an update message with information about the current state of an ego.
#define GNUNET_malloc(size)
Wrapper around malloc.
Answer from service to client about last operation; GET_DEFAULT maybe answered with this message on f...
Definition: identity.h:42
Service informs client about status of a pseudonym.
Definition: identity.h:77
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
Convert the utf-8 input string to lower case.
Definition: strings.c:553
#define gettext_noop(String)
Definition: gettext.h:69