GNUnet  0.19.2
gnunet-service-abd.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2011-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 */
25 #include "platform.h"
26 
27 #include "gnunet_util_lib.h"
28 
29 #include "abd.h"
30 #include "abd_serialization.h"
31 #include "gnunet_abd_service.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_signatures.h"
35 #include <gnunet_gns_service.h>
36 #include <gnunet_gnsrecord_lib.h>
39 
40 
41 #define GNUNET_ABD_MAX_LENGTH 255
42 
43 struct VerifyRequestHandle;
44 
46 
47 
49 {
54 
59 
64 
69 
74 
79 };
80 
85 {
90 
95 
99  uint32_t refcount;
100 
105 };
106 
112 {
117 
122 
127 
132 };
133 
139 {
144 
149 
154 
159 
164 
169 
174 
179 
184 
189 
194 
199 
204 
209 
213  bool from_bw;
214 };
215 
216 
221 {
230 
235 
240 
245 
250 
255 
260 
265 
270 
275 
280 
285 
290 
294  uint32_t del_chain_size;
295 
300 
304  uint32_t request_id;
305 
309  uint64_t pending_lookups;
310 
315 
320 };
321 
322 
326 static struct VerifyRequestHandle *vrh_head = NULL;
327 
331 static struct VerifyRequestHandle *vrh_tail = NULL;
332 
337 
341 static struct GNUNET_GNS_Handle *gns;
342 
347 
348 static void
349 print_deleset (struct DelegationSetQueueEntry *dsentry, char *text)
350 {
352  "%s %s.%s <- %s.%s\n",
353  text,
360 }
361 
362 
363 static void
365 {
366  GNUNET_free (ds_entry->issuer_key);
367  GNUNET_free (ds_entry->issuer_attribute);
368  GNUNET_free (ds_entry->attr_trailer);
369  // those fields are only set/used in bw search
370  if (ds_entry->from_bw)
371  {
372  GNUNET_free (ds_entry->lookup_attribute);
374  }
375  if (NULL != ds_entry->lookup_request)
376  {
378  ds_entry->lookup_request = NULL;
379  }
380  if (NULL != ds_entry->delegation_chain_entry)
381  {
382  GNUNET_free (
386  }
387  // Free DQ entries
388  for (struct DelegationQueueEntry *dq_entry = ds_entry->queue_entries_head;
389  NULL != ds_entry->queue_entries_head;
390  dq_entry = ds_entry->queue_entries_head)
391  {
393  ds_entry->queue_entries_tail,
394  dq_entry);
395  GNUNET_free (dq_entry);
396  }
397  GNUNET_free (ds_entry);
398 }
399 
400 
401 static void
403 {
404  struct DelegateRecordEntry *del_entry;
405  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up...\n");
406 
407  if (NULL != vrh->dsq_head)
408  {
409  for (struct DelegationSetQueueEntry *ds_entry = vrh->dsq_head; NULL !=
410  vrh->dsq_head;
411  ds_entry = vrh->dsq_head)
412  {
413  GNUNET_CONTAINER_DLL_remove (vrh->dsq_head, vrh->dsq_tail, ds_entry);
414  cleanup_dsq_entry (ds_entry);
415  }
416  }
417  if (NULL != vrh->del_chain_head)
418  {
419  for (del_entry = vrh->del_chain_head; NULL != vrh->del_chain_head;
420  del_entry = vrh->del_chain_head)
421  {
423  vrh->del_chain_tail,
424  del_entry);
425  GNUNET_free (del_entry->delegate);
426  GNUNET_free (del_entry);
427  }
428  }
430  GNUNET_free (vrh);
431 }
432 
433 
434 static void
435 shutdown_task (void *cls)
436 {
437  struct VerifyRequestHandle *vrh;
438 
439  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down!\n");
440 
441  while (NULL != (vrh = vrh_head))
442  {
443  // ABD_resolver_lookup_cancel (clh->lookup);
445  cleanup_handle (vrh);
446  }
447 
448  if (NULL != gns)
449  {
451  gns = NULL;
452  }
453  if (NULL != namestore)
454  {
456  namestore = NULL;
457  }
458  if (NULL != statistics)
459  {
461  statistics = NULL;
462  }
463 }
464 
465 
466 static void
468  DelegationChainEntry *ch_entry, bool is_bw)
469 {
471  struct GNUNET_MQ_Envelope *env;
472  struct GNUNET_ABD_Delegation *dd;
473  size_t size;
474 
475  // Don't report immediate results during collect
476  if (vrh->is_collect)
477  return;
478 
479  dd = GNUNET_new (struct GNUNET_ABD_Delegation);
480  dd->issuer_key = ch_entry->issuer_key;
481  dd->subject_key = ch_entry->subject_key;
482  dd->issuer_attribute = ch_entry->issuer_attribute;
483  dd->issuer_attribute_len = strlen (ch_entry->issuer_attribute) + 1;
484  dd->subject_attribute_len = 0;
485  dd->subject_attribute = NULL;
486  if (NULL != ch_entry->subject_attribute)
487  {
488  dd->subject_attribute = ch_entry->subject_attribute;
489  dd->subject_attribute_len = strlen (ch_entry->subject_attribute) + 1;
490  }
491 
492 
494  dd,
495  0,
496  NULL);
497 
498  env = GNUNET_MQ_msg_extra (rmsg,
499  size,
501  // Assign id so that client can find associated request
502  rmsg->id = vrh->request_id;
503  rmsg->is_bw = htons (is_bw);
504  rmsg->size = htonl (size);
505 
506  GNUNET_assert (
508  dd,
509  0,
510  NULL,
511  size,
512  (char *) &rmsg[1]));
514 
515  GNUNET_free (dd);
516 }
517 
518 
519 static void
521 {
522  struct GNUNET_MQ_Envelope *env;
523  struct DelegationChainResultMessage *rmsg;
524  struct DelegationChainEntry *dce;
525  struct GNUNET_ABD_Delegation dd[vrh->delegation_chain_size];
526  struct GNUNET_ABD_Delegate dele[vrh->del_chain_size];
527  struct DelegateRecordEntry *del;
528  struct DelegateRecordEntry *tmp;
529  size_t size;
530 
531  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n");
532  dce = vrh->delegation_chain_head;
533  for (uint32_t i = 0; i < vrh->delegation_chain_size; i++)
534  {
535  dd[i].issuer_key = dce->issuer_key;
536  dd[i].subject_key = dce->subject_key;
537  dd[i].issuer_attribute = dce->issuer_attribute;
538  dd[i].issuer_attribute_len = strlen (dce->issuer_attribute) + 1;
539  dd[i].subject_attribute_len = 0;
540  dd[i].subject_attribute = NULL;
541  if (NULL != dce->subject_attribute)
542  {
544  dd[i].subject_attribute_len = strlen (dce->subject_attribute) + 1;
545  }
546  dce = dce->next;
547  }
548 
549  // Remove all not needed credentials
550  for (del = vrh->del_chain_head; NULL != del;)
551  {
552  if (del->refcount > 0)
553  {
554  del = del->next;
555  continue;
556  }
557  tmp = del;
558  del = del->next;
560  GNUNET_free (tmp->delegate);
561  GNUNET_free (tmp);
562  vrh->del_chain_size--;
563  }
564 
565  // Get serialized record data
566  // Append at the end of rmsg
567  del = vrh->del_chain_head;
568  for (uint32_t i = 0; i < vrh->del_chain_size; i++)
569  {
570  dele[i].issuer_key = del->delegate->issuer_key;
571  dele[i].subject_key = del->delegate->subject_key;
572  dele[i].issuer_attribute_len = strlen (del->delegate->issuer_attribute) + 1;
573  dele[i].issuer_attribute = del->delegate->issuer_attribute;
574  dele[i].subject_attribute_len = del->delegate->subject_attribute_len;
575  dele[i].subject_attribute = del->delegate->subject_attribute;
576  dele[i].expiration = del->delegate->expiration;
577  dele[i].signature = del->delegate->signature;
578  del = del->next;
579  }
580  size =
582  dd,
583  vrh->del_chain_size,
584  dele);
585  env = GNUNET_MQ_msg_extra (rmsg,
586  size,
588  // Assign id so that client can find associated request
589  rmsg->id = vrh->request_id;
590  rmsg->d_count = htonl (vrh->delegation_chain_size);
591  rmsg->c_count = htonl (vrh->del_chain_size);
592 
593  if (0 < vrh->del_chain_size)
594  rmsg->del_found = htonl (GNUNET_YES);
595  else
596  rmsg->del_found = htonl (GNUNET_NO);
597 
598  GNUNET_assert (
599  -1 !=
601  dd,
602  vrh->del_chain_size,
603  dele,
604  size,
605  (char *) &rmsg[1]));
606 
609  cleanup_handle (vrh);
611  "Completed verifications",
612  1,
613  GNUNET_NO);
614 }
615 
616 
617 static char *
618 partial_match (char *tmp_trail,
619  char *tmp_subattr,
620  char *parent_trail,
621  char *issuer_attribute)
622 {
623  char *saveptr1, *saveptr2;
624  char *trail_token;
625  char *sub_token;
626  char *attr_trailer;
627 
628  // tok both, parent->attr_trailer and del->sub_attr to see how far they match,
629  // take rest of parent trailer (only when del->sub_attr token is null), and
630  // create new/actual trailer with del->iss_attr
631  trail_token = strtok_r (tmp_trail, ".", &saveptr1);
632  sub_token = strtok_r (tmp_subattr, ".", &saveptr2);
633  while (NULL != trail_token && NULL != sub_token)
634  {
635  if (0 == strcmp (trail_token, sub_token))
636  {
637  // good, matches, remove
638  }
639  else
640  {
641  // not relevant for solving the chain, end for iteration here
642  return NULL;
643  }
644 
645  trail_token = strtok_r (NULL, ".", &saveptr1);
646  sub_token = strtok_r (NULL, ".", &saveptr2);
647  }
648  // skip this entry and go to next for if:
649  // 1. at some point the attr of the trailer and the subject dont match
650  // 2. the trailer is NULL, but the subject has more attributes
651  // Reason: This will lead to "startzone.attribute" but we're looking for a solution
652  // for "<- startzone"
653  if (NULL == trail_token)
654  {
655  return NULL;
656  }
657 
658  // do not have to check sub_token == NULL, if both would be NULL
659  // at the same time, the complete match part above should have triggered already
660 
661  // otherwise, above while only ends when sub_token == NULL
662  GNUNET_asprintf (&attr_trailer, "%s", trail_token);
663  trail_token = strtok_r (NULL, ".", &saveptr1);
664  while (NULL != trail_token)
665  {
666  GNUNET_asprintf (&attr_trailer, "%s.%s", parent_trail, trail_token);
667  trail_token = strtok_r (NULL, ".", &saveptr1);
668  }
669  GNUNET_asprintf (&attr_trailer, "%s.%s", issuer_attribute, attr_trailer);
670  return attr_trailer;
671 }
672 
673 
674 static int
676  struct DelegationSetQueueEntry *match_entry,
677  struct VerifyRequestHandle *vrh)
678 {
679  struct DelegationSetQueueEntry *old_fw_parent;
680  struct DelegationSetQueueEntry *fw_entry = actual_entry;
681  struct DelegationSetQueueEntry *last_entry = match_entry;
682  // parent fixing, combine backward and forward chain parts
683  while (NULL != fw_entry->parent_queue_entry)
684  {
685  old_fw_parent = fw_entry->parent_queue_entry->parent_set;
686  // set parent
687  fw_entry->parent_queue_entry->parent_set = last_entry;
688 
689  last_entry = fw_entry;
690  fw_entry = old_fw_parent;
691  }
692  // set last entry of chain as actual_entry
693  // actual_entry = last_entry;
694  // set refcount, loop all delegations
695  for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head;
696  del_entry != NULL;
697  del_entry = del_entry->next)
698  {
699  if (0 != memcmp (&last_entry->delegation_chain_entry->subject_key,
700  &del_entry->delegate->issuer_key,
701  sizeof (struct GNUNET_IDENTITY_PublicKey)))
702  continue;
703  if (0 != strcmp (last_entry->delegation_chain_entry->subject_attribute,
704  del_entry->delegate->issuer_attribute))
705  continue;
706 
707  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found delegate.\n");
708  // increase refcount of the start delegation
709  del_entry->refcount++;
710  }
711  // backtrack
712  for (struct DelegationSetQueueEntry *tmp_set = last_entry;
713  NULL != tmp_set->parent_queue_entry;
714  tmp_set = tmp_set->parent_queue_entry->parent_set)
715  {
716  tmp_set->parent_queue_entry->required_solutions--;
717 
718  // add new found entry to vrh
719  vrh->delegation_chain_size++;
722  tmp_set->delegation_chain_entry);
723 
724  // if one node on the path still needs solutions, this current
725  // patch cannot fulfill the conditions and therefore stops here
726  // however, it is in the vrh and can be used by the other paths
727  // related to this path/collection/verification
728  if (0 < tmp_set->parent_queue_entry->required_solutions)
729  {
731  "Chain requires more solutions, waiting...\n");
732  return GNUNET_NO;
733  }
734  }
735  return GNUNET_YES;
736 }
737 
738 
739 static void
741  uint32_t rd_count,
742  const struct GNUNET_GNSRECORD_Data *rd)
743 {
744  struct VerifyRequestHandle *vrh;
745  struct DelegationSetQueueEntry *current_set;
746  struct DelegationSetQueueEntry *ds_entry;
747  struct DelegationQueueEntry *dq_entry;
748  struct GNUNET_ABD_Delegate *del;
749 
750  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d entries.\n", rd_count);
751 
752  current_set = cls;
753  // set handle to NULL (as el = NULL)
754  current_set->lookup_request = NULL;
755  vrh = current_set->handle;
756  vrh->pending_lookups--;
757 
758  // Loop record entries
759  for (uint32_t i = 0; i < rd_count; i++)
760  {
761  if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type)
762  continue;
763 
764  // Start deserialize into Delegate
766 
767  if (NULL == del)
768  continue;
769 
770  // Start: Create DQ Entry
771  dq_entry = GNUNET_new (struct DelegationQueueEntry);
772  // AND delegations are not possible, only 1 solution
773  dq_entry->required_solutions = 1;
774  dq_entry->parent_set = current_set;
775 
776  // Insert it into the current set
778  current_set->queue_entries_tail,
779  dq_entry);
780 
781  // Start: Create DS Entry
782  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
783  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
784  ds_entry->from_bw = false;
785 
786  // (1) A.a <- A.b.c
787  // (2) A.b <- D.d
788  // (3) D.d <- E
789  // (4) E.c <- F.c
790  // (5) F.c <- G
791  // Possibilities:
792  // 1. complete match: trailer = 0, validate
793  // 2. partial match: replace
794  // 3. new solution: replace, add trailer
795 
796  // At resolution chain start trailer of parent is NULL
797  if (NULL == current_set->attr_trailer)
798  {
799  // for (5) F.c <- G, remember .c when going upwards
800  ds_entry->attr_trailer = GNUNET_strdup (del->issuer_attribute);
801  }
802  else
803  {
804  if (0 == del->subject_attribute_len)
805  {
806  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: New solution\n");
807  // new solution
808  // create new trailer del->issuer_attribute, ds_entry->attr_trailer
809  GNUNET_asprintf (&ds_entry->attr_trailer,
810  "%s.%s",
811  del->issuer_attribute,
812  current_set->attr_trailer);
813  }
814  else if (0 == strcmp (del->subject_attribute, current_set->attr_trailer))
815  {
816  // complete match
817  // new trailer == issuer attribute (e.g. (5) to (4))
818  ds_entry->attr_trailer = GNUNET_strdup (del->issuer_attribute);
819  }
820  else
821  {
822  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Partial match\n");
823  // partial match
824 
825  char *trail = partial_match (GNUNET_strdup (current_set->attr_trailer),
826  GNUNET_strdup (del->subject_attribute),
827  current_set->attr_trailer,
828  GNUNET_strdup (del->issuer_attribute));
829 
830  // if null: skip this record entry (reasons: mismatch or overmatch, both not relevant)
831  if (NULL == trail)
832  {
834  "Entry not relevant, discarding: %s.%s <- %s.%s\n",
836  &del->issuer_key),
837  del->issuer_attribute,
839  &del->subject_key),
840  del->subject_attribute);
841  GNUNET_free (del);
842  continue;
843  }
844  else
845  ds_entry->attr_trailer = trail;
846  }
847  }
848 
849 
850  // Start: Credential Chain Entry
851  // issuer key is subject key, who needs to be contacted to resolve this (forward, therefore subject)
852  ds_entry->issuer_key = GNUNET_new (struct GNUNET_IDENTITY_PublicKey);
853  GNUNET_memcpy (ds_entry->issuer_key,
854  &del->subject_key,
855  sizeof (struct GNUNET_IDENTITY_PublicKey));
856 
858  ds_entry->delegation_chain_entry->subject_key = del->subject_key;
859  if (0 < del->subject_attribute_len)
861  GNUNET_strdup (del->subject_attribute);
862  ds_entry->delegation_chain_entry->issuer_key = del->issuer_key;
864  GNUNET_strdup (del->issuer_attribute);
865 
866  // Found new entry, repoting intermediate result
867  send_intermediate_response (vrh, ds_entry->delegation_chain_entry, false);
868 
869  // current delegation as parent
870  ds_entry->parent_queue_entry = dq_entry;
871 
872  // Check for solution
873  // if: issuer key we looking for
874  if (0 == memcmp (&del->issuer_key,
875  &vrh->issuer_key,
876  sizeof (struct GNUNET_IDENTITY_PublicKey)))
877  {
878  // if: issuer attr we looking for
879  if (0 == strcmp (del->issuer_attribute, vrh->issuer_attribute))
880  {
881  // if: complete match, meaning new trailer == issuer attr
882  if (0 == strcmp (vrh->issuer_attribute, ds_entry->attr_trailer))
883  {
884  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Solution\n");
885 
886  // Add found solution into delegation_chain
887  struct DelegationSetQueueEntry *tmp_set;
888  for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
889  tmp_set = tmp_set->parent_queue_entry->parent_set)
890  {
891  if (NULL != tmp_set->delegation_chain_entry)
892  {
893  vrh->delegation_chain_size++;
896  tmp_set->delegation_chain_entry);
897  }
898  }
899 
900  // Increase refcount for this delegate
901  for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head;
902  del_entry != NULL;
903  del_entry = del_entry->next)
904  {
905  if (0 == memcmp (&del_entry->delegate->issuer_key,
907  sizeof (struct GNUNET_IDENTITY_PublicKey)))
908  {
909  if (0 == strcmp (del_entry->delegate->issuer_attribute,
911  {
912  del_entry->refcount++;
913  }
914  }
915  }
916 
917  send_lookup_response (vrh);
918  GNUNET_free (del);
919  return;
920  }
921  }
922  }
923 
924  // Check for bidirectional crossmatch
925  for (struct DelegationSetQueueEntry *del_entry = vrh->dsq_head;
926  del_entry != NULL;
927  del_entry = del_entry->next)
928  {
929  // only check entries not by backward algorithm
930  if (del_entry->from_bw)
931  {
932  // key of list entry matches actual key
933  if (0 == memcmp (&del_entry->delegation_chain_entry->subject_key,
935  sizeof (struct GNUNET_IDENTITY_PublicKey)))
936  {
937  // compare entry subject attributes to this trailer (iss attr + old trailer)
938  if (0 == strcmp (del_entry->unresolved_attribute_delegation,
939  ds_entry->attr_trailer))
940  {
941  print_deleset (del_entry, "Forward:");
943  "Forward: Found match with above!\n");
944 
945  GNUNET_free (del);
946  // one node on the path still needs solutions: return
947  if (GNUNET_NO ==
948  handle_bidirectional_match (ds_entry, del_entry, vrh))
949  return;
950 
951  send_lookup_response (vrh);
952  return;
953  }
954  }
955  }
956  }
957 
958  // Starting a new GNS lookup
959  vrh->pending_lookups++;
960  ds_entry->handle = vrh;
961 
963  "Starting to look up trailer %s in zone %s\n",
964  ds_entry->attr_trailer,
966 
967  ds_entry->lookup_request =
970  &del->issuer_key,
974  ds_entry);
975  GNUNET_free (del);
976  }
977 
978  if (0 == vrh->pending_lookups)
979  {
980  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
981  send_lookup_response (vrh);
982  return;
983  }
984 }
985 
986 
987 static void
989  uint32_t rd_count,
990  const struct GNUNET_GNSRECORD_Data *rd)
991 {
992  struct VerifyRequestHandle *vrh;
993  const struct GNUNET_ABD_DelegationRecord *sets;
994  struct DelegateRecordEntry *del_pointer;
995  struct DelegationSetQueueEntry *current_set;
996  struct DelegationSetQueueEntry *ds_entry;
997  struct DelegationSetQueueEntry *tmp_set;
998  struct DelegationQueueEntry *dq_entry;
999  char *expanded_attr;
1000  char *lookup_attribute;
1001 
1002  current_set = cls;
1003  current_set->lookup_request = NULL;
1004  vrh = current_set->handle;
1005  vrh->pending_lookups--;
1006 
1007  // Each OR
1008  for (uint32_t i = 0; i < rd_count; i++)
1009  {
1010  if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
1011  continue;
1012 
1013  sets = rd[i].data;
1014  struct GNUNET_ABD_DelegationSet set[ntohl (sets->set_count)];
1016  "Found new attribute delegation with %d sets. Creating new Job...\n",
1017  ntohl (sets->set_count));
1018 
1019  if (GNUNET_OK !=
1021  sets->data_size),
1022  (const char *) &sets[1],
1023  ntohl (sets->set_count),
1024  set))
1025  {
1026  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n");
1027  continue;
1028  }
1029  dq_entry = GNUNET_new (struct DelegationQueueEntry);
1030  dq_entry->required_solutions = ntohl (sets->set_count);
1031  dq_entry->parent_set = current_set;
1032 
1034  current_set->queue_entries_tail,
1035  dq_entry);
1036  // Each AND
1037  for (uint32_t j = 0; j < ntohl (sets->set_count); j++)
1038  {
1039  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1040  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1041  ds_entry->from_bw = true;
1042 
1043  if (NULL != current_set->attr_trailer)
1044  {
1045  if (0 == set[j].subject_attribute_len)
1046  {
1047  GNUNET_asprintf (&expanded_attr, "%s", current_set->attr_trailer);
1048  }
1049  else
1050  {
1051  GNUNET_asprintf (&expanded_attr,
1052  "%s.%s",
1053  set[j].subject_attribute,
1054  current_set->attr_trailer);
1055  }
1056  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expanded to %s\n", expanded_attr);
1057  ds_entry->unresolved_attribute_delegation = expanded_attr;
1058  }
1059  else
1060  {
1061  if (0 != set[j].subject_attribute_len)
1062  {
1064  "Not Expanding %s\n",
1065  set[j].subject_attribute);
1068  }
1069  }
1070 
1071  // Add a credential chain entry
1072  ds_entry->delegation_chain_entry =
1074  ds_entry->delegation_chain_entry->subject_key = set[j].subject_key;
1075  ds_entry->issuer_key = GNUNET_new (struct GNUNET_IDENTITY_PublicKey);
1076  GNUNET_memcpy (ds_entry->issuer_key,
1077  &set[j].subject_key,
1078  sizeof (struct GNUNET_IDENTITY_PublicKey));
1079  if (0 < set[j].subject_attribute_len)
1082  ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key;
1084  GNUNET_strdup (current_set->lookup_attribute);
1085 
1086  // Found new entry, repoting intermediate result
1087  send_intermediate_response (vrh, ds_entry->delegation_chain_entry, true);
1088 
1089  ds_entry->parent_queue_entry = dq_entry; // current_delegation;
1090 
1094  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking for cred match\n");
1095 
1096  for (del_pointer = vrh->del_chain_head; del_pointer != NULL;
1097  del_pointer = del_pointer->next)
1098  {
1099  // If key and attribute match credential: continue and backtrack
1100  if (0 != memcmp (&set[j].subject_key,
1101  &del_pointer->delegate->issuer_key,
1102  sizeof (struct GNUNET_IDENTITY_PublicKey)))
1103  continue;
1105  "Checking if %s matches %s\n",
1107  del_pointer->delegate->issuer_attribute);
1108 
1109  if (0 != strcmp (ds_entry->unresolved_attribute_delegation,
1110  del_pointer->delegate->issuer_attribute))
1111  continue;
1112 
1113  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n");
1114  // increase refcount of the start delegation
1115  del_pointer->refcount++;
1116 
1117  // Backtrack
1118  for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
1119  tmp_set = tmp_set->parent_queue_entry->parent_set)
1120  {
1122  if (NULL != tmp_set->delegation_chain_entry)
1123  {
1124  vrh->delegation_chain_size++;
1126  vrh->delegation_chain_tail,
1127  tmp_set->delegation_chain_entry);
1128  }
1129  if (0 < tmp_set->parent_queue_entry->required_solutions)
1130  break;
1131  }
1132 
1133  // if the break above is not called the condition of the for is met
1134  if (NULL == tmp_set->parent_queue_entry)
1135  {
1136  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All solutions found\n");
1137  // Found match
1138  send_lookup_response (vrh);
1139  return;
1140  }
1141  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not all solutions found yet.\n");
1142  continue;
1143  }
1144 
1146  "Building new lookup request from %s\n",
1148  // Continue with next/new backward resolution
1149  char issuer_attribute_name[strlen (
1151  + 1];
1152  strcpy (issuer_attribute_name, ds_entry->unresolved_attribute_delegation);
1153  char *next_attr = strtok (issuer_attribute_name, ".");
1154  if (NULL == next_attr)
1155  {
1157  "Failed to parse next attribute\n");
1158  continue;
1159  }
1160  GNUNET_asprintf (&lookup_attribute, "%s", next_attr);
1161  GNUNET_asprintf (&ds_entry->lookup_attribute, "%s", next_attr);
1162  if (strlen (next_attr) ==
1163  strlen (ds_entry->unresolved_attribute_delegation))
1164  {
1165  ds_entry->attr_trailer = NULL;
1166  }
1167  else
1168  {
1169  next_attr += strlen (next_attr) + 1;
1170  ds_entry->attr_trailer = GNUNET_strdup (next_attr);
1171  }
1172 
1173  // Check for bidirectional crossmatch
1174  for (struct DelegationSetQueueEntry *del_entry = vrh->dsq_head;
1175  del_entry != NULL;
1176  del_entry = del_entry->next)
1177  {
1178  // only check entries added by forward algorithm
1179  if (! del_entry->from_bw)
1180  {
1181  // key of list entry matches actual key
1182  if (0 == memcmp (&del_entry->delegation_chain_entry->issuer_key,
1183  &ds_entry->delegation_chain_entry->subject_key,
1184  sizeof (struct GNUNET_IDENTITY_PublicKey)))
1185  {
1186  // compare entry subject attributes to this trailer (iss attr + old trailer)
1187  if (0 == strcmp (del_entry->attr_trailer,
1189  {
1190  print_deleset (del_entry, "Backward:");
1192  "Backward: Found match with above!\n");
1193 
1194  // if one node on the path still needs solutions: return
1195  if (GNUNET_NO ==
1196  handle_bidirectional_match (del_entry, ds_entry, vrh))
1197  break;
1198 
1199  // Send lookup response
1200  send_lookup_response (vrh);
1201  return;
1202  }
1203  }
1204  }
1205  }
1206 
1207  // Starting a new GNS lookup
1209  "Looking up %s\n",
1210  ds_entry->lookup_attribute);
1211  if (NULL != ds_entry->attr_trailer)
1213  "%s still to go...\n",
1214  ds_entry->attr_trailer);
1215 
1216  vrh->pending_lookups++;
1217  ds_entry->handle = vrh;
1218  ds_entry->lookup_request =
1220  lookup_attribute,
1221  ds_entry->issuer_key, // issuer_key,
1225  ds_entry);
1226 
1227  GNUNET_free (lookup_attribute);
1228  }
1229  }
1230 
1231  if (0 == vrh->pending_lookups)
1232  {
1233  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
1234  send_lookup_response (vrh);
1235  return;
1236  }
1237 }
1238 
1239 
1245 static int
1247 {
1248  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Start Backward Resolution...\n");
1249 
1250  struct VerifyRequestHandle *vrh = cls;
1251  struct DelegationSetQueueEntry *ds_entry;
1252  struct DelegateRecordEntry *del_entry;
1253 
1254  if (0 == vrh->del_chain_size)
1255  {
1256  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegates found\n");
1257  send_lookup_response (vrh);
1258  return 1;
1259  }
1260 
1261  // Pre-check with vrh->dele_chain_.. if match issuer_key
1262  // Backward: check every cred entry if match issuer key
1263  // otherwise: start at issuer and go down till match
1264  // A.a <- ...
1265  // X.x <- C
1266  // Y.y <- C
1267  // if not X.x or Y.y == A.a start at A
1268  for (del_entry = vrh->del_chain_head; del_entry != NULL;
1269  del_entry = del_entry->next)
1270  {
1271  if (0 != memcmp (&del_entry->delegate->issuer_key,
1272  &vrh->issuer_key,
1273  sizeof (struct GNUNET_IDENTITY_PublicKey)))
1274  continue;
1275  if (0 !=
1276  strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute))
1277  continue;
1278  del_entry->refcount++;
1279  // Found match prematurely
1280  send_lookup_response (vrh);
1281  return 1;
1282  }
1283 
1284 
1285  // Check for attributes from the issuer and follow the chain
1286  // till you get the required subject's attributes
1287  char issuer_attribute_name[strlen (vrh->issuer_attribute) + 1];
1288  strcpy (issuer_attribute_name, vrh->issuer_attribute);
1290  "Looking up %s\n",
1291  issuer_attribute_name);
1292  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1293  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1294  ds_entry->from_bw = true;
1295  ds_entry->issuer_key = GNUNET_new (struct GNUNET_IDENTITY_PublicKey);
1296  GNUNET_memcpy (ds_entry->issuer_key,
1297  &vrh->issuer_key,
1298  sizeof (struct GNUNET_IDENTITY_PublicKey));
1299  ds_entry->issuer_attribute = GNUNET_strdup (vrh->issuer_attribute);
1300 
1302  ds_entry->delegation_chain_entry->issuer_key = vrh->issuer_key;
1305 
1306  ds_entry->handle = vrh;
1307  ds_entry->lookup_attribute = GNUNET_strdup (vrh->issuer_attribute);
1308  ds_entry->unresolved_attribute_delegation = NULL;
1309  vrh->pending_lookups = 1;
1310 
1311  // Start with backward resolution
1312  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start Backward Resolution\n");
1313 
1314  ds_entry->lookup_request = GNUNET_GNS_lookup (gns,
1315  issuer_attribute_name,
1316  &vrh->issuer_key, // issuer_key,
1320  ds_entry);
1321  return 0;
1322 }
1323 
1324 
1325 static int
1327 {
1328  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Start Forward Resolution...\n");
1329 
1330  struct VerifyRequestHandle *vrh = cls;
1331  struct DelegationSetQueueEntry *ds_entry;
1332  struct DelegateRecordEntry *del_entry;
1333 
1334  // set to 0 and increase on each lookup: for fw multiple lookups (may be) started
1335  vrh->pending_lookups = 0;
1336 
1337  if (0 == vrh->del_chain_size)
1338  {
1339  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegations found\n");
1340  send_lookup_response (vrh);
1341  return 1;
1342  }
1343 
1344  // Pre-check with vrh->dele_chain_.. if match issuer_key
1345  // otherwise FW: start multiple lookups for each vrh->dele_chain
1346  // A.a <- ...
1347  // X.x <- C
1348  // Y.y <- C
1349  // if not X.x or Y.y == A.a start at X and at Y
1350  for (del_entry = vrh->del_chain_head; del_entry != NULL;
1351  del_entry = del_entry->next)
1352  {
1353  if (0 != memcmp (&del_entry->delegate->issuer_key,
1354  &vrh->issuer_key,
1355  sizeof (struct GNUNET_IDENTITY_PublicKey)))
1356  continue;
1357  if (0 !=
1358  strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute))
1359  continue;
1360  del_entry->refcount++;
1361  // Found match prematurely
1362  send_lookup_response (vrh);
1363  return 1;
1364  }
1365 
1366  // None match, therefore start for every delegation found a lookup chain
1367  // Return and end collect process on first chain iss <-> sub found
1368 
1369  // ds_entry created belongs to the first lookup, vrh still has the
1370  // issuer+attr we look for
1371  for (del_entry = vrh->del_chain_head; del_entry != NULL;
1372  del_entry = del_entry->next)
1373  {
1374 
1376  "Looking for %s.%s\n",
1378  &del_entry->delegate->issuer_key),
1379  del_entry->delegate->issuer_attribute);
1380 
1381  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1382  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1383  ds_entry->from_bw = false;
1384  ds_entry->issuer_key = GNUNET_new (struct GNUNET_IDENTITY_PublicKey);
1385  GNUNET_memcpy (ds_entry->issuer_key,
1386  &del_entry->delegate->subject_key,
1387  sizeof (struct GNUNET_IDENTITY_PublicKey));
1388 
1390  ds_entry->delegation_chain_entry->subject_key =
1391  del_entry->delegate->subject_key;
1392  ds_entry->delegation_chain_entry->subject_attribute = NULL;
1393  ds_entry->delegation_chain_entry->issuer_key =
1394  del_entry->delegate->issuer_key;
1396  GNUNET_strdup (del_entry->delegate->issuer_attribute);
1397 
1398  ds_entry->attr_trailer =
1399  GNUNET_strdup (del_entry->delegate->issuer_attribute);
1400  ds_entry->handle = vrh;
1401 
1402  vrh->pending_lookups++;
1403  // Start with forward resolution
1404  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start Forward Resolution\n");
1405 
1406  ds_entry->lookup_request =
1409  &del_entry->delegate->issuer_key, // issuer_key,
1413  ds_entry);
1414  }
1415  return 0;
1416 }
1417 
1418 
1419 static int
1420 check_verify (void *cls, const struct VerifyMessage *v_msg)
1421 {
1422  size_t msg_size;
1423  const char *attr;
1424 
1425  msg_size = ntohs (v_msg->header.size);
1426  if (msg_size < sizeof (struct VerifyMessage))
1427  {
1428  GNUNET_break (0);
1429  return GNUNET_SYSERR;
1430  }
1431  if (ntohs (v_msg->issuer_attribute_len) > GNUNET_ABD_MAX_LENGTH)
1432  {
1433  GNUNET_break (0);
1434  return GNUNET_SYSERR;
1435  }
1436  attr = (const char *) &v_msg[1];
1437 
1438  if (strlen (attr) > GNUNET_ABD_MAX_LENGTH)
1439  {
1440  GNUNET_break (0);
1441  return GNUNET_SYSERR;
1442  }
1443  return GNUNET_OK;
1444 }
1445 
1446 
1447 static void
1448 handle_verify (void *cls, const struct VerifyMessage *v_msg)
1449 {
1450  struct VerifyRequestHandle *vrh;
1451  struct GNUNET_SERVICE_Client *client = cls;
1452  struct DelegateRecordEntry *del_entry;
1453  uint32_t delegate_count;
1454  uint32_t delegate_data_size;
1455  char attr[GNUNET_ABD_MAX_LENGTH + 1];
1456  char issuer_attribute[GNUNET_ABD_MAX_LENGTH + 1];
1457  char *attrptr = attr;
1458  char *delegate_data;
1459  const char *utf_in;
1460 
1461  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n");
1462  utf_in = (const char *) &v_msg[1];
1463  GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1464  GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len));
1465  issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0';
1466  vrh = GNUNET_new (struct VerifyRequestHandle);
1467  vrh->is_collect = false;
1469  vrh->client = client;
1470  vrh->request_id = v_msg->id;
1471  vrh->issuer_key = v_msg->issuer_key;
1472  vrh->subject_key = v_msg->subject_key;
1473  vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1474  vrh->resolution_algo = ntohs (v_msg->resolution_algo);
1475 
1476  vrh->del_chain_head = NULL;
1477  vrh->del_chain_tail = NULL;
1478  vrh->dsq_head = NULL;
1479  vrh->dsq_tail = NULL;
1480  vrh->del_chain_head = NULL;
1481  vrh->del_chain_tail = NULL;
1482 
1484  if (0 == strlen (issuer_attribute))
1485  {
1486  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1487  send_lookup_response (vrh);
1488  return;
1489  }
1490 
1491  // Parse delegates from verifaction message
1492  delegate_count = ntohl (v_msg->d_count);
1493  delegate_data_size = ntohs (v_msg->header.size)
1494  - sizeof (struct VerifyMessage)
1495  - ntohs (v_msg->issuer_attribute_len) - 1;
1496  struct GNUNET_ABD_Delegate delegates[delegate_count];
1497  memset (delegates,
1498  0,
1499  sizeof (struct GNUNET_ABD_Delegate) * delegate_count);
1500  delegate_data = (char *) &v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1;
1501  if (GNUNET_OK != GNUNET_ABD_delegates_deserialize (delegate_data_size,
1502  delegate_data,
1503  delegate_count,
1504  delegates))
1505  {
1506  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot deserialize delegates!\n");
1507  send_lookup_response (vrh);
1508  return;
1509  }
1510 
1511  // Prepare vrh delegation chain for later validation
1512  for (uint32_t i = 0; i < delegate_count; i++)
1513  {
1514  del_entry = GNUNET_new (struct DelegateRecordEntry);
1515  del_entry->delegate =
1516  GNUNET_malloc (sizeof (struct GNUNET_ABD_Delegate)
1517  + delegates[i].issuer_attribute_len + 1);
1518  GNUNET_memcpy (del_entry->delegate,
1519  &delegates[i],
1520  sizeof (struct GNUNET_ABD_Delegate));
1521  GNUNET_memcpy (&del_entry->delegate[1],
1522  delegates[i].issuer_attribute,
1523  delegates[i].issuer_attribute_len);
1524  del_entry->delegate->issuer_attribute_len =
1525  delegates[i].issuer_attribute_len;
1526  del_entry->delegate->issuer_attribute = (char *) &del_entry->delegate[1];
1528  vrh->del_chain_tail,
1529  del_entry);
1530  vrh->del_chain_size++;
1531  }
1532 
1533  // Switch resolution algo
1536  {
1537  if (1 == delegation_chain_fw_resolution_start (vrh))
1538  return;
1540  }
1541  else if (GNUNET_ABD_FLAG_BACKWARD & vrh->resolution_algo)
1542  {
1544  }
1545  else if (GNUNET_ABD_FLAG_FORWARD & vrh->resolution_algo)
1546  {
1548  }
1549 }
1550 
1551 
1552 static void
1554 {
1555  struct VerifyRequestHandle *vrh = cls;
1557  "Got disconnected from namestore database.\n");
1558  vrh->dele_qe = NULL;
1559  send_lookup_response (vrh);
1560 }
1561 
1562 
1563 static void
1565 {
1566  struct VerifyRequestHandle *vrh = cls;
1567  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done collecting delegates.\n");
1568 
1569  // if both are set: bidirectional search, meaning start both chain resolutions
1572  {
1573  // if premature match found don't start bw resolution
1574  if (1 == delegation_chain_fw_resolution_start (vrh))
1575  return;
1577  }
1578  else if (GNUNET_ABD_FLAG_BACKWARD & vrh->resolution_algo)
1579  {
1581  }
1582  else if (GNUNET_ABD_FLAG_FORWARD & vrh->resolution_algo)
1583  {
1585  }
1586 }
1587 
1588 
1589 static void
1591  const struct GNUNET_IDENTITY_PrivateKey *key,
1592  const char *label,
1593  unsigned int rd_count,
1594  const struct GNUNET_GNSRECORD_Data *rd)
1595 {
1596  struct VerifyRequestHandle *vrh = cls;
1597  struct DelegateRecordEntry *del_entry;
1598  vrh->dele_qe = NULL;
1599 
1600  for (uint32_t i = 0; i < rd_count; i++)
1601  {
1602  if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type)
1603  continue;
1604  // only add the entries that are explicitly marked as private
1605  // and therefore symbolize the end of a chain
1606  if (0 == (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))
1607  continue;
1608  del_entry = GNUNET_new (struct DelegateRecordEntry);
1610  if (NULL == del_entry->delegate)
1611  {
1612  GNUNET_free (del_entry);
1613  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid delegate found\n");
1614  continue;
1615  }
1617  vrh->del_chain_tail,
1618  del_entry);
1619  vrh->del_chain_size++;
1620  }
1621 
1623 }
1624 
1625 
1626 static void
1627 handle_collect (void *cls, const struct CollectMessage *c_msg)
1628 {
1629  char attr[GNUNET_ABD_MAX_LENGTH + 1];
1630  char issuer_attribute[GNUNET_ABD_MAX_LENGTH + 1];
1631  struct VerifyRequestHandle *vrh;
1632  struct GNUNET_SERVICE_Client *client = cls;
1633  char *attrptr = attr;
1634  const char *utf_in;
1635 
1636  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received COLLECT message\n");
1637 
1638  utf_in = (const char *) &c_msg[1];
1639  GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1640 
1641  GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len));
1642  issuer_attribute[ntohs (c_msg->issuer_attribute_len)] = '\0';
1643  vrh = GNUNET_new (struct VerifyRequestHandle);
1644  vrh->is_collect = true;
1646  vrh->client = client;
1647  vrh->request_id = c_msg->id;
1648  vrh->issuer_key = c_msg->issuer_key;
1650  vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1651  vrh->resolution_algo = ntohs (c_msg->resolution_algo);
1652 
1653  vrh->del_chain_head = NULL;
1654  vrh->del_chain_tail = NULL;
1655  vrh->dsq_head = NULL;
1656  vrh->dsq_tail = NULL;
1657  vrh->del_chain_head = NULL;
1658  vrh->del_chain_tail = NULL;
1659 
1660  if (0 == strlen (issuer_attribute))
1661  {
1662  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1663  send_lookup_response (vrh);
1664  return;
1665  }
1666  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting delegates for subject\n");
1667 
1668  // Get all delegates from subject
1669  vrh->dele_qe =
1671  &c_msg->subject_key,
1674  vrh,
1676  vrh);
1678 }
1679 
1680 
1681 static int
1682 check_collect (void *cls, const struct CollectMessage *c_msg)
1683 {
1684  size_t msg_size;
1685  const char *attr;
1686 
1687  msg_size = ntohs (c_msg->header.size);
1688  if (msg_size < sizeof (struct CollectMessage))
1689  {
1690  GNUNET_break (0);
1691  return GNUNET_SYSERR;
1692  }
1693  if (ntohs (c_msg->issuer_attribute_len) > GNUNET_ABD_MAX_LENGTH)
1694  {
1695  GNUNET_break (0);
1696  return GNUNET_SYSERR;
1697  }
1698  attr = (const char *) &c_msg[1];
1699 
1700  if (('\0' != attr[msg_size - sizeof (struct CollectMessage) - 1]) ||
1701  (strlen (attr) > GNUNET_ABD_MAX_LENGTH))
1702  {
1703  GNUNET_break (0);
1704  return GNUNET_SYSERR;
1705  }
1706  return GNUNET_OK;
1707 }
1708 
1709 
1710 static void
1712  struct GNUNET_SERVICE_Client *client,
1713  void *app_ctx)
1714 {
1715  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1716 }
1717 
1718 
1719 static void *
1721  struct GNUNET_SERVICE_Client *client,
1722  struct GNUNET_MQ_Handle *mq)
1723 {
1724  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1725  return client;
1726 }
1727 
1728 
1736 static void
1737 run (void *cls,
1738  const struct GNUNET_CONFIGURATION_Handle *c,
1739  struct GNUNET_SERVICE_Handle *handle)
1740 {
1741 
1742  gns = GNUNET_GNS_connect (c);
1743  if (NULL == gns)
1744  {
1745  fprintf (stderr, _ ("Failed to connect to GNS\n"));
1746  }
1748  if (NULL == namestore)
1749  {
1750  fprintf (stderr, _ ("Failed to connect to namestore\n"));
1751  }
1752 
1753  statistics = GNUNET_STATISTICS_create ("abd", c);
1755 }
1756 
1757 
1762  "abd",
1764  &run,
1767  NULL,
1770  struct VerifyMessage,
1771  NULL),
1774  struct CollectMessage,
1775  NULL),
1777 
1778 /* end of gnunet-service-abd.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
IPC messages between ABD API and ABD service.
int GNUNET_ABD_delegates_deserialize(size_t len, const char *src, unsigned int c_count, struct GNUNET_ABD_Delegate *cd)
Deserialize the given destination.
struct GNUNET_ABD_Delegate * GNUNET_ABD_delegate_deserialize(const char *data, size_t data_size)
int GNUNET_ABD_delegation_set_deserialize(size_t len, const char *src, unsigned int d_count, struct GNUNET_ABD_DelegationSet *dsr)
Deserialize the given destination.
ssize_t GNUNET_ABD_delegation_chain_serialize(unsigned int d_count, const struct GNUNET_ABD_Delegation *dd, unsigned int c_count, const struct GNUNET_ABD_Delegate *cd, size_t dest_size, char *dest)
Serizalize the given delegation chain entries and abd.
size_t GNUNET_ABD_delegation_chain_get_size(unsigned int d_count, const struct GNUNET_ABD_Delegation *dd, unsigned int c_count, const struct GNUNET_ABD_Delegate *cd)
Calculate how many bytes we will need to serialize the given delegation chain and abd.
API to serialize and deserialize delegation chains and abds.
#define GNUNET_GNSRECORD_TYPE_ATTRIBUTE
For ABD reverse lookups.
#define GNUNET_GNSRECORD_TYPE_DELEGATE
For ABD policies.
static int collect
Collect mode.
Definition: gnunet-abd.c:132
static int verify
Verify mode.
Definition: gnunet-abd.c:127
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
uint32_t data
The data value.
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static int del
Desired action is to remove a record.
static void handle_collect(void *cls, const struct CollectMessage *c_msg)
GNUNET_SERVICE_MAIN("abd", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(verify, GNUNET_MESSAGE_TYPE_ABD_VERIFY, struct VerifyMessage, NULL), GNUNET_MQ_hd_var_size(collect, GNUNET_MESSAGE_TYPE_ABD_COLLECT, struct CollectMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static struct GNUNET_GNS_Handle * gns
Handle to GNS service.
static struct VerifyRequestHandle * vrh_tail
Tail of the DLL.
static void forward_resolution(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
static int delegation_chain_bw_resolution_start(void *cls)
Result from GNS lookup.
static void handle_delegate_collection_cb(void *cls, const struct GNUNET_IDENTITY_PrivateKey *key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
static void cleanup_handle(struct VerifyRequestHandle *vrh)
static int check_verify(void *cls, const struct VerifyMessage *v_msg)
static struct VerifyRequestHandle * vrh_head
Head of the DLL.
static void handle_delegate_collection_error_cb(void *cls)
static void shutdown_task(void *cls)
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
static int handle_bidirectional_match(struct DelegationSetQueueEntry *actual_entry, struct DelegationSetQueueEntry *match_entry, struct VerifyRequestHandle *vrh)
static int delegation_chain_fw_resolution_start(void *cls)
static void cleanup_dsq_entry(struct DelegationSetQueueEntry *ds_entry)
static void print_deleset(struct DelegationSetQueueEntry *dsentry, char *text)
static struct GNUNET_NAMESTORE_Handle * namestore
Handle to namestore service.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *handle)
Process Credential requests.
static void delegate_collection_finished(void *cls)
static void send_intermediate_response(struct VerifyRequestHandle *vrh, struct DelegationChainEntry *ch_entry, bool is_bw)
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
static char * partial_match(char *tmp_trail, char *tmp_subattr, char *parent_trail, char *issuer_attribute)
static void backward_resolution(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
static void handle_verify(void *cls, const struct VerifyMessage *v_msg)
static int check_collect(void *cls, const struct CollectMessage *c_msg)
static void send_lookup_response(struct VerifyRequestHandle *vrh)
#define GNUNET_ABD_MAX_LENGTH
API to the Credential service.
API to the GNS service.
API that can be used to manipulate GNS record data.
Identity service; implements identity management for GNUnet.
API that can be used to store naming information on a GNUnet node;.
Constants for network protocols.
API to create, modify and access statistics.
GNUNET_ABD_AlgoDirectionFlags
@ GNUNET_ABD_FLAG_BACKWARD
@ GNUNET_ABD_FLAG_FORWARD
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup(struct GNUNET_GNS_Handle *handle, const char *name, const struct GNUNET_IDENTITY_PublicKey *zone, uint32_t type, enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor proc, void *proc_cls)
Perform an asynchronous lookup operation on the GNS.
Definition: gns_api.c:422
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:290
void * GNUNET_GNS_lookup_cancel(struct GNUNET_GNS_LookupRequest *lr)
Cancel pending lookup request.
Definition: gns_api.c:314
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:268
@ GNUNET_GNS_LO_DEFAULT
Defaults, look in cache, then in DHT.
@ GNUNET_GNSRECORD_RF_PRIVATE
This is a private record of this peer and it should thus not be published.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_key_get_public(const struct GNUNET_IDENTITY_PrivateKey *privkey, struct GNUNET_IDENTITY_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: identity_api.c:179
char * GNUNET_IDENTITY_public_key_to_string(const struct GNUNET_IDENTITY_PublicKey *key)
Creates a (Base32) string representation of the public key.
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
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:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#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:62
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_lookup(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor rm, void *rm_cls)
Lookup an item in the namestore.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
#define GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT
#define GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT
#define GNUNET_MESSAGE_TYPE_ABD_COLLECT
#define GNUNET_MESSAGE_TYPE_ABD_VERIFY
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,...
Definition: scheduler.c:1303
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2443
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2249
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
enum GNUNET_GenericReturnValue GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
Convert the utf-8 input string to lower case.
Definition: strings.c:449
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Message from client to Credential service to collect credentials.
Definition: abd.h:36
struct GNUNET_IDENTITY_PublicKey issuer_key
Trust anchor.
Definition: abd.h:50
uint16_t resolution_algo
Direction of the resolution algo.
Definition: abd.h:60
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: abd.h:55
struct GNUNET_IDENTITY_PrivateKey subject_key
Subject public key.
Definition: abd.h:45
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_ABD_VERIFY.
Definition: abd.h:40
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:65
uint32_t refcount
Number of references in delegation chains.
struct DelegateRecordEntry * prev
DLL.
struct GNUNET_ABD_Delegate * delegate
Payload.
struct DelegateRecordEntry * next
DLL.
struct GNUNET_IDENTITY_PublicKey subject_key
The subject.
struct DelegationChainEntry * prev
DLL.
char * subject_attribute
The delegated attribute.
struct DelegationChainEntry * next
DLL.
char * issuer_attribute
The issued attribute.
struct GNUNET_IDENTITY_PublicKey issuer_key
The issuer.
Message from ABD service to client: new results.
Definition: abd.h:152
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:161
Message from ABD service to client: new results.
Definition: abd.h:119
uint32_t del_found
Indicates if credential has been found at all.
Definition: abd.h:133
uint32_t d_count
The number of delegations in the response.
Definition: abd.h:138
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:128
uint32_t c_count
The number of credentials in the response.
Definition: abd.h:143
DLL used for delegations Used for OR delegations.
struct DelegationQueueEntry * next
DLL.
struct DelegationQueueEntry * prev
DLL.
uint32_t required_solutions
Required solutions.
struct DelegationSetQueueEntry * parent_set
Parent set.
DLL for delegation sets Used for AND delegation set.
char * lookup_attribute
The current attribute to look up.
struct DelegationQueueEntry * parent_queue_entry
Parent QueueEntry.
char * attr_trailer
Trailing attribute context.
struct GNUNET_IDENTITY_PublicKey * issuer_key
Issuer key.
struct DelegationSetQueueEntry * prev
DLL.
char * issuer_attribute
Issuer attribute delegated to.
struct DelegationChainEntry * delegation_chain_entry
The delegation chain entry.
struct VerifyRequestHandle * handle
Verify handle.
struct DelegationQueueEntry * parent
Parent attribute delegation.
char * unresolved_attribute_delegation
Still to resolve delegation as string.
struct DelegationQueueEntry * queue_entries_head
Queue entries of this set.
struct DelegationSetQueueEntry * next
DLL.
struct DelegationQueueEntry * queue_entries_tail
Queue entries of this set.
bool from_bw
True if added by backward resolution.
struct GNUNET_GNS_LookupRequest * lookup_request
GNS handle.
const char * subject_attribute
The subject attribute.
const char * issuer_attribute
The issuer attribute.
struct GNUNET_IDENTITY_Signature signature
Signature of this credential.
uint32_t issuer_attribute_len
Length of the issuer attribute.
uint32_t subject_attribute_len
Length of the subject attribute.
struct GNUNET_IDENTITY_PublicKey subject_key
Public key of the subject this credential was issued to.
struct GNUNET_TIME_Absolute expiration
Expiration of this credential.
struct GNUNET_IDENTITY_PublicKey issuer_key
The issuer of the credential.
The attribute delegation record.
The attribute delegation record.
const char * subject_attribute
The subject attribute.
struct GNUNET_IDENTITY_PublicKey subject_key
Public key of the subject this attribute was delegated to.
uint32_t issuer_attribute_len
Length of the attribute.
struct GNUNET_IDENTITY_PublicKey issuer_key
The issuer of the delegation.
uint32_t subject_attribute_len
Length of the attribute.
const char * issuer_attribute
The attribute.
const char * subject_attribute
The attribute.
struct GNUNET_IDENTITY_PublicKey subject_key
Public key of the subject this attribute was delegated to.
const void * data
Binary value stored in the DNS record.
Connection to the GNS service.
Definition: gns_api.h:36
Handle to a lookup request.
Definition: gns_api.c:49
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Handle to a message queue.
Definition: mq.c:87
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Connection to the NAMESTORE service.
An QueueEntry used to store information for a pending NAMESTORE record operation.
Definition: namestore_api.c:53
Handle to a client that is connected to a service.
Definition: service.c:252
Handle to a service.
Definition: service.c:118
Handle for the service.
Message from client to Credential service to verify attributes.
Definition: abd.h:75
struct GNUNET_IDENTITY_PublicKey issuer_key
Trust anchor.
Definition: abd.h:89
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_ABD_VERIFY.
Definition: abd.h:79
uint16_t resolution_algo
Direction of the resolution algo.
Definition: abd.h:104
struct GNUNET_IDENTITY_PublicKey subject_key
Subject public key.
Definition: abd.h:84
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:109
uint32_t d_count
Number of delegates.
Definition: abd.h:94
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: abd.h:99
Handle to a lookup operation from api.
struct GNUNET_IDENTITY_PublicKey issuer_key
Issuer public key.
struct VerifyRequestHandle * prev
We keep these in a DLL.
struct GNUNET_NAMESTORE_QueueEntry * dele_qe
Delegate iterator for lookup.
struct GNUNET_SERVICE_Client * client
Handle to the requesting client.
uint32_t request_id
request id
struct DelegationQueueEntry * current_delegation
Current Delegation Pointer.
struct VerifyRequestHandle * next
We keep these in a DLL.
enum GNUNET_ABD_AlgoDirectionFlags resolution_algo
Direction of the resolution algo.
uint32_t del_chain_size
Delegate DLL size.
uint64_t pending_lookups
Pending lookups.
struct DelegationSetQueueEntry * dsq_head
List for bidirectional matching.
uint32_t delegation_chain_size
Size of delegation tree.
struct DelegationSetQueueEntry * dsq_tail
List for bidirectional matching.
struct GNUNET_IDENTITY_PublicKey subject_key
Subject public key.
struct DelegationChainEntry * delegation_chain_tail
Children of this attribute.
struct DelegateRecordEntry * del_chain_head
Delegate DLL.
bool is_collect
True if created by a collect request.
struct DelegateRecordEntry * del_chain_tail
Delegate DLL.
char * issuer_attribute
Issuer attribute.
struct DelegationChainEntry * delegation_chain_head
Children of this attribute.