GNUnet  0.11.x
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_dnsparser_lib.h>
36 #include <gnunet_gns_service.h>
37 #include <gnunet_gnsrecord_lib.h>
40 
41 
42 #define GNUNET_ABD_MAX_LENGTH 255
43 
44 struct VerifyRequestHandle;
45 
47 
48 
50 {
55 
60 
65 
70 
75 
80 };
81 
86 {
91 
96 
100  uint32_t refcount;
101 
106 };
107 
113 {
118 
123 
128 
133 };
134 
140 {
145 
150 
155 
160 
165 
170 
175 
180 
185 
190 
195 
200 
205 
210 
214  bool from_bw;
215 };
216 
217 
222 {
231 
236 
241 
246 
251 
256 
261 
266 
271 
276 
281 
286 
291 
295  uint32_t del_chain_size;
296 
301 
305  uint32_t request_id;
306 
310  uint64_t pending_lookups;
311 
316 
321 };
322 
323 
327 static struct VerifyRequestHandle *vrh_head = NULL;
328 
332 static struct VerifyRequestHandle *vrh_tail = NULL;
333 
338 
342 static struct GNUNET_GNS_Handle *gns;
343 
348 
349 static void
350 print_deleset (struct DelegationSetQueueEntry *dsentry, char *text)
351 {
353  "%s %s.%s <- %s.%s\n",
354  text,
361 }
362 
363 
364 static void
366 {
367  GNUNET_free (ds_entry->issuer_key);
368  GNUNET_free (ds_entry->issuer_attribute);
369  GNUNET_free (ds_entry->attr_trailer);
370  // those fields are only set/used in bw search
371  if (ds_entry->from_bw)
372  {
373  GNUNET_free (ds_entry->lookup_attribute);
375  }
376  if (NULL != ds_entry->lookup_request)
377  {
379  ds_entry->lookup_request = NULL;
380  }
381  if (NULL != ds_entry->delegation_chain_entry)
382  {
383  GNUNET_free (
387  }
388  // Free DQ entries
389  for (struct DelegationQueueEntry *dq_entry = ds_entry->queue_entries_head;
390  NULL != ds_entry->queue_entries_head;
391  dq_entry = ds_entry->queue_entries_head)
392  {
394  ds_entry->queue_entries_tail,
395  dq_entry);
396  GNUNET_free (dq_entry);
397  }
398  GNUNET_free (ds_entry);
399 }
400 
401 
402 static void
404 {
405  struct DelegateRecordEntry *del_entry;
406  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up...\n");
407 
408  if (NULL != vrh->dsq_head)
409  {
410  for (struct DelegationSetQueueEntry *ds_entry = vrh->dsq_head; NULL !=
411  vrh->dsq_head;
412  ds_entry = vrh->dsq_head)
413  {
414  GNUNET_CONTAINER_DLL_remove (vrh->dsq_head, vrh->dsq_tail, ds_entry);
415  cleanup_dsq_entry (ds_entry);
416  }
417  }
418  if (NULL != vrh->del_chain_head)
419  {
420  for (del_entry = vrh->del_chain_head; NULL != vrh->del_chain_head;
421  del_entry = vrh->del_chain_head)
422  {
424  vrh->del_chain_tail,
425  del_entry);
426  GNUNET_free (del_entry->delegate);
427  GNUNET_free (del_entry);
428  }
429  }
431  GNUNET_free (vrh);
432 }
433 
434 
435 static void
436 shutdown_task (void *cls)
437 {
438  struct VerifyRequestHandle *vrh;
439 
440  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down!\n");
441 
442  while (NULL != (vrh = vrh_head))
443  {
444  // ABD_resolver_lookup_cancel (clh->lookup);
446  cleanup_handle (vrh);
447  }
448 
449  if (NULL != gns)
450  {
452  gns = NULL;
453  }
454  if (NULL != namestore)
455  {
457  namestore = NULL;
458  }
459  if (NULL != statistics)
460  {
462  statistics = NULL;
463  }
464 }
465 
466 
467 static void
469  DelegationChainEntry *ch_entry, bool is_bw)
470 {
472  struct GNUNET_MQ_Envelope *env;
473  struct GNUNET_ABD_Delegation *dd;
474  size_t size;
475 
476  // Don't report immediate results during collect
477  if (vrh->is_collect)
478  return;
479 
480  dd = GNUNET_new (struct GNUNET_ABD_Delegation);
481  dd->issuer_key = ch_entry->issuer_key;
482  dd->subject_key = ch_entry->subject_key;
483  dd->issuer_attribute = ch_entry->issuer_attribute;
484  dd->issuer_attribute_len = strlen (ch_entry->issuer_attribute) + 1;
485  dd->subject_attribute_len = 0;
486  dd->subject_attribute = NULL;
487  if (NULL != ch_entry->subject_attribute)
488  {
489  dd->subject_attribute = ch_entry->subject_attribute;
490  dd->subject_attribute_len = strlen (ch_entry->subject_attribute) + 1;
491  }
492 
493 
495  dd,
496  0,
497  NULL);
498 
499  env = GNUNET_MQ_msg_extra (rmsg,
500  size,
502  // Assign id so that client can find associated request
503  rmsg->id = vrh->request_id;
504  rmsg->is_bw = htons (is_bw);
505  rmsg->size = htonl (size);
506 
507  GNUNET_assert (
509  dd,
510  0,
511  NULL,
512  size,
513  (char *) &rmsg[1]));
515 
516  GNUNET_free (dd);
517 }
518 
519 
520 static void
522 {
523  struct GNUNET_MQ_Envelope *env;
524  struct DelegationChainResultMessage *rmsg;
525  struct DelegationChainEntry *dce;
526  struct GNUNET_ABD_Delegation dd[vrh->delegation_chain_size];
527  struct GNUNET_ABD_Delegate dele[vrh->del_chain_size];
528  struct DelegateRecordEntry *del;
529  struct DelegateRecordEntry *tmp;
530  size_t size;
531 
532  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n");
533  dce = vrh->delegation_chain_head;
534  for (uint32_t i = 0; i < vrh->delegation_chain_size; i++)
535  {
536  dd[i].issuer_key = dce->issuer_key;
537  dd[i].subject_key = dce->subject_key;
538  dd[i].issuer_attribute = dce->issuer_attribute;
539  dd[i].issuer_attribute_len = strlen (dce->issuer_attribute) + 1;
540  dd[i].subject_attribute_len = 0;
541  dd[i].subject_attribute = NULL;
542  if (NULL != dce->subject_attribute)
543  {
545  dd[i].subject_attribute_len = strlen (dce->subject_attribute) + 1;
546  }
547  dce = dce->next;
548  }
549 
550  // Remove all not needed credentials
551  for (del = vrh->del_chain_head; NULL != del;)
552  {
553  if (del->refcount > 0)
554  {
555  del = del->next;
556  continue;
557  }
558  tmp = del;
559  del = del->next;
561  GNUNET_free (tmp->delegate);
562  GNUNET_free (tmp);
563  vrh->del_chain_size--;
564  }
565 
566  // Get serialized record data
567  // Append at the end of rmsg
568  del = vrh->del_chain_head;
569  for (uint32_t i = 0; i < vrh->del_chain_size; i++)
570  {
571  dele[i].issuer_key = del->delegate->issuer_key;
572  dele[i].subject_key = del->delegate->subject_key;
573  dele[i].issuer_attribute_len = strlen (del->delegate->issuer_attribute) + 1;
574  dele[i].issuer_attribute = del->delegate->issuer_attribute;
575  dele[i].subject_attribute_len = del->delegate->subject_attribute_len;
576  dele[i].subject_attribute = del->delegate->subject_attribute;
577  dele[i].expiration = del->delegate->expiration;
578  dele[i].signature = del->delegate->signature;
579  del = del->next;
580  }
581  size =
583  dd,
584  vrh->del_chain_size,
585  dele);
586  env = GNUNET_MQ_msg_extra (rmsg,
587  size,
589  // Assign id so that client can find associated request
590  rmsg->id = vrh->request_id;
591  rmsg->d_count = htonl (vrh->delegation_chain_size);
592  rmsg->c_count = htonl (vrh->del_chain_size);
593 
594  if (0 < vrh->del_chain_size)
595  rmsg->del_found = htonl (GNUNET_YES);
596  else
597  rmsg->del_found = htonl (GNUNET_NO);
598 
599  GNUNET_assert (
600  -1 !=
602  dd,
603  vrh->del_chain_size,
604  dele,
605  size,
606  (char *) &rmsg[1]));
607 
610  cleanup_handle (vrh);
612  "Completed verifications",
613  1,
614  GNUNET_NO);
615 }
616 
617 
618 static char *
619 partial_match (char *tmp_trail,
620  char *tmp_subattr,
621  char *parent_trail,
622  char *issuer_attribute)
623 {
624  char *saveptr1, *saveptr2;
625  char *trail_token;
626  char *sub_token;
627  char *attr_trailer;
628 
629  // tok both, parent->attr_trailer and del->sub_attr to see how far they match,
630  // take rest of parent trailer (only when del->sub_attr token is null), and
631  // create new/actual trailer with del->iss_attr
632  trail_token = strtok_r (tmp_trail, ".", &saveptr1);
633  sub_token = strtok_r (tmp_subattr, ".", &saveptr2);
634  while (NULL != trail_token && NULL != sub_token)
635  {
636  if (0 == strcmp (trail_token, sub_token))
637  {
638  // good, matches, remove
639  }
640  else
641  {
642  // not relevant for solving the chain, end for iteration here
643  return NULL;
644  }
645 
646  trail_token = strtok_r (NULL, ".", &saveptr1);
647  sub_token = strtok_r (NULL, ".", &saveptr2);
648  }
649  // skip this entry and go to next for if:
650  // 1. at some point the attr of the trailer and the subject dont match
651  // 2. the trailer is NULL, but the subject has more attributes
652  // Reason: This will lead to "startzone.attribute" but we're looking for a solution
653  // for "<- startzone"
654  if (NULL == trail_token)
655  {
656  return NULL;
657  }
658 
659  // do not have to check sub_token == NULL, if both would be NULL
660  // at the same time, the complete match part above should have triggered already
661 
662  // otherwise, above while only ends when sub_token == NULL
663  GNUNET_asprintf (&attr_trailer, "%s", trail_token);
664  trail_token = strtok_r (NULL, ".", &saveptr1);
665  while (NULL != trail_token)
666  {
667  GNUNET_asprintf (&attr_trailer, "%s.%s", parent_trail, trail_token);
668  trail_token = strtok_r (NULL, ".", &saveptr1);
669  }
670  GNUNET_asprintf (&attr_trailer, "%s.%s", issuer_attribute, attr_trailer);
671  return attr_trailer;
672 }
673 
674 
675 static int
677  struct DelegationSetQueueEntry *match_entry,
678  struct VerifyRequestHandle *vrh)
679 {
680  struct DelegationSetQueueEntry *old_fw_parent;
681  struct DelegationSetQueueEntry *fw_entry = actual_entry;
682  struct DelegationSetQueueEntry *last_entry = match_entry;
683  // parent fixing, combine backward and forward chain parts
684  while (NULL != fw_entry->parent_queue_entry)
685  {
686  old_fw_parent = fw_entry->parent_queue_entry->parent_set;
687  // set parent
688  fw_entry->parent_queue_entry->parent_set = last_entry;
689 
690  last_entry = fw_entry;
691  fw_entry = old_fw_parent;
692  }
693  // set last entry of chain as actual_entry
694  // actual_entry = last_entry;
695  // set refcount, loop all delegations
696  for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head;
697  del_entry != NULL;
698  del_entry = del_entry->next)
699  {
700  if (0 != memcmp (&last_entry->delegation_chain_entry->subject_key,
701  &del_entry->delegate->issuer_key,
702  sizeof (struct GNUNET_IDENTITY_PublicKey)))
703  continue;
704  if (0 != strcmp (last_entry->delegation_chain_entry->subject_attribute,
705  del_entry->delegate->issuer_attribute))
706  continue;
707 
708  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found delegate.\n");
709  // increase refcount of the start delegation
710  del_entry->refcount++;
711  }
712  // backtrack
713  for (struct DelegationSetQueueEntry *tmp_set = last_entry;
714  NULL != tmp_set->parent_queue_entry;
715  tmp_set = tmp_set->parent_queue_entry->parent_set)
716  {
717  tmp_set->parent_queue_entry->required_solutions--;
718 
719  // add new found entry to vrh
720  vrh->delegation_chain_size++;
723  tmp_set->delegation_chain_entry);
724 
725  // if one node on the path still needs solutions, this current
726  // patch cannot fulfill the conditions and therefore stops here
727  // however, it is in the vrh and can be used by the other paths
728  // related to this path/collection/verification
729  if (0 < tmp_set->parent_queue_entry->required_solutions)
730  {
732  "Chain requires more solutions, waiting...\n");
733  return GNUNET_NO;
734  }
735  }
736  return GNUNET_YES;
737 }
738 
739 
740 static void
742  uint32_t rd_count,
743  const struct GNUNET_GNSRECORD_Data *rd)
744 {
745  struct VerifyRequestHandle *vrh;
746  struct DelegationSetQueueEntry *current_set;
747  struct DelegationSetQueueEntry *ds_entry;
748  struct DelegationQueueEntry *dq_entry;
749  struct GNUNET_ABD_Delegate *del;
750 
751  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d entries.\n", rd_count);
752 
753  current_set = cls;
754  // set handle to NULL (as el = NULL)
755  current_set->lookup_request = NULL;
756  vrh = current_set->handle;
757  vrh->pending_lookups--;
758 
759  // Loop record entries
760  for (uint32_t i = 0; i < rd_count; i++)
761  {
762  if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type)
763  continue;
764 
765  // Start deserialize into Delegate
767 
768  if (NULL == del)
769  continue;
770 
771  // Start: Create DQ Entry
772  dq_entry = GNUNET_new (struct DelegationQueueEntry);
773  // AND delegations are not possible, only 1 solution
774  dq_entry->required_solutions = 1;
775  dq_entry->parent_set = current_set;
776 
777  // Insert it into the current set
779  current_set->queue_entries_tail,
780  dq_entry);
781 
782  // Start: Create DS Entry
783  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
784  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
785  ds_entry->from_bw = false;
786 
787  // (1) A.a <- A.b.c
788  // (2) A.b <- D.d
789  // (3) D.d <- E
790  // (4) E.c <- F.c
791  // (5) F.c <- G
792  // Possibilities:
793  // 1. complete match: trailer = 0, validate
794  // 2. partial match: replace
795  // 3. new solution: replace, add trailer
796 
797  // At resolution chain start trailer of parent is NULL
798  if (NULL == current_set->attr_trailer)
799  {
800  // for (5) F.c <- G, remember .c when going upwards
801  ds_entry->attr_trailer = GNUNET_strdup (del->issuer_attribute);
802  }
803  else
804  {
805  if (0 == del->subject_attribute_len)
806  {
807  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: New solution\n");
808  // new solution
809  // create new trailer del->issuer_attribute, ds_entry->attr_trailer
810  GNUNET_asprintf (&ds_entry->attr_trailer,
811  "%s.%s",
812  del->issuer_attribute,
813  current_set->attr_trailer);
814  }
815  else if (0 == strcmp (del->subject_attribute, current_set->attr_trailer))
816  {
817  // complete match
818  // new trailer == issuer attribute (e.g. (5) to (4))
819  ds_entry->attr_trailer = GNUNET_strdup (del->issuer_attribute);
820  }
821  else
822  {
823  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Partial match\n");
824  // partial match
825 
826  char *trail = partial_match (GNUNET_strdup (current_set->attr_trailer),
827  GNUNET_strdup (del->subject_attribute),
828  current_set->attr_trailer,
829  GNUNET_strdup (del->issuer_attribute));
830 
831  // if null: skip this record entry (reasons: mismatch or overmatch, both not relevant)
832  if (NULL == trail)
833  {
835  "Entry not relevant, discarding: %s.%s <- %s.%s\n",
837  &del->issuer_key),
838  del->issuer_attribute,
840  &del->subject_key),
841  del->subject_attribute);
842  GNUNET_free (del);
843  continue;
844  }
845  else
846  ds_entry->attr_trailer = trail;
847  }
848  }
849 
850 
851  // Start: Credential Chain Entry
852  // issuer key is subject key, who needs to be contacted to resolve this (forward, therefore subject)
853  ds_entry->issuer_key = GNUNET_new (struct GNUNET_IDENTITY_PublicKey);
854  GNUNET_memcpy (ds_entry->issuer_key,
855  &del->subject_key,
856  sizeof (struct GNUNET_IDENTITY_PublicKey));
857 
859  ds_entry->delegation_chain_entry->subject_key = del->subject_key;
860  if (0 < del->subject_attribute_len)
862  GNUNET_strdup (del->subject_attribute);
863  ds_entry->delegation_chain_entry->issuer_key = del->issuer_key;
865  GNUNET_strdup (del->issuer_attribute);
866 
867  // Found new entry, repoting intermediate result
868  send_intermediate_response (vrh, ds_entry->delegation_chain_entry, false);
869 
870  // current delegation as parent
871  ds_entry->parent_queue_entry = dq_entry;
872 
873  // Check for solution
874  // if: issuer key we looking for
875  if (0 == memcmp (&del->issuer_key,
876  &vrh->issuer_key,
877  sizeof (struct GNUNET_IDENTITY_PublicKey)))
878  {
879  // if: issuer attr we looking for
880  if (0 == strcmp (del->issuer_attribute, vrh->issuer_attribute))
881  {
882  // if: complete match, meaning new trailer == issuer attr
883  if (0 == strcmp (vrh->issuer_attribute, ds_entry->attr_trailer))
884  {
885  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Solution\n");
886 
887  // Add found solution into delegation_chain
888  struct DelegationSetQueueEntry *tmp_set;
889  for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
890  tmp_set = tmp_set->parent_queue_entry->parent_set)
891  {
892  if (NULL != tmp_set->delegation_chain_entry)
893  {
894  vrh->delegation_chain_size++;
897  tmp_set->delegation_chain_entry);
898  }
899  }
900 
901  // Increase refcount for this delegate
902  for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head;
903  del_entry != NULL;
904  del_entry = del_entry->next)
905  {
906  if (0 == memcmp (&del_entry->delegate->issuer_key,
908  sizeof (struct GNUNET_IDENTITY_PublicKey)))
909  {
910  if (0 == strcmp (del_entry->delegate->issuer_attribute,
912  {
913  del_entry->refcount++;
914  }
915  }
916  }
917 
918  send_lookup_response (vrh);
919  GNUNET_free (del);
920  return;
921  }
922  }
923  }
924 
925  // Check for bidirectional crossmatch
926  for (struct DelegationSetQueueEntry *del_entry = vrh->dsq_head;
927  del_entry != NULL;
928  del_entry = del_entry->next)
929  {
930  // only check entries not by backward algorithm
931  if (del_entry->from_bw)
932  {
933  // key of list entry matches actual key
934  if (0 == memcmp (&del_entry->delegation_chain_entry->subject_key,
936  sizeof (struct GNUNET_IDENTITY_PublicKey)))
937  {
938  // compare entry subject attributes to this trailer (iss attr + old trailer)
939  if (0 == strcmp (del_entry->unresolved_attribute_delegation,
940  ds_entry->attr_trailer))
941  {
942  print_deleset (del_entry, "Forward:");
944  "Forward: Found match with above!\n");
945 
946  GNUNET_free (del);
947  // one node on the path still needs solutions: return
948  if (GNUNET_NO ==
949  handle_bidirectional_match (ds_entry, del_entry, vrh))
950  return;
951 
952  send_lookup_response (vrh);
953  return;
954  }
955  }
956  }
957  }
958 
959  // Starting a new GNS lookup
960  vrh->pending_lookups++;
961  ds_entry->handle = vrh;
962 
964  "Starting to look up trailer %s in zone %s\n",
965  ds_entry->attr_trailer,
967 
968  ds_entry->lookup_request =
971  &del->issuer_key,
975  ds_entry);
976  GNUNET_free (del);
977  }
978 
979  if (0 == vrh->pending_lookups)
980  {
981  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
982  send_lookup_response (vrh);
983  return;
984  }
985 }
986 
987 
988 static void
990  uint32_t rd_count,
991  const struct GNUNET_GNSRECORD_Data *rd)
992 {
993  struct VerifyRequestHandle *vrh;
994  const struct GNUNET_ABD_DelegationRecord *sets;
995  struct DelegateRecordEntry *del_pointer;
996  struct DelegationSetQueueEntry *current_set;
997  struct DelegationSetQueueEntry *ds_entry;
998  struct DelegationSetQueueEntry *tmp_set;
999  struct DelegationQueueEntry *dq_entry;
1000  char *expanded_attr;
1001  char *lookup_attribute;
1002 
1003  current_set = cls;
1004  current_set->lookup_request = NULL;
1005  vrh = current_set->handle;
1006  vrh->pending_lookups--;
1007 
1008  // Each OR
1009  for (uint32_t i = 0; i < rd_count; i++)
1010  {
1011  if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
1012  continue;
1013 
1014  sets = rd[i].data;
1015  struct GNUNET_ABD_DelegationSet set[ntohl (sets->set_count)];
1017  "Found new attribute delegation with %d sets. Creating new Job...\n",
1018  ntohl (sets->set_count));
1019 
1020  if (GNUNET_OK !=
1022  sets->data_size),
1023  (const char *) &sets[1],
1024  ntohl (sets->set_count),
1025  set))
1026  {
1027  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n");
1028  continue;
1029  }
1030  dq_entry = GNUNET_new (struct DelegationQueueEntry);
1031  dq_entry->required_solutions = ntohl (sets->set_count);
1032  dq_entry->parent_set = current_set;
1033 
1035  current_set->queue_entries_tail,
1036  dq_entry);
1037  // Each AND
1038  for (uint32_t j = 0; j < ntohl (sets->set_count); j++)
1039  {
1040  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1041  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1042  ds_entry->from_bw = true;
1043 
1044  if (NULL != current_set->attr_trailer)
1045  {
1046  if (0 == set[j].subject_attribute_len)
1047  {
1048  GNUNET_asprintf (&expanded_attr, "%s", current_set->attr_trailer);
1049  }
1050  else
1051  {
1052  GNUNET_asprintf (&expanded_attr,
1053  "%s.%s",
1054  set[j].subject_attribute,
1055  current_set->attr_trailer);
1056  }
1057  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expanded to %s\n", expanded_attr);
1058  ds_entry->unresolved_attribute_delegation = expanded_attr;
1059  }
1060  else
1061  {
1062  if (0 != set[j].subject_attribute_len)
1063  {
1065  "Not Expanding %s\n",
1066  set[j].subject_attribute);
1069  }
1070  }
1071 
1072  // Add a credential chain entry
1073  ds_entry->delegation_chain_entry =
1075  ds_entry->delegation_chain_entry->subject_key = set[j].subject_key;
1076  ds_entry->issuer_key = GNUNET_new (struct GNUNET_IDENTITY_PublicKey);
1077  GNUNET_memcpy (ds_entry->issuer_key,
1078  &set[j].subject_key,
1079  sizeof (struct GNUNET_IDENTITY_PublicKey));
1080  if (0 < set[j].subject_attribute_len)
1083  ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key;
1085  GNUNET_strdup (current_set->lookup_attribute);
1086 
1087  // Found new entry, repoting intermediate result
1088  send_intermediate_response (vrh, ds_entry->delegation_chain_entry, true);
1089 
1090  ds_entry->parent_queue_entry = dq_entry; // current_delegation;
1091 
1095  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking for cred match\n");
1096 
1097  for (del_pointer = vrh->del_chain_head; del_pointer != NULL;
1098  del_pointer = del_pointer->next)
1099  {
1100  // If key and attribute match credential: continue and backtrack
1101  if (0 != memcmp (&set[j].subject_key,
1102  &del_pointer->delegate->issuer_key,
1103  sizeof (struct GNUNET_IDENTITY_PublicKey)))
1104  continue;
1106  "Checking if %s matches %s\n",
1108  del_pointer->delegate->issuer_attribute);
1109 
1110  if (0 != strcmp (ds_entry->unresolved_attribute_delegation,
1111  del_pointer->delegate->issuer_attribute))
1112  continue;
1113 
1114  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n");
1115  // increase refcount of the start delegation
1116  del_pointer->refcount++;
1117 
1118  // Backtrack
1119  for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
1120  tmp_set = tmp_set->parent_queue_entry->parent_set)
1121  {
1123  if (NULL != tmp_set->delegation_chain_entry)
1124  {
1125  vrh->delegation_chain_size++;
1127  vrh->delegation_chain_tail,
1128  tmp_set->delegation_chain_entry);
1129  }
1130  if (0 < tmp_set->parent_queue_entry->required_solutions)
1131  break;
1132  }
1133 
1134  // if the break above is not called the condition of the for is met
1135  if (NULL == tmp_set->parent_queue_entry)
1136  {
1137  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All solutions found\n");
1138  // Found match
1139  send_lookup_response (vrh);
1140  return;
1141  }
1142  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not all solutions found yet.\n");
1143  continue;
1144  }
1145 
1147  "Building new lookup request from %s\n",
1149  // Continue with next/new backward resolution
1150  char issuer_attribute_name[strlen (
1152  + 1];
1153  strcpy (issuer_attribute_name, ds_entry->unresolved_attribute_delegation);
1154  char *next_attr = strtok (issuer_attribute_name, ".");
1155  if (NULL == next_attr)
1156  {
1158  "Failed to parse next attribute\n");
1159  continue;
1160  }
1161  GNUNET_asprintf (&lookup_attribute, "%s", next_attr);
1162  GNUNET_asprintf (&ds_entry->lookup_attribute, "%s", next_attr);
1163  if (strlen (next_attr) ==
1164  strlen (ds_entry->unresolved_attribute_delegation))
1165  {
1166  ds_entry->attr_trailer = NULL;
1167  }
1168  else
1169  {
1170  next_attr += strlen (next_attr) + 1;
1171  ds_entry->attr_trailer = GNUNET_strdup (next_attr);
1172  }
1173 
1174  // Check for bidirectional crossmatch
1175  for (struct DelegationSetQueueEntry *del_entry = vrh->dsq_head;
1176  del_entry != NULL;
1177  del_entry = del_entry->next)
1178  {
1179  // only check entries added by forward algorithm
1180  if (! del_entry->from_bw)
1181  {
1182  // key of list entry matches actual key
1183  if (0 == memcmp (&del_entry->delegation_chain_entry->issuer_key,
1184  &ds_entry->delegation_chain_entry->subject_key,
1185  sizeof (struct GNUNET_IDENTITY_PublicKey)))
1186  {
1187  // compare entry subject attributes to this trailer (iss attr + old trailer)
1188  if (0 == strcmp (del_entry->attr_trailer,
1190  {
1191  print_deleset (del_entry, "Backward:");
1193  "Backward: Found match with above!\n");
1194 
1195  // if one node on the path still needs solutions: return
1196  if (GNUNET_NO ==
1197  handle_bidirectional_match (del_entry, ds_entry, vrh))
1198  break;
1199 
1200  // Send lookup response
1201  send_lookup_response (vrh);
1202  return;
1203  }
1204  }
1205  }
1206  }
1207 
1208  // Starting a new GNS lookup
1210  "Looking up %s\n",
1211  ds_entry->lookup_attribute);
1212  if (NULL != ds_entry->attr_trailer)
1214  "%s still to go...\n",
1215  ds_entry->attr_trailer);
1216 
1217  vrh->pending_lookups++;
1218  ds_entry->handle = vrh;
1219  ds_entry->lookup_request =
1221  lookup_attribute,
1222  ds_entry->issuer_key, // issuer_key,
1226  ds_entry);
1227 
1228  GNUNET_free (lookup_attribute);
1229  }
1230  }
1231 
1232  if (0 == vrh->pending_lookups)
1233  {
1234  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
1235  send_lookup_response (vrh);
1236  return;
1237  }
1238 }
1239 
1240 
1246 static int
1248 {
1249  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Start Backward Resolution...\n");
1250 
1251  struct VerifyRequestHandle *vrh = cls;
1252  struct DelegationSetQueueEntry *ds_entry;
1253  struct DelegateRecordEntry *del_entry;
1254 
1255  if (0 == vrh->del_chain_size)
1256  {
1257  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegates found\n");
1258  send_lookup_response (vrh);
1259  return 1;
1260  }
1261 
1262  // Pre-check with vrh->dele_chain_.. if match issuer_key
1263  // Backward: check every cred entry if match issuer key
1264  // otherwise: start at issuer and go down till match
1265  // A.a <- ...
1266  // X.x <- C
1267  // Y.y <- C
1268  // if not X.x or Y.y == A.a start at A
1269  for (del_entry = vrh->del_chain_head; del_entry != NULL;
1270  del_entry = del_entry->next)
1271  {
1272  if (0 != memcmp (&del_entry->delegate->issuer_key,
1273  &vrh->issuer_key,
1274  sizeof (struct GNUNET_IDENTITY_PublicKey)))
1275  continue;
1276  if (0 !=
1277  strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute))
1278  continue;
1279  del_entry->refcount++;
1280  // Found match prematurely
1281  send_lookup_response (vrh);
1282  return 1;
1283  }
1284 
1285 
1286  // Check for attributes from the issuer and follow the chain
1287  // till you get the required subject's attributes
1288  char issuer_attribute_name[strlen (vrh->issuer_attribute) + 1];
1289  strcpy (issuer_attribute_name, vrh->issuer_attribute);
1291  "Looking up %s\n",
1292  issuer_attribute_name);
1293  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1294  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1295  ds_entry->from_bw = true;
1296  ds_entry->issuer_key = GNUNET_new (struct GNUNET_IDENTITY_PublicKey);
1297  GNUNET_memcpy (ds_entry->issuer_key,
1298  &vrh->issuer_key,
1299  sizeof (struct GNUNET_IDENTITY_PublicKey));
1300  ds_entry->issuer_attribute = GNUNET_strdup (vrh->issuer_attribute);
1301 
1303  ds_entry->delegation_chain_entry->issuer_key = vrh->issuer_key;
1306 
1307  ds_entry->handle = vrh;
1308  ds_entry->lookup_attribute = GNUNET_strdup (vrh->issuer_attribute);
1309  ds_entry->unresolved_attribute_delegation = NULL;
1310  vrh->pending_lookups = 1;
1311 
1312  // Start with backward resolution
1313  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start Backward Resolution\n");
1314 
1315  ds_entry->lookup_request = GNUNET_GNS_lookup (gns,
1316  issuer_attribute_name,
1317  &vrh->issuer_key, // issuer_key,
1321  ds_entry);
1322  return 0;
1323 }
1324 
1325 
1326 static int
1328 {
1329  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Start Forward Resolution...\n");
1330 
1331  struct VerifyRequestHandle *vrh = cls;
1332  struct DelegationSetQueueEntry *ds_entry;
1333  struct DelegateRecordEntry *del_entry;
1334 
1335  // set to 0 and increase on each lookup: for fw multiple lookups (may be) started
1336  vrh->pending_lookups = 0;
1337 
1338  if (0 == vrh->del_chain_size)
1339  {
1340  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegations found\n");
1341  send_lookup_response (vrh);
1342  return 1;
1343  }
1344 
1345  // Pre-check with vrh->dele_chain_.. if match issuer_key
1346  // otherwise FW: start multiple lookups for each vrh->dele_chain
1347  // A.a <- ...
1348  // X.x <- C
1349  // Y.y <- C
1350  // if not X.x or Y.y == A.a start at X and at Y
1351  for (del_entry = vrh->del_chain_head; del_entry != NULL;
1352  del_entry = del_entry->next)
1353  {
1354  if (0 != memcmp (&del_entry->delegate->issuer_key,
1355  &vrh->issuer_key,
1356  sizeof (struct GNUNET_IDENTITY_PublicKey)))
1357  continue;
1358  if (0 !=
1359  strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute))
1360  continue;
1361  del_entry->refcount++;
1362  // Found match prematurely
1363  send_lookup_response (vrh);
1364  return 1;
1365  }
1366 
1367  // None match, therefore start for every delegation found a lookup chain
1368  // Return and end collect process on first chain iss <-> sub found
1369 
1370  // ds_entry created belongs to the first lookup, vrh still has the
1371  // issuer+attr we look for
1372  for (del_entry = vrh->del_chain_head; del_entry != NULL;
1373  del_entry = del_entry->next)
1374  {
1375 
1377  "Looking for %s.%s\n",
1379  &del_entry->delegate->issuer_key),
1380  del_entry->delegate->issuer_attribute);
1381 
1382  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1383  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1384  ds_entry->from_bw = false;
1385  ds_entry->issuer_key = GNUNET_new (struct GNUNET_IDENTITY_PublicKey);
1386  GNUNET_memcpy (ds_entry->issuer_key,
1387  &del_entry->delegate->subject_key,
1388  sizeof (struct GNUNET_IDENTITY_PublicKey));
1389 
1391  ds_entry->delegation_chain_entry->subject_key =
1392  del_entry->delegate->subject_key;
1393  ds_entry->delegation_chain_entry->subject_attribute = NULL;
1394  ds_entry->delegation_chain_entry->issuer_key =
1395  del_entry->delegate->issuer_key;
1397  GNUNET_strdup (del_entry->delegate->issuer_attribute);
1398 
1399  ds_entry->attr_trailer =
1400  GNUNET_strdup (del_entry->delegate->issuer_attribute);
1401  ds_entry->handle = vrh;
1402 
1403  vrh->pending_lookups++;
1404  // Start with forward resolution
1405  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start Forward Resolution\n");
1406 
1407  ds_entry->lookup_request =
1410  &del_entry->delegate->issuer_key, // issuer_key,
1414  ds_entry);
1415  }
1416  return 0;
1417 }
1418 
1419 
1420 static int
1421 check_verify (void *cls, const struct VerifyMessage *v_msg)
1422 {
1423  size_t msg_size;
1424  const char *attr;
1425 
1426  msg_size = ntohs (v_msg->header.size);
1427  if (msg_size < sizeof (struct VerifyMessage))
1428  {
1429  GNUNET_break (0);
1430  return GNUNET_SYSERR;
1431  }
1432  if (ntohs (v_msg->issuer_attribute_len) > GNUNET_ABD_MAX_LENGTH)
1433  {
1434  GNUNET_break (0);
1435  return GNUNET_SYSERR;
1436  }
1437  attr = (const char *) &v_msg[1];
1438 
1439  if (strlen (attr) > GNUNET_ABD_MAX_LENGTH)
1440  {
1441  GNUNET_break (0);
1442  return GNUNET_SYSERR;
1443  }
1444  return GNUNET_OK;
1445 }
1446 
1447 
1448 static void
1449 handle_verify (void *cls, const struct VerifyMessage *v_msg)
1450 {
1451  struct VerifyRequestHandle *vrh;
1452  struct GNUNET_SERVICE_Client *client = cls;
1453  struct DelegateRecordEntry *del_entry;
1454  uint32_t delegate_count;
1455  uint32_t delegate_data_size;
1456  char attr[GNUNET_ABD_MAX_LENGTH + 1];
1457  char issuer_attribute[GNUNET_ABD_MAX_LENGTH + 1];
1458  char *attrptr = attr;
1459  char *delegate_data;
1460  const char *utf_in;
1461 
1462  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n");
1463  utf_in = (const char *) &v_msg[1];
1464  GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1465  GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len));
1466  issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0';
1467  vrh = GNUNET_new (struct VerifyRequestHandle);
1468  vrh->is_collect = false;
1470  vrh->client = client;
1471  vrh->request_id = v_msg->id;
1472  vrh->issuer_key = v_msg->issuer_key;
1473  vrh->subject_key = v_msg->subject_key;
1474  vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1475  vrh->resolution_algo = ntohs (v_msg->resolution_algo);
1476 
1477  vrh->del_chain_head = NULL;
1478  vrh->del_chain_tail = NULL;
1479  vrh->dsq_head = NULL;
1480  vrh->dsq_tail = NULL;
1481  vrh->del_chain_head = NULL;
1482  vrh->del_chain_tail = NULL;
1483 
1485  if (0 == strlen (issuer_attribute))
1486  {
1487  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1488  send_lookup_response (vrh);
1489  return;
1490  }
1491 
1492  // Parse delegates from verifaction message
1493  delegate_count = ntohl (v_msg->d_count);
1494  delegate_data_size = ntohs (v_msg->header.size)
1495  - sizeof (struct VerifyMessage)
1496  - ntohs (v_msg->issuer_attribute_len) - 1;
1497  struct GNUNET_ABD_Delegate delegates[delegate_count];
1498  memset (delegates,
1499  0,
1500  sizeof (struct GNUNET_ABD_Delegate) * delegate_count);
1501  delegate_data = (char *) &v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1;
1502  if (GNUNET_OK != GNUNET_ABD_delegates_deserialize (delegate_data_size,
1503  delegate_data,
1504  delegate_count,
1505  delegates))
1506  {
1507  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot deserialize delegates!\n");
1508  send_lookup_response (vrh);
1509  return;
1510  }
1511 
1512  // Prepare vrh delegation chain for later validation
1513  for (uint32_t i = 0; i < delegate_count; i++)
1514  {
1515  del_entry = GNUNET_new (struct DelegateRecordEntry);
1516  del_entry->delegate =
1517  GNUNET_malloc (sizeof (struct GNUNET_ABD_Delegate)
1518  + delegates[i].issuer_attribute_len + 1);
1519  GNUNET_memcpy (del_entry->delegate,
1520  &delegates[i],
1521  sizeof (struct GNUNET_ABD_Delegate));
1522  GNUNET_memcpy (&del_entry->delegate[1],
1523  delegates[i].issuer_attribute,
1524  delegates[i].issuer_attribute_len);
1525  del_entry->delegate->issuer_attribute_len =
1526  delegates[i].issuer_attribute_len;
1527  del_entry->delegate->issuer_attribute = (char *) &del_entry->delegate[1];
1529  vrh->del_chain_tail,
1530  del_entry);
1531  vrh->del_chain_size++;
1532  }
1533 
1534  // Switch resolution algo
1537  {
1538  if (1 == delegation_chain_fw_resolution_start (vrh))
1539  return;
1541  }
1542  else if (GNUNET_ABD_FLAG_BACKWARD & vrh->resolution_algo)
1543  {
1545  }
1546  else if (GNUNET_ABD_FLAG_FORWARD & vrh->resolution_algo)
1547  {
1549  }
1550 }
1551 
1552 
1553 static void
1555 {
1556  struct VerifyRequestHandle *vrh = cls;
1558  "Got disconnected from namestore database.\n");
1559  vrh->dele_qe = NULL;
1560  send_lookup_response (vrh);
1561 }
1562 
1563 
1564 static void
1566 {
1567  struct VerifyRequestHandle *vrh = cls;
1568  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done collecting delegates.\n");
1569 
1570  // if both are set: bidirectional search, meaning start both chain resolutions
1573  {
1574  // if premature match found don't start bw resolution
1575  if (1 == delegation_chain_fw_resolution_start (vrh))
1576  return;
1578  }
1579  else if (GNUNET_ABD_FLAG_BACKWARD & vrh->resolution_algo)
1580  {
1582  }
1583  else if (GNUNET_ABD_FLAG_FORWARD & vrh->resolution_algo)
1584  {
1586  }
1587 }
1588 
1589 
1590 static void
1592  const struct GNUNET_IDENTITY_PrivateKey *key,
1593  const char *label,
1594  unsigned int rd_count,
1595  const struct GNUNET_GNSRECORD_Data *rd)
1596 {
1597  struct VerifyRequestHandle *vrh = cls;
1598  struct DelegateRecordEntry *del_entry;
1599  vrh->dele_qe = NULL;
1600 
1601  for (uint32_t i = 0; i < rd_count; i++)
1602  {
1603  if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type)
1604  continue;
1605  // only add the entries that are explicitly marked as private
1606  // and therefore symbolize the end of a chain
1607  if (0 == (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))
1608  continue;
1609  del_entry = GNUNET_new (struct DelegateRecordEntry);
1610  del_entry->delegate = GNUNET_ABD_delegate_deserialize (rd[i].data, rd[i].data_size);
1611  if (NULL == del_entry->delegate)
1612  {
1613  GNUNET_free (del_entry);
1614  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid delegate found\n");
1615  continue;
1616  }
1618  vrh->del_chain_tail,
1619  del_entry);
1620  vrh->del_chain_size++;
1621  }
1622 
1624 }
1625 
1626 
1627 static void
1628 handle_collect (void *cls, const struct CollectMessage *c_msg)
1629 {
1630  char attr[GNUNET_ABD_MAX_LENGTH + 1];
1631  char issuer_attribute[GNUNET_ABD_MAX_LENGTH + 1];
1632  struct VerifyRequestHandle *vrh;
1633  struct GNUNET_SERVICE_Client *client = cls;
1634  char *attrptr = attr;
1635  const char *utf_in;
1636 
1637  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received COLLECT message\n");
1638 
1639  utf_in = (const char *) &c_msg[1];
1640  GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1641 
1642  GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len));
1643  issuer_attribute[ntohs (c_msg->issuer_attribute_len)] = '\0';
1644  vrh = GNUNET_new (struct VerifyRequestHandle);
1645  vrh->is_collect = true;
1647  vrh->client = client;
1648  vrh->request_id = c_msg->id;
1649  vrh->issuer_key = c_msg->issuer_key;
1651  vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1652  vrh->resolution_algo = ntohs (c_msg->resolution_algo);
1653 
1654  vrh->del_chain_head = NULL;
1655  vrh->del_chain_tail = NULL;
1656  vrh->dsq_head = NULL;
1657  vrh->dsq_tail = NULL;
1658  vrh->del_chain_head = NULL;
1659  vrh->del_chain_tail = NULL;
1660 
1661  if (0 == strlen (issuer_attribute))
1662  {
1663  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1664  send_lookup_response (vrh);
1665  return;
1666  }
1667  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting delegates for subject\n");
1668 
1669  // Get all delegates from subject
1670  vrh->dele_qe =
1672  &c_msg->subject_key,
1675  vrh,
1677  vrh);
1679 }
1680 
1681 
1682 static int
1683 check_collect (void *cls, const struct CollectMessage *c_msg)
1684 {
1685  size_t msg_size;
1686  const char *attr;
1687 
1688  msg_size = ntohs (c_msg->header.size);
1689  if (msg_size < sizeof (struct CollectMessage))
1690  {
1691  GNUNET_break (0);
1692  return GNUNET_SYSERR;
1693  }
1694  if (ntohs (c_msg->issuer_attribute_len) > GNUNET_ABD_MAX_LENGTH)
1695  {
1696  GNUNET_break (0);
1697  return GNUNET_SYSERR;
1698  }
1699  attr = (const char *) &c_msg[1];
1700 
1701  if (('\0' != attr[msg_size - sizeof (struct CollectMessage) - 1]) ||
1702  (strlen (attr) > GNUNET_ABD_MAX_LENGTH))
1703  {
1704  GNUNET_break (0);
1705  return GNUNET_SYSERR;
1706  }
1707  return GNUNET_OK;
1708 }
1709 
1710 
1711 static void
1713  struct GNUNET_SERVICE_Client *client,
1714  void *app_ctx)
1715 {
1716  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1717 }
1718 
1719 
1720 static void *
1722  struct GNUNET_SERVICE_Client *client,
1723  struct GNUNET_MQ_Handle *mq)
1724 {
1725  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1726  return client;
1727 }
1728 
1729 
1737 static void
1738 run (void *cls,
1739  const struct GNUNET_CONFIGURATION_Handle *c,
1740  struct GNUNET_SERVICE_Handle *handle)
1741 {
1742 
1743  gns = GNUNET_GNS_connect (c);
1744  if (NULL == gns)
1745  {
1746  fprintf (stderr, _ ("Failed to connect to GNS\n"));
1747  }
1749  if (NULL == namestore)
1750  {
1751  fprintf (stderr, _ ("Failed to connect to namestore\n"));
1752  }
1753 
1754  statistics = GNUNET_STATISTICS_create ("abd", c);
1756 }
1757 
1758 
1763  "abd",
1765  &run,
1768  NULL,
1771  struct VerifyMessage,
1772  NULL),
1775  struct CollectMessage,
1776  NULL),
1778 
1779 /* 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 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
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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:412
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.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
@ GNUNET_GNSRECORD_RF_PRIVATE
This is a private record of this peer and it should thus not be handed out to other peers.
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:175
char * GNUNET_IDENTITY_public_key_to_string(const struct GNUNET_IDENTITY_PublicKey *key)
Creates a (Base32) string representation of the public key.
#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:302
#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:52
#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:1331
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2442
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2248
@ 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:450
static unsigned int size
Size of the "table".
Definition: peer.c:67
#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:86
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:54
Handle to a client that is connected to a service.
Definition: service.c:251
Handle to a service.
Definition: service.c:117
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.