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 
315  enum GNUNET_ABD_AlgoDirectionFlags resolution_algo;
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_non_null (ds_entry->issuer_key);
370  // those fields are only set/used in bw search
371  if (ds_entry->from_bw)
372  {
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  {
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_non_null (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);
445  GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
446  cleanup_handle (vrh);
447  }
448 
449  if (NULL != gns)
450  {
451  GNUNET_GNS_disconnect (gns);
452  gns = NULL;
453  }
454  if (NULL != namestore)
455  {
456  GNUNET_NAMESTORE_disconnect (namestore);
457  namestore = NULL;
458  }
459  if (NULL != statistics)
460  {
461  GNUNET_STATISTICS_destroy (statistics, GNUNET_NO);
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 
517 
518 static void
520 {
521  struct GNUNET_MQ_Envelope *env;
522  struct DelegationChainResultMessage *rmsg;
523  struct DelegationChainEntry *dce;
524  struct GNUNET_ABD_Delegation dd[vrh->delegation_chain_size];
525  struct GNUNET_ABD_Delegate dele[vrh->del_chain_size];
526  struct DelegateRecordEntry *del;
527  struct DelegateRecordEntry *tmp;
528  size_t size;
529 
530  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n");
531  dce = vrh->delegation_chain_head;
532  for (uint32_t i = 0; i < vrh->delegation_chain_size; i++)
533  {
534  dd[i].issuer_key = dce->issuer_key;
535  dd[i].subject_key = dce->subject_key;
536  dd[i].issuer_attribute = dce->issuer_attribute;
537  dd[i].issuer_attribute_len = strlen (dce->issuer_attribute) + 1;
538  dd[i].subject_attribute_len = 0;
539  dd[i].subject_attribute = NULL;
540  if (NULL != dce->subject_attribute)
541  {
543  dd[i].subject_attribute_len = strlen (dce->subject_attribute) + 1;
544  }
545  dce = dce->next;
546  }
547 
548  // Remove all not needed credentials
549  for (del = vrh->del_chain_head; NULL != del;)
550  {
551  if (del->refcount > 0)
552  {
553  del = del->next;
554  continue;
555  }
556  tmp = del;
557  del = del->next;
558  GNUNET_CONTAINER_DLL_remove (vrh->del_chain_head, vrh->del_chain_tail, tmp);
559  GNUNET_free (tmp->delegate);
560  GNUNET_free (tmp);
561  vrh->del_chain_size--;
562  }
563 
564  // Get serialized record data
565  // Append at the end of rmsg
566  del = vrh->del_chain_head;
567  for (uint32_t i = 0; i < vrh->del_chain_size; i++)
568  {
569  dele[i].issuer_key = del->delegate->issuer_key;
570  dele[i].subject_key = del->delegate->subject_key;
571  dele[i].issuer_attribute_len = strlen (del->delegate->issuer_attribute) + 1;
575  dele[i].expiration = del->delegate->expiration;
576  dele[i].signature = del->delegate->signature;
577  del = del->next;
578  }
579  size =
580  GNUNET_ABD_delegation_chain_get_size (vrh->delegation_chain_size,
581  dd,
582  vrh->del_chain_size,
583  dele);
584  env = GNUNET_MQ_msg_extra (rmsg,
585  size,
587  // Assign id so that client can find associated request
588  rmsg->id = vrh->request_id;
589  rmsg->d_count = htonl (vrh->delegation_chain_size);
590  rmsg->c_count = htonl (vrh->del_chain_size);
591 
592  if (0 < vrh->del_chain_size)
593  rmsg->del_found = htonl (GNUNET_YES);
594  else
595  rmsg->del_found = htonl (GNUNET_NO);
596 
597  GNUNET_assert (
598  -1 !=
599  GNUNET_ABD_delegation_chain_serialize (vrh->delegation_chain_size,
600  dd,
601  vrh->del_chain_size,
602  dele,
603  size,
604  (char *) &rmsg[1]));
605 
606  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (vrh->client), env);
607  GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
608  cleanup_handle (vrh);
609  GNUNET_STATISTICS_update (statistics,
610  "Completed verifications",
611  1,
612  GNUNET_NO);
613 }
614 
615 
616 static char *
617 partial_match (char *tmp_trail,
618  char *tmp_subattr,
619  char *parent_trail,
620  char *issuer_attribute)
621 {
622  char *saveptr1, *saveptr2;
623  char *trail_token;
624  char *sub_token;
625  char *attr_trailer;
626 
627  // tok both, parent->attr_trailer and del->sub_attr to see how far they match,
628  // take rest of parent trailer (only when del->sub_attr token is null), and
629  // create new/actual trailer with del->iss_attr
630  trail_token = strtok_r (tmp_trail, ".", &saveptr1);
631  sub_token = strtok_r (tmp_subattr, ".", &saveptr2);
632  while (NULL != trail_token && NULL != sub_token)
633  {
634  if (0 == strcmp (trail_token, sub_token))
635  {
636  // good, matches, remove
637  }
638  else
639  {
640  // not relevant for solving the chain, end for iteration here
641  return NULL;
642  }
643 
644  trail_token = strtok_r (NULL, ".", &saveptr1);
645  sub_token = strtok_r (NULL, ".", &saveptr2);
646  }
647  // skip this entry and go to next for if:
648  // 1. at some point the attr of the trailer and the subject dont match
649  // 2. the trailer is NULL, but the subject has more attributes
650  // Reason: This will lead to "startzone.attribute" but we're looking for a solution
651  // for "<- startzone"
652  if (NULL == trail_token)
653  {
654  return NULL;
655  }
656 
657  // do not have to check sub_token == NULL, if both would be NULL
658  // at the same time, the complete match part above should have triggered already
659 
660  // otherwise, above while only ends when sub_token == NULL
661  GNUNET_asprintf (&attr_trailer, "%s", trail_token);
662  trail_token = strtok_r (NULL, ".", &saveptr1);
663  while (NULL != trail_token)
664  {
665  GNUNET_asprintf (&attr_trailer, "%s.%s", parent_trail, trail_token);
666  trail_token = strtok_r (NULL, ".", &saveptr1);
667  }
668  GNUNET_asprintf (&attr_trailer, "%s.%s", issuer_attribute, attr_trailer);
669  return attr_trailer;
670 }
671 
672 
673 static int
675  struct DelegationSetQueueEntry *match_entry,
676  struct VerifyRequestHandle *vrh)
677 {
678  struct DelegationSetQueueEntry *old_fw_parent;
679  struct DelegationSetQueueEntry *fw_entry = actual_entry;
680  struct DelegationSetQueueEntry *last_entry = match_entry;
681  // parent fixing, combine backward and forward chain parts
682  while (NULL != fw_entry->parent_queue_entry)
683  {
684  old_fw_parent = fw_entry->parent_queue_entry->parent_set;
685  // set parent
686  fw_entry->parent_queue_entry->parent_set = last_entry;
687 
688  last_entry = fw_entry;
689  fw_entry = old_fw_parent;
690  }
691  // set last entry of chain as actual_entry
692  // actual_entry = last_entry;
693  // set refcount, loop all delegations
694  for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head;
695  del_entry != NULL;
696  del_entry = del_entry->next)
697  {
698  if (0 != memcmp (&last_entry->delegation_chain_entry->subject_key,
699  &del_entry->delegate->issuer_key,
700  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
701  continue;
702  if (0 != strcmp (last_entry->delegation_chain_entry->subject_attribute,
703  del_entry->delegate->issuer_attribute))
704  continue;
705 
706  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found delegate.\n");
707  // increase refcount of the start delegation
708  del_entry->refcount++;
709  }
710  // backtrack
711  for (struct DelegationSetQueueEntry *tmp_set = last_entry;
712  NULL != tmp_set->parent_queue_entry;
713  tmp_set = tmp_set->parent_queue_entry->parent_set)
714  {
715  tmp_set->parent_queue_entry->required_solutions--;
716 
717  // add new found entry to vrh
718  vrh->delegation_chain_size++;
721  tmp_set->delegation_chain_entry);
722 
723  // if one node on the path still needs solutions, this current
724  // patch cannot fullfil the conditions and therefore stops here
725  // however, it is in the vrh and can be used by the other paths
726  // related to this path/collection/verification
727  if (0 < tmp_set->parent_queue_entry->required_solutions)
728  {
730  "Chain requires more solutions, waiting...\n");
731  return GNUNET_NO;
732  }
733  }
734  return GNUNET_YES;
735 }
736 
737 
738 static void
740  uint32_t rd_count,
741  const struct GNUNET_GNSRECORD_Data *rd)
742 {
743  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d entries.\n", rd_count);
744 
745  struct VerifyRequestHandle *vrh;
746  struct DelegationSetQueueEntry *current_set;
747  struct DelegationSetQueueEntry *ds_entry;
748  struct DelegationQueueEntry *dq_entry;
749 
750  current_set = cls;
751  // set handle to NULL (as el = NULL)
752  current_set->lookup_request = NULL;
753  vrh = current_set->handle;
754  vrh->pending_lookups--;
755 
756  // Loop record entries
757  for (uint32_t i = 0; i < rd_count; i++)
758  {
759  if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type)
760  continue;
761 
762  // Start deserialize into Delegate
763  struct GNUNET_ABD_Delegate *del;
764  del = GNUNET_ABD_delegate_deserialize (rd[i].data, rd[i].data_size);
765 
766  // Start: Create DQ Entry
767  dq_entry = GNUNET_new (struct DelegationQueueEntry);
768  // AND delegations are not possible, only 1 solution
769  dq_entry->required_solutions = 1;
770  dq_entry->parent_set = current_set;
771 
772  // Insert it into the current set
774  current_set->queue_entries_tail,
775  dq_entry);
776 
777  // Start: Create DS Entry
778  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
779  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
780  ds_entry->from_bw = false;
781 
782  // (1) A.a <- A.b.c
783  // (2) A.b <- D.d
784  // (3) D.d <- E
785  // (4) E.c <- F.c
786  // (5) F.c <- G
787  // Possibilities:
788  // 1. complete match: trailer = 0, validate
789  // 2. partial match: replace
790  // 3. new solution: replace, add trailer
791 
792  // At resolution chain start trailer of parent is NULL
793  if (NULL == current_set->attr_trailer)
794  {
795  // for (5) F.c <- G, remember .c when going upwards
796  ds_entry->attr_trailer = GNUNET_strdup (del->issuer_attribute);
797  }
798  else
799  {
800  if (0 == del->subject_attribute_len)
801  {
802  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: New solution\n");
803  // new solution
804  // create new trailer del->issuer_attribute, ds_entry->attr_trailer
805  GNUNET_asprintf (&ds_entry->attr_trailer,
806  "%s.%s",
807  del->issuer_attribute,
808  current_set->attr_trailer);
809  }
810  else if (0 == strcmp (del->subject_attribute, current_set->attr_trailer))
811  {
812  // complete match
813  // new trailer == issuer attribute (e.g. (5) to (4))
814  ds_entry->attr_trailer = GNUNET_strdup (del->issuer_attribute);
815  }
816  else
817  {
818  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Partial match\n");
819  // partial match
820 
821  char *trail = partial_match (GNUNET_strdup (current_set->attr_trailer),
823  current_set->attr_trailer,
825 
826  // if null: skip this record entry (reasons: mismatch or overmatch, both not relevant)
827  if (NULL == trail)
828  {
830  "Entry not relevant, discarding: %s.%s <- %s.%s\n",
832  &del->issuer_key),
833  del->issuer_attribute,
835  &del->subject_key),
836  del->subject_attribute);
837  continue;
838  }
839  else
840  ds_entry->attr_trailer = trail;
841  }
842  }
843 
844 
845  // Start: Credential Chain Entry
846  // issuer key is subject key, who needs to be contacted to resolve this (forward, therefore subject)
848  GNUNET_memcpy (ds_entry->issuer_key,
849  &del->subject_key,
850  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
851 
854  if (0 < del->subject_attribute_len)
857  ds_entry->delegation_chain_entry->issuer_key = del->issuer_key;
860 
861  // Found new entry, repoting intermediate result
862  send_intermediate_response (vrh, ds_entry->delegation_chain_entry, false);
863 
864  // current delegation as parent
865  ds_entry->parent_queue_entry = dq_entry;
866 
867  // Check for solution
868  // if: issuer key we looking for
869  if (0 == memcmp (&del->issuer_key,
870  &vrh->issuer_key,
871  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
872  {
873  // if: issuer attr we looking for
874  if (0 == strcmp (del->issuer_attribute, vrh->issuer_attribute))
875  {
876  // if: complete match, meaning new trailer == issuer attr
877  if (0 == strcmp (vrh->issuer_attribute, ds_entry->attr_trailer))
878  {
879  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Solution\n");
880 
881  // Add found solution into delegation_chain
882  struct DelegationSetQueueEntry *tmp_set;
883  for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
884  tmp_set = tmp_set->parent_queue_entry->parent_set)
885  {
886  if (NULL != tmp_set->delegation_chain_entry)
887  {
888  vrh->delegation_chain_size++;
891  tmp_set->delegation_chain_entry);
892  }
893  }
894 
895  // Increase refcount for this delegate
896  for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head;
897  del_entry != NULL;
898  del_entry = del_entry->next)
899  {
900  if (0 == memcmp (&del_entry->delegate->issuer_key,
902  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
903  {
904  if (0 == strcmp (del_entry->delegate->issuer_attribute,
906  {
907  del_entry->refcount++;
908  }
909  }
910  }
911 
912  send_lookup_response (vrh);
913  return;
914  }
915  }
916  }
917 
918  // Check for bidirectional crossmatch
919  for (struct DelegationSetQueueEntry *del_entry = vrh->dsq_head;
920  del_entry != NULL;
921  del_entry = del_entry->next)
922  {
923  // only check entries not by backward algorithm
924  if (del_entry->from_bw)
925  {
926  // key of list entry matches actual key
927  if (0 == memcmp (&del_entry->delegation_chain_entry->subject_key,
929  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
930  {
931  // compare entry subject attributes to this trailer (iss attr + old trailer)
932  if (0 == strcmp (del_entry->unresolved_attribute_delegation,
933  ds_entry->attr_trailer))
934  {
935  print_deleset (del_entry, "Forward:");
937  "Forward: Found match with above!\n");
938 
939  // one node on the path still needs solutions: return
940  if (GNUNET_NO ==
941  handle_bidirectional_match (ds_entry, del_entry, vrh))
942  return;
943 
944  send_lookup_response (vrh);
945  return;
946  }
947  }
948  }
949  }
950 
951  // Starting a new GNS lookup
952  vrh->pending_lookups++;
953  ds_entry->handle = vrh;
954 
956  "Starting to look up trailer %s in zone %s\n",
957  ds_entry->attr_trailer,
959 
960  ds_entry->lookup_request =
961  GNUNET_GNS_lookup (gns,
963  &del->issuer_key,
967  ds_entry);
968  }
969 
970  if (0 == vrh->pending_lookups)
971  {
972  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
973  send_lookup_response (vrh);
974  return;
975  }
976 }
977 
978 
979 static void
981  uint32_t rd_count,
982  const struct GNUNET_GNSRECORD_Data *rd)
983 {
984  struct VerifyRequestHandle *vrh;
985  const struct GNUNET_ABD_DelegationRecord *sets;
986  struct DelegateRecordEntry *del_pointer;
987  struct DelegationSetQueueEntry *current_set;
988  struct DelegationSetQueueEntry *ds_entry;
989  struct DelegationSetQueueEntry *tmp_set;
990  struct DelegationQueueEntry *dq_entry;
991  char *expanded_attr;
992  char *lookup_attribute;
993 
994  current_set = cls;
995  current_set->lookup_request = NULL;
996  vrh = current_set->handle;
997  vrh->pending_lookups--;
998 
999  // Each OR
1000  for (uint32_t i = 0; i < rd_count; i++)
1001  {
1002  if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
1003  continue;
1004 
1005  sets = rd[i].data;
1006  struct GNUNET_ABD_DelegationSet set[ntohl (sets->set_count)];
1008  "Found new attribute delegation with %d sets. Creating new Job...\n",
1009  ntohl (sets->set_count));
1010 
1011  if (GNUNET_OK !=
1013  sets->data_size),
1014  (const char *) &sets[1],
1015  ntohl (sets->set_count),
1016  set))
1017  {
1018  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n");
1019  continue;
1020  }
1021  dq_entry = GNUNET_new (struct DelegationQueueEntry);
1022  dq_entry->required_solutions = ntohl (sets->set_count);
1023  dq_entry->parent_set = current_set;
1024 
1026  current_set->queue_entries_tail,
1027  dq_entry);
1028  // Each AND
1029  for (uint32_t j = 0; j < ntohl (sets->set_count); j++)
1030  {
1031  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1032  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1033  ds_entry->from_bw = true;
1034 
1035  if (NULL != current_set->attr_trailer)
1036  {
1037  if (0 == set[j].subject_attribute_len)
1038  {
1039  GNUNET_asprintf (&expanded_attr, "%s", current_set->attr_trailer);
1040  }
1041  else
1042  {
1043  GNUNET_asprintf (&expanded_attr,
1044  "%s.%s",
1045  set[j].subject_attribute,
1046  current_set->attr_trailer);
1047  }
1048  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expanded to %s\n", expanded_attr);
1049  ds_entry->unresolved_attribute_delegation = expanded_attr;
1050  }
1051  else
1052  {
1053  if (0 != set[j].subject_attribute_len)
1054  {
1056  "Not Expanding %s\n",
1057  set[j].subject_attribute);
1059  GNUNET_strdup (set[j].subject_attribute);
1060  }
1061  }
1062 
1063  // Add a credential chain entry
1064  ds_entry->delegation_chain_entry =
1066  ds_entry->delegation_chain_entry->subject_key = set[j].subject_key;
1067  ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
1068  GNUNET_memcpy (ds_entry->issuer_key,
1069  &set[j].subject_key,
1070  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1071  if (0 < set[j].subject_attribute_len)
1074  ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key;
1076  GNUNET_strdup (current_set->lookup_attribute);
1077 
1078  // Found new entry, repoting intermediate result
1079  send_intermediate_response (vrh, ds_entry->delegation_chain_entry, true);
1080 
1081  ds_entry->parent_queue_entry = dq_entry; // current_delegation;
1082 
1086  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking for cred match\n");
1087 
1088  for (del_pointer = vrh->del_chain_head; del_pointer != NULL;
1089  del_pointer = del_pointer->next)
1090  {
1091  // If key and attribute match credential: continue and backtrack
1092  if (0 != memcmp (&set[j].subject_key,
1093  &del_pointer->delegate->issuer_key,
1094  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1095  continue;
1097  "Checking if %s matches %s\n",
1099  del_pointer->delegate->issuer_attribute);
1100 
1101  if (0 != strcmp (ds_entry->unresolved_attribute_delegation,
1102  del_pointer->delegate->issuer_attribute))
1103  continue;
1104 
1105  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n");
1106  // increase refcount of the start delegation
1107  del_pointer->refcount++;
1108 
1109  // Backtrack
1110  for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
1111  tmp_set = tmp_set->parent_queue_entry->parent_set)
1112  {
1114  if (NULL != tmp_set->delegation_chain_entry)
1115  {
1116  vrh->delegation_chain_size++;
1118  vrh->delegation_chain_tail,
1119  tmp_set->delegation_chain_entry);
1120  }
1121  if (0 < tmp_set->parent_queue_entry->required_solutions)
1122  break;
1123  }
1124 
1125  // if the break above is not called the condition of the for is met
1126  if (NULL == tmp_set->parent_queue_entry)
1127  {
1128  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All solutions found\n");
1129  // Found match
1130  send_lookup_response (vrh);
1131  return;
1132  }
1133  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not all solutions found yet.\n");
1134  continue;
1135  }
1136 
1138  "Building new lookup request from %s\n",
1140  // Continue with next/new backward resolution
1141  char issuer_attribute_name[strlen (
1143  + 1];
1144  strcpy (issuer_attribute_name, ds_entry->unresolved_attribute_delegation);
1145  char *next_attr = strtok (issuer_attribute_name, ".");
1146  if (NULL == next_attr)
1147  {
1149  "Failed to parse next attribute\n");
1150  continue;
1151  }
1152  GNUNET_asprintf (&lookup_attribute, "%s", next_attr);
1153  GNUNET_asprintf (&ds_entry->lookup_attribute, "%s", next_attr);
1154  if (strlen (next_attr) ==
1155  strlen (ds_entry->unresolved_attribute_delegation))
1156  {
1157  ds_entry->attr_trailer = NULL;
1158  }
1159  else
1160  {
1161  next_attr += strlen (next_attr) + 1;
1162  ds_entry->attr_trailer = GNUNET_strdup (next_attr);
1163  }
1164 
1165  // Check for bidirectional crossmatch
1166  for (struct DelegationSetQueueEntry *del_entry = vrh->dsq_head;
1167  del_entry != NULL;
1168  del_entry = del_entry->next)
1169  {
1170  // only check entries added by forward algorithm
1171  if (! del_entry->from_bw)
1172  {
1173  // key of list entry matches actual key
1174  if (0 == memcmp (&del_entry->delegation_chain_entry->issuer_key,
1175  &ds_entry->delegation_chain_entry->subject_key,
1176  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1177  {
1178  // compare entry subject attributes to this trailer (iss attr + old trailer)
1179  if (0 == strcmp (del_entry->attr_trailer,
1181  {
1182  print_deleset (del_entry, "Backward:");
1184  "Backward: Found match with above!\n");
1185 
1186  // if one node on the path still needs solutions: return
1187  if (GNUNET_NO ==
1188  handle_bidirectional_match (del_entry, ds_entry, vrh))
1189  break;
1190 
1191  // Send lookup response
1192  send_lookup_response (vrh);
1193  return;
1194  }
1195  }
1196  }
1197  }
1198 
1199  // Starting a new GNS lookup
1201  "Looking up %s\n",
1202  ds_entry->lookup_attribute);
1203  if (NULL != ds_entry->attr_trailer)
1205  "%s still to go...\n",
1206  ds_entry->attr_trailer);
1207 
1208  vrh->pending_lookups++;
1209  ds_entry->handle = vrh;
1210  ds_entry->lookup_request =
1211  GNUNET_GNS_lookup (gns,
1212  lookup_attribute,
1213  ds_entry->issuer_key, // issuer_key,
1217  ds_entry);
1218 
1219  GNUNET_free (lookup_attribute);
1220  }
1221  }
1222 
1223  if (0 == vrh->pending_lookups)
1224  {
1225  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
1226  send_lookup_response (vrh);
1227  return;
1228  }
1229 }
1230 
1231 
1237 static int
1239 {
1240  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Start Backward Resolution...\n");
1241 
1242  struct VerifyRequestHandle *vrh = cls;
1243  struct DelegationSetQueueEntry *ds_entry;
1244  struct DelegateRecordEntry *del_entry;
1245 
1246  if (0 == vrh->del_chain_size)
1247  {
1248  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegates found\n");
1249  send_lookup_response (vrh);
1250  return 1;
1251  }
1252 
1253  // Pre-check with vrh->dele_chain_.. if match issuer_key
1254  // Backward: check every cred entry if match issuer key
1255  // otherwise: start at issuer and go down till match
1256  // A.a <- ...
1257  // X.x <- C
1258  // Y.y <- C
1259  // if not X.x or Y.y == A.a start at A
1260  for (del_entry = vrh->del_chain_head; del_entry != NULL;
1261  del_entry = del_entry->next)
1262  {
1263  if (0 != memcmp (&del_entry->delegate->issuer_key,
1264  &vrh->issuer_key,
1265  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1266  continue;
1267  if (0 !=
1268  strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute))
1269  continue;
1270  del_entry->refcount++;
1271  // Found match prematurely
1272  send_lookup_response (vrh);
1273  return 1;
1274  }
1275 
1276 
1277  // Check for attributes from the issuer and follow the chain
1278  // till you get the required subject's attributes
1279  char issuer_attribute_name[strlen (vrh->issuer_attribute) + 1];
1280  strcpy (issuer_attribute_name, vrh->issuer_attribute);
1282  "Looking up %s\n",
1283  issuer_attribute_name);
1284  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1285  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1286  ds_entry->from_bw = true;
1287  ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
1288  GNUNET_memcpy (ds_entry->issuer_key,
1289  &vrh->issuer_key,
1290  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1291  ds_entry->issuer_attribute = GNUNET_strdup (vrh->issuer_attribute);
1292 
1294  ds_entry->delegation_chain_entry->issuer_key = vrh->issuer_key;
1297 
1298  ds_entry->handle = vrh;
1299  ds_entry->lookup_attribute = GNUNET_strdup (vrh->issuer_attribute);
1300  ds_entry->unresolved_attribute_delegation = NULL;
1301  vrh->pending_lookups = 1;
1302 
1303  // Start with backward resolution
1304  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start Backward Resolution\n");
1305 
1306  ds_entry->lookup_request = GNUNET_GNS_lookup (gns,
1307  issuer_attribute_name,
1308  &vrh->issuer_key, // issuer_key,
1312  ds_entry);
1313  return 0;
1314 }
1315 
1316 
1317 static int
1319 {
1320  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Start Forward Resolution...\n");
1321 
1322  struct VerifyRequestHandle *vrh = cls;
1323  struct DelegationSetQueueEntry *ds_entry;
1324  struct DelegateRecordEntry *del_entry;
1325 
1326  // set to 0 and increase on each lookup: for fw multiple lookups (may be) started
1327  vrh->pending_lookups = 0;
1328 
1329  if (0 == vrh->del_chain_size)
1330  {
1331  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegations found\n");
1332  send_lookup_response (vrh);
1333  return 1;
1334  }
1335 
1336  // Pre-check with vrh->dele_chain_.. if match issuer_key
1337  // otherwise FW: start mutliple lookups for each vrh->dele_chain
1338  // A.a <- ...
1339  // X.x <- C
1340  // Y.y <- C
1341  // if not X.x or Y.y == A.a start at X and at Y
1342  for (del_entry = vrh->del_chain_head; del_entry != NULL;
1343  del_entry = del_entry->next)
1344  {
1345  if (0 != memcmp (&del_entry->delegate->issuer_key,
1346  &vrh->issuer_key,
1347  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1348  continue;
1349  if (0 !=
1350  strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute))
1351  continue;
1352  del_entry->refcount++;
1353  // Found match prematurely
1354  send_lookup_response (vrh);
1355  return 1;
1356  }
1357 
1358  // None match, therefore start for every delegation found a lookup chain
1359  // Return and end collect process on first chain iss <-> sub found
1360 
1361  // ds_entry created belongs to the first lookup, vrh still has the
1362  // issuer+attr we look for
1363  for (del_entry = vrh->del_chain_head; del_entry != NULL;
1364  del_entry = del_entry->next)
1365  {
1366 
1368  "Looking for %s.%s\n",
1370  &del_entry->delegate->issuer_key),
1371  del_entry->delegate->issuer_attribute);
1372 
1373  ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1374  GNUNET_CONTAINER_DLL_insert (vrh->dsq_head, vrh->dsq_tail, ds_entry);
1375  ds_entry->from_bw = false;
1376  ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
1377  GNUNET_memcpy (ds_entry->issuer_key,
1378  &del_entry->delegate->subject_key,
1379  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1380 
1382  ds_entry->delegation_chain_entry->subject_key =
1383  del_entry->delegate->subject_key;
1384  ds_entry->delegation_chain_entry->subject_attribute = NULL;
1385  ds_entry->delegation_chain_entry->issuer_key =
1386  del_entry->delegate->issuer_key;
1388  GNUNET_strdup (del_entry->delegate->issuer_attribute);
1389 
1390  ds_entry->attr_trailer =
1391  GNUNET_strdup (del_entry->delegate->issuer_attribute);
1392  ds_entry->handle = vrh;
1393 
1394  vrh->pending_lookups++;
1395  // Start with forward resolution
1396  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start Forward Resolution\n");
1397 
1398  ds_entry->lookup_request =
1399  GNUNET_GNS_lookup (gns,
1401  &del_entry->delegate->issuer_key, // issuer_key,
1405  ds_entry);
1406  }
1407  return 0;
1408 }
1409 
1410 
1411 static int
1412 check_verify (void *cls, const struct VerifyMessage *v_msg)
1413 {
1414  size_t msg_size;
1415  const char *attr;
1416 
1417  msg_size = ntohs (v_msg->header.size);
1418  if (msg_size < sizeof (struct VerifyMessage))
1419  {
1420  GNUNET_break (0);
1421  return GNUNET_SYSERR;
1422  }
1423  if (ntohs (v_msg->issuer_attribute_len) > GNUNET_ABD_MAX_LENGTH)
1424  {
1425  GNUNET_break (0);
1426  return GNUNET_SYSERR;
1427  }
1428  attr = (const char *) &v_msg[1];
1429 
1430  if (strlen (attr) > GNUNET_ABD_MAX_LENGTH)
1431  {
1432  GNUNET_break (0);
1433  return GNUNET_SYSERR;
1434  }
1435  return GNUNET_OK;
1436 }
1437 
1438 
1439 static void
1440 handle_verify (void *cls, const struct VerifyMessage *v_msg)
1441 {
1442  struct VerifyRequestHandle *vrh;
1443  struct GNUNET_SERVICE_Client *client = cls;
1444  struct DelegateRecordEntry *del_entry;
1445  uint32_t delegate_count;
1446  uint32_t delegate_data_size;
1447  char attr[GNUNET_ABD_MAX_LENGTH + 1];
1449  char *attrptr = attr;
1450  char *delegate_data;
1451  const char *utf_in;
1452 
1453  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n");
1454  utf_in = (const char *) &v_msg[1];
1455  GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1456  GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len));
1457  issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0';
1458  vrh = GNUNET_new (struct VerifyRequestHandle);
1459  vrh->is_collect = false;
1460  GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
1461  vrh->client = client;
1462  vrh->request_id = v_msg->id;
1463  vrh->issuer_key = v_msg->issuer_key;
1464  vrh->subject_key = v_msg->subject_key;
1465  vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1466  vrh->resolution_algo = ntohs (v_msg->resolution_algo);
1467 
1468  vrh->del_chain_head = NULL;
1469  vrh->del_chain_tail = NULL;
1470  vrh->dsq_head = NULL;
1471  vrh->dsq_tail = NULL;
1472  vrh->del_chain_head = NULL;
1473  vrh->del_chain_tail = NULL;
1474 
1476  if (0 == strlen (issuer_attribute))
1477  {
1478  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1479  send_lookup_response (vrh);
1480  return;
1481  }
1482 
1483  // Parse delegates from verifaction message
1484  delegate_count = ntohl (v_msg->d_count);
1485  delegate_data_size = ntohs (v_msg->header.size)
1486  - sizeof (struct VerifyMessage)
1487  - ntohs (v_msg->issuer_attribute_len) - 1;
1488  struct GNUNET_ABD_Delegate delegates[delegate_count];
1489  memset (delegates,
1490  0,
1491  sizeof (struct GNUNET_ABD_Delegate) * delegate_count);
1492  delegate_data = (char *) &v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1;
1493  if (GNUNET_OK != GNUNET_ABD_delegates_deserialize (delegate_data_size,
1494  delegate_data,
1495  delegate_count,
1496  delegates))
1497  {
1498  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot deserialize delegates!\n");
1499  send_lookup_response (vrh);
1500  return;
1501  }
1502 
1503  // Prepare vrh delegation chain for later validation
1504  for (uint32_t i = 0; i < delegate_count; i++)
1505  {
1506  del_entry = GNUNET_new (struct DelegateRecordEntry);
1507  del_entry->delegate =
1508  GNUNET_malloc (sizeof (struct GNUNET_ABD_Delegate)
1509  + delegates[i].issuer_attribute_len + 1);
1510  GNUNET_memcpy (del_entry->delegate,
1511  &delegates[i],
1512  sizeof (struct GNUNET_ABD_Delegate));
1513  GNUNET_memcpy (&del_entry->delegate[1],
1514  delegates[i].issuer_attribute,
1515  delegates[i].issuer_attribute_len);
1516  del_entry->delegate->issuer_attribute_len =
1517  delegates[i].issuer_attribute_len;
1518  del_entry->delegate->issuer_attribute = (char *) &del_entry->delegate[1];
1520  vrh->del_chain_tail,
1521  del_entry);
1522  vrh->del_chain_size++;
1523  }
1524 
1525  // Switch resolution algo
1528  {
1529  if (1 == delegation_chain_fw_resolution_start (vrh))
1530  return;
1532  }
1533  else if (GNUNET_ABD_FLAG_BACKWARD & vrh->resolution_algo)
1534  {
1536  }
1537  else if (GNUNET_ABD_FLAG_FORWARD & vrh->resolution_algo)
1538  {
1540  }
1541 }
1542 
1543 
1544 static void
1546 {
1547  struct VerifyRequestHandle *vrh = cls;
1549  "Got disconnected from namestore database.\n");
1550  vrh->dele_qe = NULL;
1551  send_lookup_response (vrh);
1552 }
1553 
1554 
1555 static void
1557 {
1558  struct VerifyRequestHandle *vrh = cls;
1559  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done collecting delegates.\n");
1560 
1561  // if both are set: bidirectional search, meaning start both chain resolutions
1564  {
1565  // if premature match found don't start bw resultion
1566  if (1 == delegation_chain_fw_resolution_start (vrh))
1567  return;
1569  }
1570  else if (GNUNET_ABD_FLAG_BACKWARD & vrh->resolution_algo)
1571  {
1573  }
1574  else if (GNUNET_ABD_FLAG_FORWARD & vrh->resolution_algo)
1575  {
1577  }
1578 }
1579 
1580 
1581 static void
1583  const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
1584  const char *label,
1585  unsigned int rd_count,
1586  const struct GNUNET_GNSRECORD_Data *rd)
1587 {
1588  struct VerifyRequestHandle *vrh = cls;
1589  struct GNUNET_ABD_Delegate *del;
1590  struct DelegateRecordEntry *del_entry;
1591  int cred_record_count;
1592  cred_record_count = 0;
1593  vrh->dele_qe = NULL;
1594 
1595  for (uint32_t i = 0; i < rd_count; i++)
1596  {
1597  if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type)
1598  continue;
1599  cred_record_count++;
1600  del = GNUNET_ABD_delegate_deserialize (rd[i].data, rd[i].data_size);
1601  if (NULL == del)
1602  {
1603  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid delegate found\n");
1604  continue;
1605  }
1606  // only add the entries that are explicity marked as private
1607  // and therefor symbolize the end of a chain
1608  if (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)
1609  {
1610  del_entry = GNUNET_new (struct DelegateRecordEntry);
1611  del_entry->delegate = del;
1613  vrh->del_chain_tail,
1614  del_entry);
1615  vrh->del_chain_size++;
1616  }
1617  }
1618 
1620 }
1621 
1622 
1623 static void
1624 handle_collect (void *cls, const struct CollectMessage *c_msg)
1625 {
1626  char attr[GNUNET_ABD_MAX_LENGTH + 1];
1628  struct VerifyRequestHandle *vrh;
1629  struct GNUNET_SERVICE_Client *client = cls;
1630  char *attrptr = attr;
1631  const char *utf_in;
1632 
1633  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received COLLECT message\n");
1634 
1635  utf_in = (const char *) &c_msg[1];
1636  GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1637 
1638  GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len));
1639  issuer_attribute[ntohs (c_msg->issuer_attribute_len)] = '\0';
1640  vrh = GNUNET_new (struct VerifyRequestHandle);
1641  vrh->is_collect = true;
1642  GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
1643  vrh->client = client;
1644  vrh->request_id = c_msg->id;
1645  vrh->issuer_key = c_msg->issuer_key;
1647  vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1648  vrh->resolution_algo = ntohs (c_msg->resolution_algo);
1649 
1650  vrh->del_chain_head = NULL;
1651  vrh->del_chain_tail = NULL;
1652  vrh->dsq_head = NULL;
1653  vrh->dsq_tail = NULL;
1654  vrh->del_chain_head = NULL;
1655  vrh->del_chain_tail = NULL;
1656 
1657  if (0 == strlen (issuer_attribute))
1658  {
1659  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1660  send_lookup_response (vrh);
1661  return;
1662  }
1663  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting delegates for subject\n");
1664 
1665  // Get all delegates from subject
1666  vrh->dele_qe =
1668  &c_msg->subject_key,
1671  vrh,
1673  vrh);
1675 }
1676 
1677 
1678 static int
1679 check_collect (void *cls, const struct CollectMessage *c_msg)
1680 {
1681  size_t msg_size;
1682  const char *attr;
1683 
1684  msg_size = ntohs (c_msg->header.size);
1685  if (msg_size < sizeof (struct CollectMessage))
1686  {
1687  GNUNET_break (0);
1688  return GNUNET_SYSERR;
1689  }
1690  if (ntohs (c_msg->issuer_attribute_len) > GNUNET_ABD_MAX_LENGTH)
1691  {
1692  GNUNET_break (0);
1693  return GNUNET_SYSERR;
1694  }
1695  attr = (const char *) &c_msg[1];
1696 
1697  if (('\0' != attr[msg_size - sizeof (struct CollectMessage) - 1]) ||
1698  (strlen (attr) > GNUNET_ABD_MAX_LENGTH))
1699  {
1700  GNUNET_break (0);
1701  return GNUNET_SYSERR;
1702  }
1703  return GNUNET_OK;
1704 }
1705 
1706 
1707 static void
1709  struct GNUNET_SERVICE_Client *client,
1710  void *app_ctx)
1711 {
1712  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1713 }
1714 
1715 
1716 static void *
1718  struct GNUNET_SERVICE_Client *client,
1719  struct GNUNET_MQ_Handle *mq)
1720 {
1721  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1722  return client;
1723 }
1724 
1725 
1733 static void
1734 run (void *cls,
1735  const struct GNUNET_CONFIGURATION_Handle *c,
1736  struct GNUNET_SERVICE_Handle *handle)
1737 {
1738 
1739  gns = GNUNET_GNS_connect (c);
1740  if (NULL == gns)
1741  {
1742  fprintf (stderr, _ ("Failed to connect to GNS\n"));
1743  }
1744  namestore = GNUNET_NAMESTORE_connect (c);
1745  if (NULL == namestore)
1746  {
1747  fprintf (stderr, _ ("Failed to connect to namestore\n"));
1748  }
1749 
1750  statistics = GNUNET_STATISTICS_create ("abd", c);
1752 }
1753 
1754 
1759  "abd",
1761  &run,
1764  NULL,
1767  struct VerifyMessage,
1768  NULL),
1771  struct CollectMessage,
1772  NULL),
1774 
1775 /* end of gnunet-service-abd.c */
uint64_t pending_lookups
Pending lookups.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct VerifyRequestHandle * next
We keep these in a DLL.
Connection to the GNS service.
Definition: gns_api.h:35
Message from client to Credential service to verify attributes.
Definition: abd.h:74
#define GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT
static void cleanup_handle(struct VerifyRequestHandle *vrh)
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:128
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Public key of the subject this credential was issued to.
struct DelegationQueueEntry * parent
Parent attribute delegation.
struct DelegationChainEntry * prev
DLL.
struct DelegationChainEntry * delegation_chain_tail
Children of this attribute.
static void handle_verify(void *cls, const struct VerifyMessage *v_msg)
IPC messages between ABD API and ABD service.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
uint32_t issuer_attribute_len
Length of the attribute.
Handle to a service.
Definition: service.c:116
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
The subject.
struct VerifyRequestHandle * prev
We keep these in a DLL.
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: abd.h:99
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_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2437
struct DelegationSetQueueEntry * dsq_tail
List for bidirectional matching.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_lookup(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *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.
uint16_t resolution_algo
Direction of the resolution algo.
Definition: abd.h:104
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:109
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
Message from ABD service to client: new results.
Definition: abd.h:118
struct DelegateRecordEntry * prev
DLL.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
char * issuer_attribute
Issuer attribute.
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:161
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
struct GNUNET_ABD_Delegate * delegate
Payload.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct DelegationChainEntry * delegation_chain_entry
The delegation chain entry.
Handle to a lookup request.
Definition: gns_api.c:42
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Trust anchor.
Definition: abd.h:50
static struct VerifyRequestHandle * vrh_head
Head of the DLL.
GNUNET_ABD_AlgoDirectionFlags
static void send_lookup_response(struct VerifyRequestHandle *vrh)
The attribute delegation record.
char * issuer_attribute
Issuer attribute delegated to.
Message from client to Credential service to collect credentials.
Definition: abd.h:35
static void handle_delegate_collection_cb(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
char * issuer_attribute
The issued attribute.
DLL for delegation sets Used for AND delegation set.
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Subject public key.
Definition: abd.h:84
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
bool is_collect
True if created by a collect request.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
static int check_verify(void *cls, const struct VerifyMessage *v_msg)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct DelegationSetQueueEntry * next
DLL.
Message from ABD service to client: new results.
Definition: abd.h:151
Handle for the service.
struct DelegateRecordEntry * del_chain_tail
Delegate DLL.
struct GNUNET_CRYPTO_EcdsaSignature signature
Signature of this credential.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
bool from_bw
True if added by backward resolution.
struct GNUNET_GNS_LookupRequest * lookup_request
GNS handle.
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
The issuer of the credential.
static char * partial_match(char *tmp_trail, char *tmp_subattr, char *parent_trail, char *issuer_attribute)
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.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
enum GNUNET_ABD_AlgoDirectionFlags resolution_algo
Direction of the resolution algo.
struct DelegationQueueEntry * queue_entries_head
Queue entries of this set.
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *handle)
Process Credential requests.
Handle to a client that is connected to a service.
Definition: service.c:250
struct DelegationChainEntry * next
DLL.
uint32_t request_id
request id
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Issuer public key.
struct DelegationQueueEntry * current_delegation
Current Delegation Pointer.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
static int delegation_chain_fw_resolution_start(void *cls)
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define GNUNET_GNSRECORD_TYPE_DELEGATE
65546 reserved
static int delegation_chain_bw_resolution_start(void *cls)
Result from GNS lookup.
#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
struct GNUNET_ABD_Delegate * GNUNET_ABD_delegate_deserialize(const char *data, size_t data_size)
uint32_t del_chain_size
Delegate DLL size.
const void * data
Binary value stored in the DNS record.
static int del
Desired action is to remove a record.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
static void backward_resolution(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Connection to the NAMESTORE service.
struct DelegationSetQueueEntry * prev
DLL.
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:284
DLL for record.
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_ABD_VERIFY.
Definition: abd.h:79
uint32_t subject_attribute_len
Length of the subject attribute.
uint16_t resolution_algo
Direction of the resolution algo.
Definition: abd.h:60
static void handle_delegate_collection_error_cb(void *cls)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct VerifyRequestHandle * handle
Verify handle.
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:262
This is a private record of this peer and it should thus not be handed out to other peers...
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
The issuer of the delegation.
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:237
struct DelegationChainEntry * delegation_chain_head
Children of this attribute.
static void forward_resolution(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
static int collect
Collect mode.
Definition: gnunet-abd.c:132
#define GNUNET_MESSAGE_TYPE_ABD_VERIFY
uint32_t issuer_attribute_len
Length of the issuer attribute.
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...
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
uint32_t refcount
Number of references in delegation chains.
static unsigned int size
Size of the "table".
Definition: peer.c:67
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:172
An QueueEntry used to store information for a pending NAMESTORE record operation. ...
Definition: namestore_api.c:53
struct DelegateRecordEntry * del_chain_head
Delegate DLL.
static void handle_collect(void *cls, const struct CollectMessage *c_msg)
Handle to a lookup operation from api.
uint32_t delegation_chain_size
Size of delegation tree.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
uint32_t id
Unique identifier for this request (for key collisions).
Definition: abd.h:65
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_ABD_VERIFY.
Definition: abd.h:40
struct DelegationQueueEntry * queue_entries_tail
Queue entries of this set.
#define GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT
const char * subject_attribute
The attribute.
char * attr_trailer
Trailing attribute context.
const char * subject_attribute
The subject attribute.
static void delegate_collection_finished(void *cls)
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.
uint32_t d_count
Number of delegates.
Definition: abd.h:94
struct GNUNET_CRYPTO_EcdsaPrivateKey subject_key
Subject public key.
Definition: abd.h:45
Handle to a message queue.
Definition: mq.c:85
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.
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Public key of the subject this attribute was delegated to.
The attribute delegation record.
configuration data
Definition: configuration.c:85
#define GNUNET_MESSAGE_TYPE_ABD_COLLECT
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
static int check_collect(void *cls, const struct CollectMessage *c_msg)
struct DelegationQueueEntry * next
DLL.
#define GNUNET_GNSRECORD_TYPE_ATTRIBUTE
Record type for reverse lookups.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key
Subject public key.
void * GNUNET_GNS_lookup_cancel(struct GNUNET_GNS_LookupRequest *lr)
Cancel pending lookup request.
Definition: gns_api.c:308
struct GNUNET_NAMESTORE_QueueEntry * dele_qe
Delegate iterator for lookup.
struct GNUNET_TIME_Absolute expiration
Expiration of this credential.
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
struct GNUNET_CRYPTO_EcdsaPublicKey * issuer_key
Issuer key.
struct DelegationSetQueueEntry * dsq_head
List for bidirectional matching.
struct GNUNET_SERVICE_Client * client
Handle to the requesting client.
uint16_t issuer_attribute_len
Length of the issuer attribute.
Definition: abd.h:55
uint32_t del_found
Indicates if credential has been found at all.
Definition: abd.h:133
#define GNUNET_YES
Definition: gnunet_common.h:77
char * subject_attribute
The delegated attribute.
Defaults, look in cache, then in DHT.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
#define GNUNET_ABD_MAX_LENGTH
uint32_t required_solutions
Required solutions.
static struct VerifyRequestHandle * vrh_tail
Tail of the DLL.
static struct GNUNET_GNS_Handle * gns
Handle to GNS service.
const char * issuer_attribute
The attribute.
const char * issuer_attribute
The issuer attribute.
static void shutdown_task(void *cls)
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
Trust anchor.
Definition: abd.h:89
static void send_intermediate_response(struct VerifyRequestHandle *vrh, struct DelegationChainEntry *ch_entry, bool is_bw)
struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup(struct GNUNET_GNS_Handle *handle, const char *name, const struct GNUNET_CRYPTO_EcdsaPublicKey *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:336
static void cleanup_dsq_entry(struct DelegationSetQueueEntry *ds_entry)
static int verify
Verify mode.
Definition: gnunet-abd.c:127
uint32_t data
The data value.
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key
The issuer.
static void print_deleset(struct DelegationSetQueueEntry *dsentry, char *text)
API to serialize and deserialize delegation chains and abds.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
struct DelegationQueueEntry * parent_queue_entry
Parent QueueEntry.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
uint32_t subject_attribute_len
Length of the attribute.
uint32_t d_count
The number of delegations in the response.
Definition: abd.h:138
#define GNUNET_malloc(size)
Wrapper around malloc.
static struct GNUNET_NAMESTORE_Handle * namestore
Handle to namestore service.
static int handle_bidirectional_match(struct DelegationSetQueueEntry *actual_entry, struct DelegationSetQueueEntry *match_entry, struct VerifyRequestHandle *vrh)
char * unresolved_attribute_delegation
Still to resolve delegation as string.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
uint32_t c_count
The number of credentials in the response.
Definition: abd.h:143
#define GNUNET_free(ptr)
Wrapper around free.
struct DelegationQueueEntry * prev
DLL.
DLL used for delegations Used for OR delegations.
struct DelegationSetQueueEntry * parent_set
Parent set.
void GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
Convert the utf-8 input string to lower case.
Definition: strings.c:553
struct DelegateRecordEntry * next
DLL.
char * lookup_attribute
The current attribute to look up.