GNUnet  0.10.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 {
49  struct Ego *next;
50 
54  struct Ego *prev;
55 
60 
64  char *identifier;
65 };
66 
67 
71 static const struct GNUNET_CONFIGURATION_Handle *cfg;
72 
78 
83 
88 
92 static char *ego_directory;
93 
97 static char *subsystem_cfg_file;
98 
102 static struct Ego *ego_head;
103 
107 static struct Ego *ego_tail;
108 
109 
116 static char *
117 get_ego_filename(struct Ego *ego)
118 {
119  char *filename;
120 
121  GNUNET_asprintf(&filename,
122  "%s%s%s",
125  ego->identifier);
126  return filename;
127 }
128 
136 static void
138  struct GNUNET_SERVICE_Client *client,
139  void *app_ctx)
140 {
141  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
142 }
143 
144 
153 static void *
155  struct GNUNET_SERVICE_Client *client,
156  struct GNUNET_MQ_Handle *mq)
157 {
158  return client;
159 }
160 
166 static void
167 shutdown_task(void *cls)
168 {
169  struct Ego *e;
170 
171  if (NULL != nc)
172  {
174  nc = NULL;
175  }
176  if (NULL != stats)
177  {
179  stats = NULL;
180  }
181  GNUNET_CONFIGURATION_destroy(subsystem_cfg);
182  subsystem_cfg = NULL;
184  subsystem_cfg_file = NULL;
186  ego_directory = NULL;
187  while (NULL != (e = ego_head))
188  {
189  GNUNET_CONTAINER_DLL_remove(ego_head, ego_tail, e);
190  GNUNET_free(e->pk);
192  GNUNET_free(e);
193  }
194 }
195 
196 
204 static void
206  uint32_t result_code,
207  const char *emsg)
208 {
209  struct ResultCodeMessage *rcm;
210  struct GNUNET_MQ_Envelope *env;
211  size_t elen;
212 
213  if (NULL == emsg)
214  elen = 0;
215  else
216  elen = strlen(emsg) + 1;
217  env =
219  rcm->result_code = htonl(result_code);
220  if (0 < elen)
221  GNUNET_memcpy(&rcm[1], emsg, elen);
223  "Sending result %d (%s) to client\n",
224  (int)result_code,
225  emsg);
227 }
228 
229 
236 static struct GNUNET_MQ_Envelope *
238 {
239  struct UpdateMessage *um;
240  struct GNUNET_MQ_Envelope *env;
241  size_t name_len;
242 
243  name_len = (NULL == ego->identifier) ? 0 : (strlen(ego->identifier) + 1);
245  um->name_len = htons(name_len);
246  um->end_of_list = htons(GNUNET_NO);
247  um->private_key = *ego->pk;
248  GNUNET_memcpy(&um[1], ego->identifier, name_len);
249  return env;
250 }
251 
252 
260 static struct GNUNET_MQ_Envelope *
261 create_set_default_message(struct Ego *ego, const char *servicename)
262 {
263  struct SetDefaultMessage *sdm;
264  struct GNUNET_MQ_Envelope *env;
265  size_t name_len;
266 
267  name_len = (NULL == servicename) ? 0 : (strlen(servicename) + 1);
268  env = GNUNET_MQ_msg_extra(sdm,
269  name_len,
271  sdm->name_len = htons(name_len);
272  sdm->reserved = htons(0);
273  sdm->private_key = *ego->pk;
274  GNUNET_memcpy(&sdm[1], servicename, name_len);
275  return env;
276 }
277 
278 
288 static void
289 handle_start_message(void *cls, const struct GNUNET_MessageHeader *message)
290 {
291  struct GNUNET_SERVICE_Client *client = cls;
292  struct UpdateMessage *ume;
293  struct GNUNET_MQ_Envelope *env;
294  struct Ego *ego;
295 
296  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n");
300  for (ego = ego_head; NULL != ego; ego = ego->next)
301  {
302  env = create_update_message(ego);
304  }
306  ume->end_of_list = htons(GNUNET_YES);
307  ume->name_len = htons(0);
310 }
311 
312 
321 static int
322 check_lookup_message(void *cls, const struct LookupMessage *message)
323 {
325  return GNUNET_OK;
326 }
327 
328 
336 static void
337 handle_lookup_message(void *cls, const struct LookupMessage *message)
338 {
339  struct GNUNET_SERVICE_Client *client = cls;
340  const char *name;
341  struct GNUNET_MQ_Envelope *env;
342  struct Ego *ego;
343 
344  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received LOOKUP message from client\n");
345  name = (const char *)&message[1];
346  for (ego = ego_head; NULL != ego; ego = ego->next)
347  {
348  if (0 != strcasecmp(name, ego->identifier))
349  continue;
350  env = create_update_message(ego);
353  return;
354  }
355  send_result_code(client, 0, "ego not found");
357 }
358 
359 
368 static int
369 check_lookup_by_suffix_message(void *cls, const struct LookupMessage *message)
370 {
372  return GNUNET_OK;
373 }
374 
375 
383 static void
384 handle_lookup_by_suffix_message(void *cls, const struct LookupMessage *message)
385 {
386  struct GNUNET_SERVICE_Client *client = cls;
387  const char *name;
388  struct GNUNET_MQ_Envelope *env;
389  struct Ego *lprefix;
390 
392  "Received LOOKUP_BY_SUFFIX message from client\n");
393  name = (const char *)&message[1];
394  lprefix = NULL;
395  for (struct Ego *ego = ego_head; NULL != ego; ego = ego->next)
396  {
397  if ((strlen(ego->identifier) <= strlen(name)) &&
398  (0 == strcmp(ego->identifier,
399  &name[strlen(name) - strlen(ego->identifier)])) &&
400  ((strlen(name) == strlen(ego->identifier)) ||
401  ('.' == name[strlen(name) - strlen(ego->identifier) - 1])) &&
402  ((NULL == lprefix) ||
403  (strlen(ego->identifier) > strlen(lprefix->identifier))))
404  {
405  /* found better match, update! */
406  lprefix = ego;
407  }
408  }
409  if (NULL != lprefix)
410  {
411  env = create_update_message(lprefix);
414  return;
415  }
416  send_result_code(client, 0, "ego not found");
418 }
419 
420 
428 static int
430 {
431  uint16_t size;
432  uint16_t name_len;
433  const char *name;
434 
435  size = ntohs(msg->header.size);
436  if (size <= sizeof(struct GetDefaultMessage))
437  {
438  GNUNET_break(0);
439  return GNUNET_SYSERR;
440  }
441  name = (const char *)&msg[1];
442  name_len = ntohs(msg->name_len);
443  if ((name_len + sizeof(struct GetDefaultMessage) != size) ||
444  (0 != ntohs(msg->reserved)) || ('\0' != name[name_len - 1]))
445  {
446  GNUNET_break(0);
447  return GNUNET_SYSERR;
448  }
449  return GNUNET_OK;
450 }
451 
452 
461 static void
462 handle_get_default_message(void *cls, const struct GetDefaultMessage *gdm)
463 {
464  struct GNUNET_MQ_Envelope *env;
465  struct GNUNET_SERVICE_Client *client = cls;
466  struct Ego *ego;
467  char *name;
468  char *identifier;
469 
470 
471  name = GNUNET_strdup((const char *)&gdm[1]);
472  GNUNET_STRINGS_utf8_tolower((const char *)&gdm[1], name);
474  "Received GET_DEFAULT for service `%s' from client\n",
475  name);
477  name,
478  "DEFAULT_IDENTIFIER",
479  &identifier))
480  {
481  send_result_code(client, 1, gettext_noop("no default known"));
483  GNUNET_free(name);
484  return;
485  }
486  for (ego = ego_head; NULL != ego; ego = ego->next)
487  {
488  if (0 == strcmp(ego->identifier, identifier))
489  {
490  env = create_set_default_message(ego, name);
493  GNUNET_free(identifier);
494  GNUNET_free(name);
495  return;
496  }
497  }
498  GNUNET_free(identifier);
499  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Failed to find ego `%s'\n", name);
500  GNUNET_free(name);
501  send_result_code(client,
502  1,
503  gettext_noop(
504  "default configured, but ego unknown (internal error)"));
506 }
507 
508 
516 static int
518  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk2)
519 {
520  return GNUNET_memcmp(pk1, pk2);
521 }
522 
530 static int
532 {
533  uint16_t size;
534  uint16_t name_len;
535  const char *str;
536 
537  size = ntohs(msg->header.size);
538  if (size <= sizeof(struct SetDefaultMessage))
539  {
540  GNUNET_break(0);
541  return GNUNET_SYSERR;
542  }
543  name_len = ntohs(msg->name_len);
544  GNUNET_break(0 == ntohs(msg->reserved));
545  if (name_len + sizeof(struct SetDefaultMessage) != size)
546  {
547  GNUNET_break(0);
548  return GNUNET_SYSERR;
549  }
550  str = (const char *)&msg[1];
551  if ('\0' != str[name_len - 1])
552  {
553  GNUNET_break(0);
554  return GNUNET_SYSERR;
555  }
556  return GNUNET_OK;
557 }
558 
567 static void
568 handle_set_default_message(void *cls, const struct SetDefaultMessage *sdm)
569 {
570  struct Ego *ego;
571  struct GNUNET_SERVICE_Client *client = cls;
572  char *str;
573 
574  str = GNUNET_strdup((const char *)&sdm[1]);
575  GNUNET_STRINGS_utf8_tolower((const char *)&sdm[1], str);
576 
578  "Received SET_DEFAULT for service `%s' from client\n",
579  str);
580  for (ego = ego_head; NULL != ego; ego = ego->next)
581  {
582  if (0 == key_cmp(ego->pk, &sdm->private_key))
583  {
585  str,
586  "DEFAULT_IDENTIFIER",
587  ego->identifier);
588  if (GNUNET_OK !=
590  GNUNET_log(
592  _("Failed to write subsystem default identifier map to `%s'.\n"),
594  send_result_code(client, 0, NULL);
596  GNUNET_free(str);
597  return;
598  }
599  }
600  send_result_code(client,
601  1,
602  _("Unknown ego specified for service (internal error)"));
603  GNUNET_free(str);
605 }
606 
607 
613 static void
614 notify_listeners(struct Ego *ego)
615 {
616  struct UpdateMessage *um;
617  size_t name_len;
618 
619  name_len = (NULL == ego->identifier) ? 0 : (strlen(ego->identifier) + 1);
620  um = GNUNET_malloc(sizeof(struct UpdateMessage) + name_len);
622  um->header.size = htons(sizeof(struct UpdateMessage) + name_len);
623  um->name_len = htons(name_len);
624  um->end_of_list = htons(GNUNET_NO);
625  um->private_key = *ego->pk;
626  GNUNET_memcpy(&um[1], ego->identifier, name_len);
628  GNUNET_free(um);
629 }
630 
638 static int
640 {
641  uint16_t size;
642  uint16_t name_len;
643  const char *str;
644 
645  size = ntohs(msg->header.size);
646  if (size <= sizeof(struct CreateRequestMessage))
647  {
648  GNUNET_break(0);
649  return GNUNET_SYSERR;
650  }
651  name_len = ntohs(msg->name_len);
652  GNUNET_break(0 == ntohs(msg->reserved));
653  if (name_len + sizeof(struct CreateRequestMessage) != size)
654  {
655  GNUNET_break(0);
656  return GNUNET_SYSERR;
657  }
658  str = (const char *)&msg[1];
659  if ('\0' != str[name_len - 1])
660  {
661  GNUNET_break(0);
662  return GNUNET_SYSERR;
663  }
664  return GNUNET_OK;
665 }
666 
675 static void
676 handle_create_message(void *cls, const struct CreateRequestMessage *crm)
677 {
678  struct GNUNET_SERVICE_Client *client = cls;
679  struct Ego *ego;
680  char *str;
681  char *fn;
682 
683  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received CREATE message from client\n");
684  str = GNUNET_strdup((const char *)&crm[1]);
685  GNUNET_STRINGS_utf8_tolower((const char *)&crm[1], str);
686  for (ego = ego_head; NULL != ego; ego = ego->next)
687  {
688  if (0 == strcmp(ego->identifier, str))
689  {
690  send_result_code(client,
691  1,
692  gettext_noop(
693  "identifier already in use for another ego"));
695  GNUNET_free(str);
696  return;
697  }
698  }
699  ego = GNUNET_new(struct Ego);
701  *ego->pk = crm->private_key;
702  ego->identifier = GNUNET_strdup(str);
703  GNUNET_CONTAINER_DLL_insert(ego_head, ego_tail, ego);
704  send_result_code(client, 0, NULL);
705  fn = get_ego_filename(ego);
707  if (sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey) !=
709  &crm->private_key,
710  sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey),
714  GNUNET_free(fn);
715  GNUNET_free(str);
716  notify_listeners(ego);
718 }
719 
720 
728  const char *old_name;
729 
733  const char *new_name;
734 };
735 
743 static void
744 handle_ego_rename(void *cls, const char *section)
745 {
746  struct RenameContext *rc = cls;
747  char *id;
748 
750  section,
751  "DEFAULT_IDENTIFIER",
752  &id))
753  return;
754  if (0 != strcmp(id, rc->old_name))
755  {
756  GNUNET_free(id);
757  return;
758  }
760  section,
761  "DEFAULT_IDENTIFIER",
762  rc->new_name);
763  GNUNET_free(id);
764 }
765 
773 static int
774 check_rename_message(void *cls, const struct RenameMessage *msg)
775 {
776  uint16_t size;
777  uint16_t old_name_len;
778  uint16_t new_name_len;
779  const char *old_name;
780  const char *new_name;
781 
782  size = ntohs(msg->header.size);
783  if (size <= sizeof(struct RenameMessage))
784  {
785  GNUNET_break(0);
786  return GNUNET_SYSERR;
787  }
788  old_name_len = ntohs(msg->old_name_len);
789  new_name_len = ntohs(msg->new_name_len);
790  old_name = (const char *)&msg[1];
791  new_name = &old_name[old_name_len];
792  if ((old_name_len + new_name_len + sizeof(struct RenameMessage) != size) ||
793  ('\0' != old_name[old_name_len - 1]) ||
794  ('\0' != new_name[new_name_len - 1]))
795  {
796  GNUNET_break(0);
797  return GNUNET_SYSERR;
798  }
799 
800  return GNUNET_OK;
801 }
802 
803 
812 static void
813 handle_rename_message(void *cls, const struct RenameMessage *rm)
814 {
815  uint16_t old_name_len;
816  struct Ego *ego;
817  char *old_name;
818  char *new_name;
819  struct RenameContext rename_ctx;
820  struct GNUNET_SERVICE_Client *client = cls;
821  char *fn_old;
822  char *fn_new;
823  const char *old_name_tmp;
824 
825  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received RENAME message from client\n");
826  old_name_len = ntohs(rm->old_name_len);
827  old_name_tmp = (const char *)&rm[1];
828  old_name = GNUNET_strdup(old_name_tmp);
829  GNUNET_STRINGS_utf8_tolower(old_name_tmp, old_name);
830  new_name = GNUNET_strdup(&old_name_tmp[old_name_len]);
831  GNUNET_STRINGS_utf8_tolower(&old_name_tmp[old_name_len], new_name);
832 
833  /* check if new name is already in use */
834  for (ego = ego_head; NULL != ego; ego = ego->next)
835  {
836  if (0 == strcmp(ego->identifier, new_name))
837  {
838  send_result_code(client, 1, gettext_noop("target name already exists"));
840  GNUNET_free(old_name);
841  GNUNET_free(new_name);
842  return;
843  }
844  }
845 
846  /* locate old name and, if found, perform rename */
847  for (ego = ego_head; NULL != ego; ego = ego->next)
848  {
849  if (0 == strcmp(ego->identifier, old_name))
850  {
851  fn_old = get_ego_filename(ego);
852  GNUNET_free(ego->identifier);
853  rename_ctx.old_name = old_name;
854  rename_ctx.new_name = new_name;
857  &rename_ctx);
858  if (GNUNET_OK !=
860  GNUNET_log(
862  _("Failed to write subsystem default identifier map to `%s'.\n"),
864  ego->identifier = GNUNET_strdup(new_name);
865  fn_new = get_ego_filename(ego);
866  if (0 != rename(fn_old, fn_new))
868  GNUNET_free(fn_old);
869  GNUNET_free(fn_new);
870  GNUNET_free(old_name);
871  GNUNET_free(new_name);
872  notify_listeners(ego);
873  send_result_code(client, 0, NULL);
875  return;
876  }
877  }
878 
879  /* failed to locate old name */
880  send_result_code(client, 1, gettext_noop("no matching ego found"));
881  GNUNET_free(old_name);
882  GNUNET_free(new_name);
884 }
885 
886 
894 static void
895 handle_ego_delete(void *cls, const char *section)
896 {
897  const char *identifier = cls;
898  char *id;
899 
901  section,
902  "DEFAULT_IDENTIFIER",
903  &id))
904  return;
905  if (0 != strcmp(id, identifier))
906  {
907  GNUNET_free(id);
908  return;
909  }
911  section,
912  "DEFAULT_IDENTIFIER",
913  NULL);
914  GNUNET_free(id);
915 }
916 
924 static int
925 check_delete_message(void *cls, const struct DeleteMessage *msg)
926 {
927  uint16_t size;
928  uint16_t name_len;
929  const char *name;
930 
931  size = ntohs(msg->header.size);
932  if (size <= sizeof(struct DeleteMessage))
933  {
934  GNUNET_break(0);
935  return GNUNET_SYSERR;
936  }
937  name = (const char *)&msg[1];
938  name_len = ntohs(msg->name_len);
939  if ((name_len + sizeof(struct DeleteMessage) != size) ||
940  (0 != ntohs(msg->reserved)) || ('\0' != name[name_len - 1]))
941  {
942  GNUNET_break(0);
943  return GNUNET_SYSERR;
944  }
945  return GNUNET_OK;
946 }
947 
948 
957 static void
958 handle_delete_message(void *cls, const struct DeleteMessage *dm)
959 {
960  struct Ego *ego;
961  char *name;
962  char *fn;
963  struct GNUNET_SERVICE_Client *client = cls;
964 
965  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received DELETE message from client\n");
966  name = GNUNET_strdup((const char *)&dm[1]);
967  GNUNET_STRINGS_utf8_tolower((const char *)&dm[1], name);
968 
969  for (ego = ego_head; NULL != ego; ego = ego->next)
970  {
971  if (0 == strcmp(ego->identifier, name))
972  {
973  GNUNET_CONTAINER_DLL_remove(ego_head, ego_tail, ego);
976  ego->identifier);
977  if (GNUNET_OK !=
979  GNUNET_log(
981  _("Failed to write subsystem default identifier map to `%s'.\n"),
983  fn = get_ego_filename(ego);
984  if (0 != unlink(fn))
986  GNUNET_free(fn);
987  GNUNET_free(ego->identifier);
988  ego->identifier = NULL;
989  notify_listeners(ego);
990  GNUNET_free(ego->pk);
991  GNUNET_free(ego);
992  GNUNET_free(name);
993  send_result_code(client, 0, NULL);
995  return;
996  }
997  }
998 
999  send_result_code(client, 1, gettext_noop("no matching ego found"));
1000  GNUNET_free(name);
1002 }
1003 
1004 
1015 static int
1016 process_ego_file(void *cls, const char *filename)
1017 {
1018  struct Ego *ego;
1019  const char *fn;
1020 
1021  fn = strrchr(filename, (int)DIR_SEPARATOR);
1022  if (NULL == fn)
1023  {
1024  GNUNET_break(0);
1025  return GNUNET_OK;
1026  }
1027  ego = GNUNET_new(struct Ego);
1029  if (NULL == ego->pk)
1030  {
1031  GNUNET_free(ego);
1033  _("Failed to parse ego information in `%s'\n"),
1034  filename);
1035  return GNUNET_OK;
1036  }
1037  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Loaded ego `%s'\n", fn + 1);
1038  ego->identifier = GNUNET_strdup(fn + 1);
1039  GNUNET_CONTAINER_DLL_insert(ego_head, ego_tail, ego);
1040  return GNUNET_OK;
1041 }
1042 
1043 
1051 static void
1052 run(void *cls,
1053  const struct GNUNET_CONFIGURATION_Handle *c,
1055 {
1056  cfg = c;
1059  "identity",
1060  "EGODIR",
1061  &ego_directory))
1062  {
1063  GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, "identity", "EGODIR");
1065  return;
1066  }
1067  if (GNUNET_OK !=
1069  "identity",
1070  "SUBSYSTEM_CFG",
1072  {
1074  "identity",
1075  "SUBSYSTEM_CFG");
1077  return;
1078  }
1080  "Loading subsystem configuration `%s'\n",
1082  subsystem_cfg = GNUNET_CONFIGURATION_create();
1084  (GNUNET_OK !=
1086  {
1088  _(
1089  "Failed to parse subsystem identity configuration file `%s'\n"),
1092  return;
1093  }
1094  stats = GNUNET_STATISTICS_create("identity", cfg);
1096  {
1098  _("Failed to create directory `%s' for storing egos\n"),
1099  ego_directory);
1100  }
1103 }
1104 
1105 
1110  "identity",
1112  &run,
1115  NULL,
1116  GNUNET_MQ_hd_fixed_size(start_message,
1118  struct GNUNET_MessageHeader,
1119  NULL),
1120  GNUNET_MQ_hd_var_size(lookup_message,
1122  struct LookupMessage,
1123  NULL),
1124  GNUNET_MQ_hd_var_size(lookup_by_suffix_message,
1126  struct LookupMessage,
1127  NULL),
1128  GNUNET_MQ_hd_var_size(get_default_message,
1130  struct GetDefaultMessage,
1131  NULL),
1132  GNUNET_MQ_hd_var_size(set_default_message,
1134  struct SetDefaultMessage,
1135  NULL),
1136  GNUNET_MQ_hd_var_size(create_message,
1138  struct CreateRequestMessage,
1139  NULL),
1140  GNUNET_MQ_hd_var_size(rename_message,
1142  struct RenameMessage,
1143  NULL),
1144  GNUNET_MQ_hd_var_size(delete_message,
1146  struct DeleteMessage,
1147  NULL),
1149 
1150 
1151 /* 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:173
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:541
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key.
Definition: identity.h:149
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:74
Used from service to client as a result to the GET_DEFAULT message, used from client to service to SE...
Definition: identity.h:130
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:163
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:114
uint16_t reserved
Always zero.
Definition: identity.h:119
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:2424
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:586
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:1284
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE.
Definition: identity.h:79
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:139
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:114
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT.
Definition: identity.h:109
uint16_t old_name_len
Number of characters in the old name including 0-termination, in NBO.
Definition: identity.h:197
Client requests renaming of an identity.
Definition: identity.h:188
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key.
Definition: identity.h:95
#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:227
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:681
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:909
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:517
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:168
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:158
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:877
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:246
uint16_t reserved
Always zero.
Definition: identity.h:144
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:159
#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:2394
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:217
Client requests deletion of an identity.
Definition: identity.h:213
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:66
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.
const char * name
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:134
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:119
Information we keep about each ego.
uint32_t result_code
Status code for the last operation, in NBO.
Definition: identity.h:52
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:85
Handle to a message queue.
Definition: mq.c:84
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:202
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:187
static void notify_listeners(struct Ego *ego)
Send an updated message for the given ego to all listeners.
configuration data
Definition: configuration.c:83
static int key_cmp(const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk1, const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk2)
Compare the given two private keys for equality.
uint16_t end_of_list
Usually GNUNET_NO, GNUNET_YES to signal end of list.
Definition: identity.h:90
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:222
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:192
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:135
#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:351
const char * old_name
Old name.
Client requests knowledge about default identity for a subsystem from identity service.
Definition: identity.h:105
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:2258
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:2234
#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:75
#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:552
#define gettext_noop(String)
Definition: gettext.h:69