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 {
144  "Client %p disconnected\n",
145  client);
146 }
147 
148 
157 static void *
158 client_connect_cb (void *cls,
159  struct GNUNET_SERVICE_Client *client,
160  struct GNUNET_MQ_Handle *mq)
161 {
162  return client;
163 }
164 
165 
171 static void
172 shutdown_task (void *cls)
173 {
174  struct Ego *e;
175 
176  if (NULL != nc)
177  {
179  nc = NULL;
180  }
181  if (NULL != stats)
182  {
184  stats = NULL;
185  }
186  GNUNET_CONFIGURATION_destroy (subsystem_cfg);
187  subsystem_cfg = NULL;
189  subsystem_cfg_file = NULL;
191  ego_directory = NULL;
192  while (NULL != (e = ego_head))
193  {
194  GNUNET_CONTAINER_DLL_remove (ego_head,
195  ego_tail,
196  e);
197  GNUNET_free (e->identifier);
198  GNUNET_free (e);
199  }
200 }
201 
202 
210 static void
212  uint32_t result_code,
213  const char *emsg)
214 {
215  struct ResultCodeMessage *rcm;
216  struct GNUNET_MQ_Envelope *env;
217  size_t elen;
218 
219  if (NULL == emsg)
220  elen = 0;
221  else
222  elen = strlen (emsg) + 1;
223  env =
225  rcm->result_code = htonl (result_code);
226  if (0 < elen)
227  GNUNET_memcpy (&rcm[1], emsg, elen);
229  "Sending result %d (%s) to client\n",
230  (int) result_code,
231  emsg);
233 }
234 
235 
242 static struct GNUNET_MQ_Envelope *
244 {
245  struct UpdateMessage *um;
246  struct GNUNET_MQ_Envelope *env;
247  size_t name_len;
248 
249  name_len = (NULL == ego->identifier) ? 0 : (strlen (ego->identifier) + 1);
251  um->name_len = htons (name_len);
252  um->end_of_list = htons (GNUNET_NO);
253  um->private_key = ego->pk;
254  GNUNET_memcpy (&um[1], ego->identifier, name_len);
255  return env;
256 }
257 
258 
266 static struct GNUNET_MQ_Envelope *
268  const char *servicename)
269 {
270  struct SetDefaultMessage *sdm;
271  struct GNUNET_MQ_Envelope *env;
272  size_t name_len;
273 
274  name_len = (NULL == servicename) ? 0 : (strlen (servicename) + 1);
275  env = GNUNET_MQ_msg_extra (sdm,
276  name_len,
278  sdm->name_len = htons (name_len);
279  sdm->reserved = htons (0);
280  sdm->private_key = ego->pk;
281  GNUNET_memcpy (&sdm[1], servicename, name_len);
282  return env;
283 }
284 
285 
295 static void
297  const struct GNUNET_MessageHeader *message)
298 {
299  struct GNUNET_SERVICE_Client *client = cls;
300 
302  "Received START message from client\n");
307  for (struct Ego *ego = ego_head; NULL != ego; ego = ego->next)
308  {
310  create_update_message (ego));
311  }
312  {
313  struct UpdateMessage *ume;
314  struct GNUNET_MQ_Envelope *env;
315 
316  env = GNUNET_MQ_msg_extra (ume,
317  0,
319  ume->end_of_list = htons (GNUNET_YES);
320  ume->name_len = htons (0);
322  env);
323  }
325 }
326 
327 
336 static int
338  const struct LookupMessage *message)
339 {
341  return GNUNET_OK;
342 }
343 
344 
352 static void
354  const struct LookupMessage *message)
355 {
356  struct GNUNET_SERVICE_Client *client = cls;
357  const char *name;
358  struct GNUNET_MQ_Envelope *env;
359  struct Ego *ego;
360 
362  "Received LOOKUP message from client\n");
363  name = (const char *) &message[1];
364  for (ego = ego_head; NULL != ego; ego = ego->next)
365  {
366  if (0 != strcasecmp (name, ego->identifier))
367  continue;
368  env = create_update_message (ego);
371  return;
372  }
373  send_result_code (client, 0, "ego not found");
375 }
376 
377 
386 static int
388  const struct LookupMessage *message)
389 {
391  return GNUNET_OK;
392 }
393 
394 
402 static void
404  const struct LookupMessage *message)
405 {
406  struct GNUNET_SERVICE_Client *client = cls;
407  const char *name;
408  struct GNUNET_MQ_Envelope *env;
409  struct Ego *lprefix;
410 
412  "Received LOOKUP_BY_SUFFIX message from client\n");
413  name = (const char *) &message[1];
414  lprefix = NULL;
415  for (struct Ego *ego = ego_head; NULL != ego; ego = ego->next)
416  {
417  if ((strlen (ego->identifier) <= strlen (name)) &&
418  (0 == strcmp (ego->identifier,
419  &name[strlen (name) - strlen (ego->identifier)])) &&
420  ((strlen (name) == strlen (ego->identifier)) ||
421  ('.' == name[strlen (name) - strlen (ego->identifier) - 1])) &&
422  ((NULL == lprefix) ||
423  (strlen (ego->identifier) > strlen (lprefix->identifier))))
424  {
425  /* found better match, update! */
426  lprefix = ego;
427  }
428  }
429  if (NULL != lprefix)
430  {
431  env = create_update_message (lprefix);
434  return;
435  }
436  send_result_code (client, 0, "ego not found");
438 }
439 
440 
448 static int
450  const struct GetDefaultMessage *msg)
451 {
452  uint16_t size;
453  uint16_t name_len;
454  const char *name;
455 
456  size = ntohs (msg->header.size);
457  if (size <= sizeof(struct GetDefaultMessage))
458  {
459  GNUNET_break (0);
460  return GNUNET_SYSERR;
461  }
462  name = (const char *) &msg[1];
463  name_len = ntohs (msg->name_len);
464  if ((name_len + sizeof(struct GetDefaultMessage) != size) ||
465  (0 != ntohs (msg->reserved)) || ('\0' != name[name_len - 1]))
466  {
467  GNUNET_break (0);
468  return GNUNET_SYSERR;
469  }
470  return GNUNET_OK;
471 }
472 
473 
482 static void
484  const struct GetDefaultMessage *gdm)
485 {
486  struct GNUNET_MQ_Envelope *env;
487  struct GNUNET_SERVICE_Client *client = cls;
488  char *name;
489  char *identifier;
490 
491  name = GNUNET_strdup ((const char *) &gdm[1]);
492  GNUNET_STRINGS_utf8_tolower ((const char *) &gdm[1],
493  name);
495  "Received GET_DEFAULT for service `%s' from client\n",
496  name);
497  if (GNUNET_OK !=
499  name,
500  "DEFAULT_IDENTIFIER",
501  &identifier))
502  {
503  send_result_code (client, 1, gettext_noop ("no default known"));
505  GNUNET_free (name);
506  return;
507  }
508  for (struct Ego *ego = ego_head; NULL != ego; ego = ego->next)
509  {
510  if (0 == strcmp (ego->identifier, identifier))
511  {
512  env = create_set_default_message (ego, name);
515  GNUNET_free (identifier);
516  GNUNET_free (name);
517  return;
518  }
519  }
520  GNUNET_free (identifier);
522  "Failed to find ego `%s'\n",
523  name);
524  GNUNET_free (name);
525  send_result_code (client,
526  1,
527  gettext_noop (
528  "default configured, but ego unknown (internal error)"));
530 }
531 
532 
540 static int
542  const struct GNUNET_IDENTITY_PrivateKey *pk2)
543 {
544  return GNUNET_memcmp (pk1, pk2);
545 }
546 
547 
555 static int
557  const struct SetDefaultMessage *msg)
558 {
559  uint16_t size;
560  uint16_t name_len;
561  const char *str;
562 
563  size = ntohs (msg->header.size);
564  if (size <= sizeof(struct SetDefaultMessage))
565  {
566  GNUNET_break (0);
567  return GNUNET_SYSERR;
568  }
569  name_len = ntohs (msg->name_len);
570  GNUNET_break (0 == ntohs (msg->reserved));
571  if (name_len + sizeof(struct SetDefaultMessage) != size)
572  {
573  GNUNET_break (0);
574  return GNUNET_SYSERR;
575  }
576  str = (const char *) &msg[1];
577  if ('\0' != str[name_len - 1])
578  {
579  GNUNET_break (0);
580  return GNUNET_SYSERR;
581  }
582  return GNUNET_OK;
583 }
584 
585 
594 static void
596  const struct SetDefaultMessage *sdm)
597 {
598  struct Ego *ego;
599  struct GNUNET_SERVICE_Client *client = cls;
600  char *str;
601 
602  str = GNUNET_strdup ((const char *) &sdm[1]);
603  GNUNET_STRINGS_utf8_tolower ((const char *) &sdm[1], str);
604 
606  "Received SET_DEFAULT for service `%s' from client\n",
607  str);
608  for (ego = ego_head; NULL != ego; ego = ego->next)
609  {
610  if (0 == key_cmp (&ego->pk,
611  &sdm->private_key))
612  {
614  str,
615  "DEFAULT_IDENTIFIER",
616  ego->identifier);
617  if (GNUNET_OK !=
619  GNUNET_log (
621  _ ("Failed to write subsystem default identifier map to `%s'.\n"),
623  send_result_code (client, 0, NULL);
625  GNUNET_free (str);
626  return;
627  }
628  }
629  send_result_code (client,
630  1,
631  _ ("Unknown ego specified for service (internal error)"));
632  GNUNET_free (str);
634 }
635 
636 
642 static void
643 notify_listeners (struct Ego *ego)
644 {
645  struct UpdateMessage *um;
646  size_t name_len;
647 
648  name_len = (NULL == ego->identifier) ? 0 : (strlen (ego->identifier) + 1);
649  um = GNUNET_malloc (sizeof(struct UpdateMessage) + name_len);
651  um->header.size = htons (sizeof(struct UpdateMessage) + name_len);
652  um->name_len = htons (name_len);
653  um->end_of_list = htons (GNUNET_NO);
654  um->private_key = ego->pk;
655  GNUNET_memcpy (&um[1], ego->identifier, name_len);
657  GNUNET_free (um);
658 }
659 
660 
668 static int
670  const struct CreateRequestMessage *msg)
671 {
672  uint16_t size;
673  uint16_t name_len;
674  const char *str;
675 
676  size = ntohs (msg->header.size);
677  if (size <= sizeof(struct CreateRequestMessage))
678  {
679  GNUNET_break (0);
680  return GNUNET_SYSERR;
681  }
682  name_len = ntohs (msg->name_len);
683  GNUNET_break (0 == ntohs (msg->reserved));
684  if (name_len + sizeof(struct CreateRequestMessage) != size)
685  {
686  GNUNET_break (0);
687  return GNUNET_SYSERR;
688  }
689  str = (const char *) &msg[1];
690  if ('\0' != str[name_len - 1])
691  {
692  GNUNET_break (0);
693  return GNUNET_SYSERR;
694  }
695  return GNUNET_OK;
696 }
697 
698 
706 static void
708  const struct CreateRequestMessage *crm)
709 {
710  struct GNUNET_SERVICE_Client *client = cls;
711  struct Ego *ego;
712  char *str;
713  char *fn;
714 
715  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CREATE message from client\n");
716  str = GNUNET_strdup ((const char *) &crm[1]);
717  GNUNET_STRINGS_utf8_tolower ((const char *) &crm[1], str);
718  for (ego = ego_head; NULL != ego; ego = ego->next)
719  {
720  if (0 == strcmp (ego->identifier, str))
721  {
722  send_result_code (client,
723  1,
724  gettext_noop (
725  "identifier already in use for another ego"));
727  GNUNET_free (str);
728  return;
729  }
730  }
731  ego = GNUNET_new (struct Ego);
732  ego->pk = crm->private_key;
733  ego->identifier = GNUNET_strdup (str);
734  GNUNET_CONTAINER_DLL_insert (ego_head,
735  ego_tail,
736  ego);
737  send_result_code (client, 0, NULL);
738  fn = get_ego_filename (ego);
739  if (GNUNET_OK !=
741  &crm->private_key,
742  sizeof(struct GNUNET_IDENTITY_PrivateKey),
746  GNUNET_free (fn);
747  GNUNET_free (str);
748  notify_listeners (ego);
750 }
751 
752 
757 {
761  const char *old_name;
762 
766  const char *new_name;
767 };
768 
776 static void
777 handle_ego_rename (void *cls, const char *section)
778 {
779  struct RenameContext *rc = cls;
780  char *id;
781 
782  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg,
783  section,
784  "DEFAULT_IDENTIFIER",
785  &id))
786  return;
787  if (0 != strcmp (id, rc->old_name))
788  {
789  GNUNET_free (id);
790  return;
791  }
793  section,
794  "DEFAULT_IDENTIFIER",
795  rc->new_name);
796  GNUNET_free (id);
797 }
798 
799 
807 static int
808 check_rename_message (void *cls, const struct RenameMessage *msg)
809 {
810  uint16_t size;
811  uint16_t old_name_len;
812  uint16_t new_name_len;
813  const char *old_name;
814  const char *new_name;
815 
816  size = ntohs (msg->header.size);
817  if (size <= sizeof(struct RenameMessage))
818  {
819  GNUNET_break (0);
820  return GNUNET_SYSERR;
821  }
822  old_name_len = ntohs (msg->old_name_len);
823  new_name_len = ntohs (msg->new_name_len);
824  old_name = (const char *) &msg[1];
825  new_name = &old_name[old_name_len];
826  if ((old_name_len + new_name_len + sizeof(struct RenameMessage) != size) ||
827  ('\0' != old_name[old_name_len - 1]) ||
828  ('\0' != new_name[new_name_len - 1]))
829  {
830  GNUNET_break (0);
831  return GNUNET_SYSERR;
832  }
833 
834  return GNUNET_OK;
835 }
836 
837 
846 static void
847 handle_rename_message (void *cls, const struct RenameMessage *rm)
848 {
849  uint16_t old_name_len;
850  struct Ego *ego;
851  char *old_name;
852  char *new_name;
853  struct RenameContext rename_ctx;
854  struct GNUNET_SERVICE_Client *client = cls;
855  char *fn_old;
856  char *fn_new;
857  const char *old_name_tmp;
858 
859  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received RENAME message from client\n");
860  old_name_len = ntohs (rm->old_name_len);
861  old_name_tmp = (const char *) &rm[1];
862  old_name = GNUNET_strdup (old_name_tmp);
863  GNUNET_STRINGS_utf8_tolower (old_name_tmp, old_name);
864  new_name = GNUNET_strdup (&old_name_tmp[old_name_len]);
865  GNUNET_STRINGS_utf8_tolower (&old_name_tmp[old_name_len], new_name);
866 
867  /* check if new name is already in use */
868  for (ego = ego_head; NULL != ego; ego = ego->next)
869  {
870  if (0 == strcmp (ego->identifier, new_name))
871  {
872  send_result_code (client, 1, gettext_noop ("target name already exists"));
874  GNUNET_free (old_name);
875  GNUNET_free (new_name);
876  return;
877  }
878  }
879 
880  /* locate old name and, if found, perform rename */
881  for (ego = ego_head; NULL != ego; ego = ego->next)
882  {
883  if (0 == strcmp (ego->identifier, old_name))
884  {
885  fn_old = get_ego_filename (ego);
886  GNUNET_free (ego->identifier);
887  rename_ctx.old_name = old_name;
888  rename_ctx.new_name = new_name;
891  &rename_ctx);
892  if (GNUNET_OK !=
894  GNUNET_log (
896  _ ("Failed to write subsystem default identifier map to `%s'.\n"),
898  ego->identifier = GNUNET_strdup (new_name);
899  fn_new = get_ego_filename (ego);
900  if (0 != rename (fn_old, fn_new))
902  GNUNET_free (fn_old);
903  GNUNET_free (fn_new);
904  GNUNET_free (old_name);
905  GNUNET_free (new_name);
906  notify_listeners (ego);
907  send_result_code (client, 0, NULL);
909  return;
910  }
911  }
912 
913  /* failed to locate old name */
914  send_result_code (client, 1, gettext_noop ("no matching ego found"));
915  GNUNET_free (old_name);
916  GNUNET_free (new_name);
918 }
919 
920 
928 static void
929 handle_ego_delete (void *cls, const char *section)
930 {
931  const char *identifier = cls;
932  char *id;
933 
934  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg,
935  section,
936  "DEFAULT_IDENTIFIER",
937  &id))
938  return;
939  if (0 != strcmp (id, identifier))
940  {
941  GNUNET_free (id);
942  return;
943  }
945  section,
946  "DEFAULT_IDENTIFIER",
947  NULL);
948  GNUNET_free (id);
949 }
950 
951 
959 static int
960 check_delete_message (void *cls, const struct DeleteMessage *msg)
961 {
962  uint16_t size;
963  uint16_t name_len;
964  const char *name;
965 
966  size = ntohs (msg->header.size);
967  if (size <= sizeof(struct DeleteMessage))
968  {
969  GNUNET_break (0);
970  return GNUNET_SYSERR;
971  }
972  name = (const char *) &msg[1];
973  name_len = ntohs (msg->name_len);
974  if ((name_len + sizeof(struct DeleteMessage) != size) ||
975  (0 != ntohs (msg->reserved)) || ('\0' != name[name_len - 1]))
976  {
977  GNUNET_break (0);
978  return GNUNET_SYSERR;
979  }
980  return GNUNET_OK;
981 }
982 
983 
992 static void
993 handle_delete_message (void *cls, const struct DeleteMessage *dm)
994 {
995  struct Ego *ego;
996  char *name;
997  char *fn;
998  struct GNUNET_SERVICE_Client *client = cls;
999 
1000  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received DELETE message from client\n");
1001  name = GNUNET_strdup ((const char *) &dm[1]);
1002  GNUNET_STRINGS_utf8_tolower ((const char *) &dm[1], name);
1003 
1004  for (ego = ego_head; NULL != ego; ego = ego->next)
1005  {
1006  if (0 == strcmp (ego->identifier, name))
1007  {
1008  GNUNET_CONTAINER_DLL_remove (ego_head, ego_tail, ego);
1011  ego->identifier);
1012  if (GNUNET_OK !=
1014  GNUNET_log (
1016  _ ("Failed to write subsystem default identifier map to `%s'.\n"),
1018  fn = get_ego_filename (ego);
1019  if (0 != unlink (fn))
1021  GNUNET_free (fn);
1022  GNUNET_free (ego->identifier);
1023  ego->identifier = NULL;
1024  notify_listeners (ego);
1025  GNUNET_free (ego);
1026  GNUNET_free (name);
1027  send_result_code (client, 0, NULL);
1029  return;
1030  }
1031  }
1032 
1033  send_result_code (client, 1, gettext_noop ("no matching ego found"));
1034  GNUNET_free (name);
1036 }
1037 
1038 
1039 static int
1041  void *buf,
1042  size_t buf_size)
1043 {
1044  int fd;
1045  struct stat sb;
1046 
1047  fd = open (filename,
1048  O_RDONLY);
1049  if (-1 == fd)
1050  {
1051  memset (buf,
1052  0,
1053  buf_size);
1054  return GNUNET_SYSERR;
1055  }
1056  if (0 != fstat (fd,
1057  &sb))
1058  {
1060  "stat",
1061  filename);
1062  GNUNET_assert (0 == close (fd));
1063  memset (buf,
1064  0,
1065  buf_size);
1066  return GNUNET_SYSERR;
1067  }
1068  if (sb.st_size != buf_size)
1069  {
1071  "File `%s' has wrong size (%llu), expected %llu bytes\n",
1072  filename,
1073  (unsigned long long) sb.st_size,
1074  (unsigned long long) buf_size);
1075  GNUNET_assert (0 == close (fd));
1076  memset (buf,
1077  0,
1078  buf_size);
1079  return GNUNET_SYSERR;
1080  }
1081  if (buf_size !=
1082  read (fd,
1083  buf,
1084  buf_size))
1085  {
1087  "read",
1088  filename);
1089  GNUNET_assert (0 == close (fd));
1090  memset (buf,
1091  0,
1092  buf_size);
1093  return GNUNET_SYSERR;
1094  }
1095  GNUNET_assert (0 == close (fd));
1096  return GNUNET_OK;
1097 }
1098 
1099 
1110 static int
1111 process_ego_file (void *cls,
1112  const char *filename)
1113 {
1114  struct Ego *ego;
1115  const char *fn;
1116 
1117  fn = strrchr (filename, (int) DIR_SEPARATOR);
1118  if (NULL == fn)
1119  {
1120  GNUNET_break (0);
1121  return GNUNET_OK;
1122  }
1123  ego = GNUNET_new (struct Ego);
1124  if (GNUNET_OK !=
1125  read_from_file (filename,
1126  &ego->pk,
1127  sizeof (ego->pk)))
1128  {
1129  GNUNET_free (ego);
1131  _ ("Failed to parse ego information in `%s'\n"),
1132  filename);
1133  return GNUNET_OK;
1134  }
1136  "Loaded ego `%s'\n",
1137  fn + 1);
1138  ego->identifier = GNUNET_strdup (fn + 1);
1139  GNUNET_CONTAINER_DLL_insert (ego_head, ego_tail, ego);
1140  return GNUNET_OK;
1141 }
1142 
1143 
1151 static void
1152 run (void *cls,
1153  const struct GNUNET_CONFIGURATION_Handle *c,
1155 {
1156  cfg = c;
1159  "identity",
1160  "EGODIR",
1161  &ego_directory))
1162  {
1163  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "EGODIR");
1165  return;
1166  }
1167  if (GNUNET_OK !=
1169  "identity",
1170  "SUBSYSTEM_CFG",
1172  {
1174  "identity",
1175  "SUBSYSTEM_CFG");
1177  return;
1178  }
1180  "Loading subsystem configuration `%s'\n",
1182  subsystem_cfg = GNUNET_CONFIGURATION_create ();
1184  (GNUNET_OK !=
1186  {
1188  _ (
1189  "Failed to parse subsystem identity configuration file `%s'\n"),
1192  return;
1193  }
1194  stats = GNUNET_STATISTICS_create ("identity", cfg);
1196  {
1198  _ ("Failed to create directory `%s' for storing egos\n"),
1199  ego_directory);
1200  }
1203  NULL);
1205 }
1206 
1207 
1212  "identity",
1214  &run,
1217  NULL,
1218  GNUNET_MQ_hd_fixed_size (start_message,
1220  struct GNUNET_MessageHeader,
1221  NULL),
1222  GNUNET_MQ_hd_var_size (lookup_message,
1224  struct LookupMessage,
1225  NULL),
1226  GNUNET_MQ_hd_var_size (lookup_by_suffix_message,
1228  struct LookupMessage,
1229  NULL),
1230  GNUNET_MQ_hd_var_size (get_default_message,
1232  struct GetDefaultMessage,
1233  NULL),
1234  GNUNET_MQ_hd_var_size (set_default_message,
1236  struct SetDefaultMessage,
1237  NULL),
1240  struct CreateRequestMessage,
1241  NULL),
1242  GNUNET_MQ_hd_var_size (rename_message,
1244  struct RenameMessage,
1245  NULL),
1246  GNUNET_MQ_hd_var_size (delete_message,
1248  struct DeleteMessage,
1249  NULL),
1251 
1252 
1253 /* 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:217
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:172
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:207
struct Ego * next
We keep egos in a DLL.
static int key_cmp(const struct GNUNET_IDENTITY_PrivateKey *pk1, const struct GNUNET_IDENTITY_PrivateKey *pk2)
Compare the given two private keys for equality.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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:161
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...
enum GNUNET_GenericReturnValue 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...
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2438
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:1331
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE.
Definition: identity.h:120
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:182
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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:156
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT.
Definition: identity.h:151
uint16_t old_name_len
Number of characters in the old name including 0-termination, in NBO.
Definition: identity.h:242
Client requests renaming of an identity.
Definition: identity.h:232
A private key for an identity as per LSD0001.
#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:273
static struct Experiment * e
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_MESSAGE_TYPE_IDENTITY_UPDATE
Update about identity status from service to clients.
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
enum GNUNET_GenericReturnValue 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.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:794
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_MESSENGER_Message * create_message(enum GNUNET_MESSENGER_MessageKind kind)
Creates and allocates a new message with a specific kind.
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:531
Handle for the service.
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_write(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Write configuration file.
#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:212
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...
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:178
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:187
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:202
#define DIR_SEPARATOR_STR
Definition: platform.h:165
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
static char buf[2048]
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.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:476
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the &#39;monitor&#39; flag on this client.
Definition: service.c:2408
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:263
Client requests deletion of an identity.
Definition: identity.h:258
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
static void handle_rename_message(void *cls, const struct RenameMessage *rm)
Handler for RENAME message from client, creates new identity.
const char * new_name
New name.
#define DIR_SEPARATOR
Definition: platform.h:164
#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).
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.
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:177
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.
enum GNUNET_GenericReturnValue GNUNET_DISK_fn_write(const char *fn, const void *buf, size_t buf_size, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file atomically.
Definition: disk.c:705
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:91
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:126
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:247
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.
static int read_from_file(const char *filename, void *buf, size_t buf_size)
configuration data
Definition: configuration.c:84
const char * name
uint16_t end_of_list
Usually GNUNET_NO, GNUNET_YES to signal end of list.
Definition: identity.h:131
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.
struct GNUNET_IDENTITY_PrivateKey pk
Private key of the ego.
#define GNUNET_MESSAGE_TYPE_IDENTITY_RENAME
Rename existing identity (client->service).
static char * ego_directory
Directory where we store the identities.
struct GNUNET_IDENTITY_PrivateKey private_key
The private key.
Definition: identity.h:136
uint16_t name_len
Number of characters in the name including 0-termination, in NBO.
Definition: identity.h:268
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:237
Header for all communications.
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:355
const char * old_name
Old name.
Client requests knowledge about default identity for a subsystem from identity service.
Definition: identity.h:146
static struct Ego * ego_tail
Tail of DLL of all egos.
struct GNUNET_IDENTITY_PrivateKey private_key
The private key.
Definition: identity.h:192
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:2268
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:2244
#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.
enum GNUNET_GenericReturnValue 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:437
#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:80
Service informs client about status of a pseudonym.
Definition: identity.h:115
#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:568
#define gettext_noop(String)
Definition: gettext.h:69