aboutsummaryrefslogtreecommitdiff
path: root/src/credential/gnunet-service-credential.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/credential/gnunet-service-credential.c')
-rw-r--r--src/credential/gnunet-service-credential.c643
1 files changed, 365 insertions, 278 deletions
diff --git a/src/credential/gnunet-service-credential.c b/src/credential/gnunet-service-credential.c
index 2d954f823..41f4f64d6 100644
--- a/src/credential/gnunet-service-credential.c
+++ b/src/credential/gnunet-service-credential.c
@@ -340,7 +340,7 @@ struct VerifyRequestHandle
340 /** 340 /**
341 * Direction of the resolution algo 341 * Direction of the resolution algo
342 */ 342 */
343 enum direction resolution_algo; 343 enum GNUNET_CREDENTIAL_AlgoDirectionFlags resolution_algo;
344 344
345 /** 345 /**
346 * Delegate iterator for lookup 346 * Delegate iterator for lookup
@@ -385,12 +385,14 @@ cleanup_delegation_set (struct DelegationSetQueueEntry *ds_entry)
385 return; 385 return;
386 386
387 for (dq_entry = ds_entry->queue_entries_head; NULL != dq_entry; 387 for (dq_entry = ds_entry->queue_entries_head; NULL != dq_entry;
388 dq_entry = ds_entry->queue_entries_head) { 388 dq_entry = ds_entry->queue_entries_head)
389 {
389 GNUNET_CONTAINER_DLL_remove (ds_entry->queue_entries_head, 390 GNUNET_CONTAINER_DLL_remove (ds_entry->queue_entries_head,
390 ds_entry->queue_entries_tail, 391 ds_entry->queue_entries_tail,
391 dq_entry); 392 dq_entry);
392 for (child = dq_entry->set_entries_head; NULL != child; 393 for (child = dq_entry->set_entries_head; NULL != child;
393 child = dq_entry->set_entries_head) { 394 child = dq_entry->set_entries_head)
395 {
394 GNUNET_CONTAINER_DLL_remove (dq_entry->set_entries_head, 396 GNUNET_CONTAINER_DLL_remove (dq_entry->set_entries_head,
395 dq_entry->set_entries_tail, 397 dq_entry->set_entries_tail,
396 child); 398 child);
@@ -403,11 +405,13 @@ cleanup_delegation_set (struct DelegationSetQueueEntry *ds_entry)
403 GNUNET_free_non_null (ds_entry->issuer_attribute); 405 GNUNET_free_non_null (ds_entry->issuer_attribute);
404 GNUNET_free_non_null (ds_entry->unresolved_attribute_delegation); 406 GNUNET_free_non_null (ds_entry->unresolved_attribute_delegation);
405 GNUNET_free_non_null (ds_entry->attr_trailer); 407 GNUNET_free_non_null (ds_entry->attr_trailer);
406 if (NULL != ds_entry->lookup_request) { 408 if (NULL != ds_entry->lookup_request)
409 {
407 GNUNET_GNS_lookup_cancel (ds_entry->lookup_request); 410 GNUNET_GNS_lookup_cancel (ds_entry->lookup_request);
408 ds_entry->lookup_request = NULL; 411 ds_entry->lookup_request = NULL;
409 } 412 }
410 if (NULL != ds_entry->delegation_chain_entry) { 413 if (NULL != ds_entry->delegation_chain_entry)
414 {
411 GNUNET_free_non_null (ds_entry->delegation_chain_entry->subject_attribute); 415 GNUNET_free_non_null (ds_entry->delegation_chain_entry->subject_attribute);
412 GNUNET_free_non_null (ds_entry->delegation_chain_entry->issuer_attribute); 416 GNUNET_free_non_null (ds_entry->delegation_chain_entry->issuer_attribute);
413 GNUNET_free (ds_entry->delegation_chain_entry); 417 GNUNET_free (ds_entry->delegation_chain_entry);
@@ -420,14 +424,16 @@ cleanup_handle (struct VerifyRequestHandle *vrh)
420{ 424{
421 struct DelegateRecordEntry *del_entry; 425 struct DelegateRecordEntry *del_entry;
422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up...\n"); 426 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up...\n");
423 if (NULL != vrh->lookup_request) { 427 if (NULL != vrh->lookup_request)
428 {
424 GNUNET_GNS_lookup_cancel (vrh->lookup_request); 429 GNUNET_GNS_lookup_cancel (vrh->lookup_request);
425 vrh->lookup_request = NULL; 430 vrh->lookup_request = NULL;
426 } 431 }
427 cleanup_delegation_set (vrh->root_set); 432 cleanup_delegation_set (vrh->root_set);
428 GNUNET_free_non_null (vrh->issuer_attribute); 433 GNUNET_free_non_null (vrh->issuer_attribute);
429 for (del_entry = vrh->del_chain_head; NULL != vrh->del_chain_head; 434 for (del_entry = vrh->del_chain_head; NULL != vrh->del_chain_head;
430 del_entry = vrh->del_chain_head) { 435 del_entry = vrh->del_chain_head)
436 {
431 GNUNET_CONTAINER_DLL_remove (vrh->del_chain_head, 437 GNUNET_CONTAINER_DLL_remove (vrh->del_chain_head,
432 vrh->del_chain_tail, 438 vrh->del_chain_tail,
433 del_entry); 439 del_entry);
@@ -444,21 +450,25 @@ shutdown_task (void *cls)
444 450
445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down!\n"); 451 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down!\n");
446 452
447 while (NULL != (vrh = vrh_head)) { 453 while (NULL != (vrh = vrh_head))
454 {
448 // CREDENTIAL_resolver_lookup_cancel (clh->lookup); 455 // CREDENTIAL_resolver_lookup_cancel (clh->lookup);
449 GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh); 456 GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
450 cleanup_handle (vrh); 457 cleanup_handle (vrh);
451 } 458 }
452 459
453 if (NULL != gns) { 460 if (NULL != gns)
461 {
454 GNUNET_GNS_disconnect (gns); 462 GNUNET_GNS_disconnect (gns);
455 gns = NULL; 463 gns = NULL;
456 } 464 }
457 if (NULL != namestore) { 465 if (NULL != namestore)
466 {
458 GNUNET_NAMESTORE_disconnect (namestore); 467 GNUNET_NAMESTORE_disconnect (namestore);
459 namestore = NULL; 468 namestore = NULL;
460 } 469 }
461 if (NULL != statistics) { 470 if (NULL != statistics)
471 {
462 GNUNET_STATISTICS_destroy (statistics, GNUNET_NO); 472 GNUNET_STATISTICS_destroy (statistics, GNUNET_NO);
463 statistics = NULL; 473 statistics = NULL;
464 } 474 }
@@ -480,14 +490,16 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
480 490
481 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n"); 491 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n");
482 dce = vrh->delegation_chain_head; 492 dce = vrh->delegation_chain_head;
483 for (uint32_t i = 0; i < vrh->delegation_chain_size; i++) { 493 for (uint32_t i = 0; i < vrh->delegation_chain_size; i++)
494 {
484 dd[i].issuer_key = dce->issuer_key; 495 dd[i].issuer_key = dce->issuer_key;
485 dd[i].subject_key = dce->subject_key; 496 dd[i].subject_key = dce->subject_key;
486 dd[i].issuer_attribute = dce->issuer_attribute; 497 dd[i].issuer_attribute = dce->issuer_attribute;
487 dd[i].issuer_attribute_len = strlen (dce->issuer_attribute) + 1; 498 dd[i].issuer_attribute_len = strlen (dce->issuer_attribute) + 1;
488 dd[i].subject_attribute_len = 0; 499 dd[i].subject_attribute_len = 0;
489 dd[i].subject_attribute = NULL; 500 dd[i].subject_attribute = NULL;
490 if (NULL != dce->subject_attribute) { 501 if (NULL != dce->subject_attribute)
502 {
491 dd[i].subject_attribute = dce->subject_attribute; 503 dd[i].subject_attribute = dce->subject_attribute;
492 dd[i].subject_attribute_len = strlen (dce->subject_attribute) + 1; 504 dd[i].subject_attribute_len = strlen (dce->subject_attribute) + 1;
493 } 505 }
@@ -495,16 +507,16 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
495 } 507 }
496 508
497 // Remove all not needed credentials 509 // Remove all not needed credentials
498 for (del = vrh->del_chain_head; NULL != del;) { 510 for (del = vrh->del_chain_head; NULL != del;)
499 if (del->refcount > 0) { 511 {
512 if (del->refcount > 0)
513 {
500 del = del->next; 514 del = del->next;
501 continue; 515 continue;
502 } 516 }
503 tmp = del; 517 tmp = del;
504 del = del->next; 518 del = del->next;
505 GNUNET_CONTAINER_DLL_remove (vrh->del_chain_head, 519 GNUNET_CONTAINER_DLL_remove (vrh->del_chain_head, vrh->del_chain_tail, tmp);
506 vrh->del_chain_tail,
507 tmp);
508 GNUNET_free (tmp->delegate); 520 GNUNET_free (tmp->delegate);
509 GNUNET_free (tmp); 521 GNUNET_free (tmp);
510 vrh->del_chain_size--; 522 vrh->del_chain_size--;
@@ -513,20 +525,21 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
513 // Get serialized record data 525 // Get serialized record data
514 // Append at the end of rmsg 526 // Append at the end of rmsg
515 del = vrh->del_chain_head; 527 del = vrh->del_chain_head;
516 for (uint32_t i = 0; i < vrh->del_chain_size; i++) { 528 for (uint32_t i = 0; i < vrh->del_chain_size; i++)
529 {
517 dele[i].issuer_key = del->delegate->issuer_key; 530 dele[i].issuer_key = del->delegate->issuer_key;
518 dele[i].subject_key = del->delegate->subject_key; 531 dele[i].subject_key = del->delegate->subject_key;
519 dele[i].issuer_attribute_len 532 dele[i].issuer_attribute_len = strlen (del->delegate->issuer_attribute) + 1;
520 = strlen (del->delegate->issuer_attribute) + 1;
521 dele[i].issuer_attribute = del->delegate->issuer_attribute; 533 dele[i].issuer_attribute = del->delegate->issuer_attribute;
522 dele[i].expiration = del->delegate->expiration; 534 dele[i].expiration = del->delegate->expiration;
523 dele[i].signature = del->delegate->signature; 535 dele[i].signature = del->delegate->signature;
524 del = del->next; 536 del = del->next;
525 } 537 }
526 size = GNUNET_CREDENTIAL_delegation_chain_get_size (vrh->delegation_chain_size, 538 size =
527 dd, 539 GNUNET_CREDENTIAL_delegation_chain_get_size (vrh->delegation_chain_size,
528 vrh->del_chain_size, 540 dd,
529 dele); 541 vrh->del_chain_size,
542 dele);
530 env = GNUNET_MQ_msg_extra (rmsg, 543 env = GNUNET_MQ_msg_extra (rmsg,
531 size, 544 size,
532 GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT); 545 GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT);
@@ -541,13 +554,13 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
541 rmsg->del_found = htonl (GNUNET_NO); 554 rmsg->del_found = htonl (GNUNET_NO);
542 555
543 GNUNET_assert ( 556 GNUNET_assert (
544 -1 557 -1 !=
545 != GNUNET_CREDENTIAL_delegation_chain_serialize (vrh->delegation_chain_size, 558 GNUNET_CREDENTIAL_delegation_chain_serialize (vrh->delegation_chain_size,
546 dd, 559 dd,
547 vrh->del_chain_size, 560 vrh->del_chain_size,
548 dele, 561 dele,
549 size, 562 size,
550 (char *)&rmsg[1])); 563 (char *) &rmsg[1]));
551 564
552 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (vrh->client), env); 565 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (vrh->client), env);
553 GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh); 566 GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
@@ -559,8 +572,11 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
559 GNUNET_NO); 572 GNUNET_NO);
560} 573}
561 574
562static char* 575static char *
563partial_match(char *tmp_trail, char *tmp_subattr, char *parent_trail, char *issuer_attribute) 576partial_match (char *tmp_trail,
577 char *tmp_subattr,
578 char *parent_trail,
579 char *issuer_attribute)
564{ 580{
565 char *saveptr1, *saveptr2; 581 char *saveptr1, *saveptr2;
566 char *trail_token; 582 char *trail_token;
@@ -574,14 +590,16 @@ partial_match(char *tmp_trail, char *tmp_subattr, char *parent_trail, char *issu
574 sub_token = strtok_r (tmp_subattr, ".", &saveptr2); 590 sub_token = strtok_r (tmp_subattr, ".", &saveptr2);
575 while (NULL != trail_token && NULL != sub_token) 591 while (NULL != trail_token && NULL != sub_token)
576 { 592 {
577 if(0 == strcmp(trail_token,sub_token)) 593 if (0 == strcmp (trail_token, sub_token))
578 { 594 {
579 // good, matches, remove 595 // good, matches, remove
580 } else { 596 }
597 else
598 {
581 // not relevant for solving the chain, end for iteration here 599 // not relevant for solving the chain, end for iteration here
582 return NULL; 600 return NULL;
583 } 601 }
584 602
585 trail_token = strtok_r (NULL, ".", &saveptr1); 603 trail_token = strtok_r (NULL, ".", &saveptr1);
586 sub_token = strtok_r (NULL, ".", &saveptr2); 604 sub_token = strtok_r (NULL, ".", &saveptr2);
587 } 605 }
@@ -590,47 +608,38 @@ partial_match(char *tmp_trail, char *tmp_subattr, char *parent_trail, char *issu
590 // 2. the trailer is NULL, but the subject has more attributes 608 // 2. the trailer is NULL, but the subject has more attributes
591 // Reason: This will lead to "startzone.attribute" but we're looking for a solution 609 // Reason: This will lead to "startzone.attribute" but we're looking for a solution
592 // for "<- startzone" 610 // for "<- startzone"
593 if(NULL == trail_token) 611 if (NULL == trail_token)
594 { 612 {
595 return NULL; 613 return NULL;
596 } 614 }
597 615
598 // do not have to check sub_token == NULL, if both would be NULL 616 // do not have to check sub_token == NULL, if both would be NULL
599 // at the same time, the complete match part above should have triggered already 617 // at the same time, the complete match part above should have triggered already
600 618
601 // otherwise, above while only ends when sub_token == NULL 619 // otherwise, above while only ends when sub_token == NULL
602 GNUNET_asprintf (&attr_trailer, 620 GNUNET_asprintf (&attr_trailer, "%s", trail_token);
603 "%s", 621 trail_token = strtok_r (NULL, ".", &saveptr1);
604 trail_token); 622 while (NULL != trail_token)
605 trail_token = strtok_r (NULL, ".", &saveptr1);
606 while(NULL != trail_token)
607 { 623 {
608 GNUNET_asprintf (&attr_trailer, 624 GNUNET_asprintf (&attr_trailer, "%s.%s", parent_trail, trail_token);
609 "%s.%s", 625 trail_token = strtok_r (NULL, ".", &saveptr1);
610 parent_trail,
611 trail_token);
612 trail_token = strtok_r (NULL, ".", &saveptr1);
613
614 } 626 }
615 GNUNET_asprintf (&attr_trailer, 627 GNUNET_asprintf (&attr_trailer, "%s.%s", issuer_attribute, attr_trailer);
616 "%s.%s",
617 issuer_attribute,
618 attr_trailer);
619 return attr_trailer; 628 return attr_trailer;
620} 629}
621 630
622static void 631static void
623forward_resolution (void *cls, 632forward_resolution (void *cls,
624 uint32_t rd_count, 633 uint32_t rd_count,
625 const struct GNUNET_GNSRECORD_Data *rd) 634 const struct GNUNET_GNSRECORD_Data *rd)
626{ 635{
627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d entries.\n", rd_count); 636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d entries.\n", rd_count);
628 637
629 struct VerifyRequestHandle *vrh; 638 struct VerifyRequestHandle *vrh;
630 struct DelegationSetQueueEntry *current_set; 639 struct DelegationSetQueueEntry *current_set;
631 struct DelegationSetQueueEntry *ds_entry; 640 struct DelegationSetQueueEntry *ds_entry;
632 struct DelegationQueueEntry *dq_entry; 641 struct DelegationQueueEntry *dq_entry;
633 642
634 current_set = cls; 643 current_set = cls;
635 // set handle to NULL (as el = NULL) 644 // set handle to NULL (as el = NULL)
636 current_set->lookup_request = NULL; 645 current_set->lookup_request = NULL;
@@ -638,20 +647,21 @@ forward_resolution (void *cls,
638 vrh->pending_lookups--; 647 vrh->pending_lookups--;
639 648
640 // Loop record entries 649 // Loop record entries
641 for (uint32_t i = 0; i < rd_count; i++) { 650 for (uint32_t i = 0; i < rd_count; i++)
651 {
642 if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type) 652 if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type)
643 continue; 653 continue;
644 654
645 // Start deserialize into Delegate 655 // Start deserialize into Delegate
646 struct GNUNET_CREDENTIAL_Delegate *del; 656 struct GNUNET_CREDENTIAL_Delegate *del;
647 del = GNUNET_CREDENTIAL_delegate_deserialize(rd[i].data, rd[i].data_size); 657 del = GNUNET_CREDENTIAL_delegate_deserialize (rd[i].data, rd[i].data_size);
648 658
649 // Start: Create DQ Entry 659 // Start: Create DQ Entry
650 dq_entry = GNUNET_new (struct DelegationQueueEntry); 660 dq_entry = GNUNET_new (struct DelegationQueueEntry);
651 // AND delegations are not possible, only 1 solution 661 // AND delegations are not possible, only 1 solution
652 dq_entry->required_solutions = 1; 662 dq_entry->required_solutions = 1;
653 dq_entry->parent_set = current_set; 663 dq_entry->parent_set = current_set;
654 664
655 // Insert it into the current set 665 // Insert it into the current set
656 GNUNET_CONTAINER_DLL_insert (current_set->queue_entries_head, 666 GNUNET_CONTAINER_DLL_insert (current_set->queue_entries_head,
657 current_set->queue_entries_tail, 667 current_set->queue_entries_tail,
@@ -659,7 +669,7 @@ forward_resolution (void *cls,
659 669
660 // Start: Create DS Entry 670 // Start: Create DS Entry
661 ds_entry = GNUNET_new (struct DelegationSetQueueEntry); 671 ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
662 672
663 // (1) A.a <- A.b.c 673 // (1) A.a <- A.b.c
664 // (2) A.b <- D.d 674 // (2) A.b <- D.d
665 // (3) D.d <- E 675 // (3) D.d <- E
@@ -671,42 +681,55 @@ forward_resolution (void *cls,
671 // 3. new solution: replace, add trailer 681 // 3. new solution: replace, add trailer
672 682
673 // At resolution chain start trailer of parent is NULL 683 // At resolution chain start trailer of parent is NULL
674 if (NULL == current_set->attr_trailer) { 684 if (NULL == current_set->attr_trailer)
685 {
675 // for (5) F.c <- G, remember .c when going upwards 686 // for (5) F.c <- G, remember .c when going upwards
676 ds_entry->attr_trailer = GNUNET_strdup(del->issuer_attribute); 687 ds_entry->attr_trailer = GNUNET_strdup (del->issuer_attribute);
677 } else { 688 }
678 if (0 == del->subject_attribute_len){ 689 else
690 {
691 if (0 == del->subject_attribute_len)
692 {
679 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: New solution\n"); 693 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: New solution\n");
680 // new solution 694 // new solution
681 // create new trailer del->issuer_attribute, ds_entry->attr_trailer 695 // create new trailer del->issuer_attribute, ds_entry->attr_trailer
682 GNUNET_asprintf (&ds_entry->attr_trailer, 696 GNUNET_asprintf (&ds_entry->attr_trailer,
683 "%s.%s", 697 "%s.%s",
684 del->issuer_attribute, 698 del->issuer_attribute,
685 current_set->attr_trailer); 699 current_set->attr_trailer);
686 } else if(0 == strcmp(del->subject_attribute, current_set->attr_trailer)){ 700 }
701 else if (0 == strcmp (del->subject_attribute, current_set->attr_trailer))
702 {
687 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Complete match\n"); 703 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Complete match\n");
688 // complete match 704 // complete match
689 // new trailer == issuer attribute (e.g. (5) to (4)) 705 // new trailer == issuer attribute (e.g. (5) to (4))
690 // TODO memleak, free trailer before 706 // TODO memleak, free trailer before
691 ds_entry->attr_trailer = GNUNET_strdup(del->issuer_attribute); 707 ds_entry->attr_trailer = GNUNET_strdup (del->issuer_attribute);
692 } else { 708 }
709 else
710 {
693 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Partial match\n"); 711 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Partial match\n");
694 // partial match 712 // partial match
695 713
696 char *trail = partial_match(GNUNET_strdup (current_set->attr_trailer), 714 char *trail = partial_match (GNUNET_strdup (current_set->attr_trailer),
697 GNUNET_strdup (del->subject_attribute), 715 GNUNET_strdup (del->subject_attribute),
698 current_set->attr_trailer, 716 current_set->attr_trailer,
699 GNUNET_strdup (del->issuer_attribute)); 717 GNUNET_strdup (del->issuer_attribute));
700 718
701 // if null: skip this record entry (reasons: mismatch or overmatch, both not relevant) 719 // if null: skip this record entry (reasons: mismatch or overmatch, both not relevant)
702 if(NULL == trail) { 720 if (NULL == trail)
703 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entry not relevant, discarding: %s.%s <- %s.%s\n", 721 {
704 GNUNET_CRYPTO_ecdsa_public_key_to_string(&del->issuer_key), 722 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
705 del->issuer_attribute, 723 "Entry not relevant, discarding: %s.%s <- %s.%s\n",
706 GNUNET_CRYPTO_ecdsa_public_key_to_string(&del->subject_key), 724 GNUNET_CRYPTO_ecdsa_public_key_to_string (
707 del->subject_attribute); 725 &del->issuer_key),
726 del->issuer_attribute,
727 GNUNET_CRYPTO_ecdsa_public_key_to_string (
728 &del->subject_key),
729 del->subject_attribute);
708 continue; 730 continue;
709 } else 731 }
732 else
710 ds_entry->attr_trailer = trail; 733 ds_entry->attr_trailer = trail;
711 } 734 }
712 } 735 }
@@ -717,15 +740,17 @@ forward_resolution (void *cls,
717 // TODO: new ds_entry struct with subject_key (or one for both with contact_key or sth) 740 // TODO: new ds_entry struct with subject_key (or one for both with contact_key or sth)
718 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); 741 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
719 GNUNET_memcpy (ds_entry->issuer_key, 742 GNUNET_memcpy (ds_entry->issuer_key,
720 &del->subject_key, 743 &del->subject_key,
721 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 744 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
722 745
723 ds_entry->delegation_chain_entry = GNUNET_new (struct DelegationChainEntry); 746 ds_entry->delegation_chain_entry = GNUNET_new (struct DelegationChainEntry);
724 ds_entry->delegation_chain_entry->subject_key = del->subject_key; 747 ds_entry->delegation_chain_entry->subject_key = del->subject_key;
725 if (0 < del->subject_attribute_len) 748 if (0 < del->subject_attribute_len)
726 ds_entry->delegation_chain_entry->subject_attribute = GNUNET_strdup (del->subject_attribute); 749 ds_entry->delegation_chain_entry->subject_attribute =
750 GNUNET_strdup (del->subject_attribute);
727 ds_entry->delegation_chain_entry->issuer_key = del->issuer_key; 751 ds_entry->delegation_chain_entry->issuer_key = del->issuer_key;
728 ds_entry->delegation_chain_entry->issuer_attribute = GNUNET_strdup (del->issuer_attribute); 752 ds_entry->delegation_chain_entry->issuer_attribute =
753 GNUNET_strdup (del->issuer_attribute);
729 754
730 // current delegation as parent 755 // current delegation as parent
731 ds_entry->parent_queue_entry = dq_entry; 756 ds_entry->parent_queue_entry = dq_entry;
@@ -733,66 +758,74 @@ forward_resolution (void *cls,
733 // Check for solution 758 // Check for solution
734 // if: issuer key we looking for 759 // if: issuer key we looking for
735 if (0 == memcmp (&del->issuer_key, 760 if (0 == memcmp (&del->issuer_key,
736 &vrh->issuer_key, 761 &vrh->issuer_key,
737 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) 762 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
738 { 763 {
739 // if: issuer attr we looking for 764 // if: issuer attr we looking for
740 if (0 == strcmp (del->issuer_attribute, 765 if (0 == strcmp (del->issuer_attribute, vrh->issuer_attribute))
741 vrh->issuer_attribute)) 766 {
767 // if: complete match, meaning new trailer == issuer attr
768 if (0 == strcmp (vrh->issuer_attribute, ds_entry->attr_trailer))
742 { 769 {
743 // if: complete match, meaning new trailer == issuer attr 770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found: Solution\n");
744 if(0 == strcmp (vrh->issuer_attribute, ds_entry->attr_trailer)) 771
772 // Add found solution into delegation_chain
773 struct DelegationSetQueueEntry *tmp_set;
774 for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
775 tmp_set = tmp_set->parent_queue_entry->parent_set)
745 { 776 {
746 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found: Solution\n"); 777 if (NULL != tmp_set->delegation_chain_entry)
747 778 {
748 // Add found solution into delegation_chain 779 vrh->delegation_chain_size++;
749 struct DelegationSetQueueEntry *tmp_set; 780 GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head,
750 for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry; 781 vrh->delegation_chain_tail,
751 tmp_set = tmp_set->parent_queue_entry->parent_set) { 782 tmp_set->delegation_chain_entry);
752 if (NULL != tmp_set->delegation_chain_entry) {
753 vrh->delegation_chain_size++;
754 GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head,
755 vrh->delegation_chain_tail,
756 tmp_set->delegation_chain_entry);
757 }
758 } 783 }
784 }
759 785
760 // Increase refcount for this delegate 786 // Increase refcount for this delegate
761 for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head; del_entry != NULL; del_entry = del_entry->next) { 787 for (struct DelegateRecordEntry *del_entry = vrh->del_chain_head;
762 if (0 == memcmp (&del_entry->delegate->issuer_key, 788 del_entry != NULL;
763 &vrh->delegation_chain_head->subject_key, 789 del_entry = del_entry->next)
764 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) 790 {
791 if (0 == memcmp (&del_entry->delegate->issuer_key,
792 &vrh->delegation_chain_head->subject_key,
793 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
794 {
795 if (0 == strcmp (del_entry->delegate->issuer_attribute,
796 vrh->delegation_chain_head->subject_attribute))
765 { 797 {
766 if (0 == strcmp (del_entry->delegate->issuer_attribute, 798 del_entry->refcount++;
767 vrh->delegation_chain_head->subject_attribute))
768 {
769 del_entry->refcount++;
770 }
771 } 799 }
772 } 800 }
773
774 send_lookup_response (vrh);
775 return;
776 } 801 }
802
803 send_lookup_response (vrh);
804 return;
777 } 805 }
806 }
778 } 807 }
779 808
780 // Starting a new GNS lookup 809 // Starting a new GNS lookup
781 vrh->pending_lookups++; 810 vrh->pending_lookups++;
782 ds_entry->handle = vrh; 811 ds_entry->handle = vrh;
783 812
784 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Starting to look up trailer %s in zone %s\n", ds_entry->attr_trailer, GNUNET_CRYPTO_ecdsa_public_key_to_string(&del->issuer_key)); 813 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
785 814 "Starting to look up trailer %s in zone %s\n",
815 ds_entry->attr_trailer,
816 GNUNET_CRYPTO_ecdsa_public_key_to_string (&del->issuer_key));
817
786 GNUNET_GNS_lookup (gns, 818 GNUNET_GNS_lookup (gns,
787 GNUNET_GNS_EMPTY_LABEL_AT, 819 GNUNET_GNS_EMPTY_LABEL_AT,
788 &del->issuer_key, 820 &del->issuer_key,
789 GNUNET_GNSRECORD_TYPE_DELEGATE, 821 GNUNET_GNSRECORD_TYPE_DELEGATE,
790 GNUNET_GNS_LO_DEFAULT, 822 GNUNET_GNS_LO_DEFAULT,
791 &forward_resolution, 823 &forward_resolution,
792 ds_entry); 824 ds_entry);
793 } 825 }
794 826
795 if (0 == vrh->pending_lookups) { 827 if (0 == vrh->pending_lookups)
828 {
796 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n"); 829 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
797 send_lookup_response (vrh); 830 send_lookup_response (vrh);
798 return; 831 return;
@@ -820,23 +853,24 @@ backward_resolution (void *cls,
820 vrh->pending_lookups--; 853 vrh->pending_lookups--;
821 854
822 // Each OR 855 // Each OR
823 for (uint32_t i = 0; i < rd_count; i++) { 856 for (uint32_t i = 0; i < rd_count; i++)
857 {
824 if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type) 858 if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
825 continue; 859 continue;
826 860
827 sets = rd[i].data; 861 sets = rd[i].data;
828 struct GNUNET_CREDENTIAL_DelegationSet set[ntohl (sets->set_count)]; 862 struct GNUNET_CREDENTIAL_DelegationSet set[ntohl (sets->set_count)];
829 GNUNET_log ( 863 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
830 GNUNET_ERROR_TYPE_DEBUG, 864 "Found new attribute delegation with %d sets. Creating new Job...\n",
831 "Found new attribute delegation with %d sets. Creating new Job...\n", 865 ntohl (sets->set_count));
832 ntohl (sets->set_count)); 866
833 867 if (GNUNET_OK !=
834 if (GNUNET_OK 868 GNUNET_CREDENTIAL_delegation_set_deserialize (GNUNET_ntohll (
835 != GNUNET_CREDENTIAL_delegation_set_deserialize ( 869 sets->data_size),
836 GNUNET_ntohll (sets->data_size), 870 (const char *) &sets[1],
837 (const char *)&sets[1], 871 ntohl (sets->set_count),
838 ntohl (sets->set_count), 872 set))
839 set)) { 873 {
840 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n"); 874 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n");
841 continue; 875 continue;
842 } 876 }
@@ -848,13 +882,17 @@ backward_resolution (void *cls,
848 current_set->queue_entries_tail, 882 current_set->queue_entries_tail,
849 dq_entry); 883 dq_entry);
850 // Each AND 884 // Each AND
851 for (uint32_t j = 0; j < ntohl (sets->set_count); j++) { 885 for (uint32_t j = 0; j < ntohl (sets->set_count); j++)
886 {
852 ds_entry = GNUNET_new (struct DelegationSetQueueEntry); 887 ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
853 if (NULL != current_set->attr_trailer) { 888 if (NULL != current_set->attr_trailer)
854 if (0 == set[j].subject_attribute_len) { 889 {
890 if (0 == set[j].subject_attribute_len)
891 {
855 GNUNET_asprintf (&expanded_attr, "%s", current_set->attr_trailer); 892 GNUNET_asprintf (&expanded_attr, "%s", current_set->attr_trailer);
856 893 }
857 } else { 894 else
895 {
858 GNUNET_asprintf (&expanded_attr, 896 GNUNET_asprintf (&expanded_attr,
859 "%s.%s", 897 "%s.%s",
860 set[j].subject_attribute, 898 set[j].subject_attribute,
@@ -862,30 +900,33 @@ backward_resolution (void *cls,
862 } 900 }
863 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expanded to %s\n", expanded_attr); 901 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expanded to %s\n", expanded_attr);
864 ds_entry->unresolved_attribute_delegation = expanded_attr; 902 ds_entry->unresolved_attribute_delegation = expanded_attr;
865 } else { 903 }
866 if (0 != set[j].subject_attribute_len) { 904 else
905 {
906 if (0 != set[j].subject_attribute_len)
907 {
867 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 908 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
868 "Not Expanding %s\n", 909 "Not Expanding %s\n",
869 set[j].subject_attribute); 910 set[j].subject_attribute);
870 ds_entry->unresolved_attribute_delegation 911 ds_entry->unresolved_attribute_delegation =
871 = GNUNET_strdup (set[j].subject_attribute); 912 GNUNET_strdup (set[j].subject_attribute);
872 } 913 }
873 } 914 }
874 915
875 // Add a credential chain entry 916 // Add a credential chain entry
876 ds_entry->delegation_chain_entry 917 ds_entry->delegation_chain_entry =
877 = GNUNET_new (struct DelegationChainEntry); 918 GNUNET_new (struct DelegationChainEntry);
878 ds_entry->delegation_chain_entry->subject_key = set[j].subject_key; 919 ds_entry->delegation_chain_entry->subject_key = set[j].subject_key;
879 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); 920 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
880 GNUNET_memcpy (ds_entry->issuer_key, 921 GNUNET_memcpy (ds_entry->issuer_key,
881 &set[j].subject_key, 922 &set[j].subject_key,
882 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 923 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
883 if (0 < set[j].subject_attribute_len) 924 if (0 < set[j].subject_attribute_len)
884 ds_entry->delegation_chain_entry->subject_attribute 925 ds_entry->delegation_chain_entry->subject_attribute =
885 = GNUNET_strdup (set[j].subject_attribute); 926 GNUNET_strdup (set[j].subject_attribute);
886 ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key; 927 ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key;
887 ds_entry->delegation_chain_entry->issuer_attribute 928 ds_entry->delegation_chain_entry->issuer_attribute =
888 = GNUNET_strdup (current_set->lookup_attribute); 929 GNUNET_strdup (current_set->lookup_attribute);
889 930
890 ds_entry->parent_queue_entry = dq_entry; // current_delegation; 931 ds_entry->parent_queue_entry = dq_entry; // current_delegation;
891 932
@@ -898,30 +939,31 @@ backward_resolution (void *cls,
898 * Check if this delegation already matches one of our credentials 939 * Check if this delegation already matches one of our credentials
899 */ 940 */
900 for (del_pointer = vrh->del_chain_head; del_pointer != NULL; 941 for (del_pointer = vrh->del_chain_head; del_pointer != NULL;
901 del_pointer = del_pointer->next) { 942 del_pointer = del_pointer->next)
943 {
902 // If key and attribute match credential continue and backtrack 944 // If key and attribute match credential continue and backtrack
903 if (0 945 if (0 != memcmp (&set->subject_key,
904 != memcmp (&set->subject_key, 946 &del_pointer->delegate->issuer_key,
905 &del_pointer->delegate->issuer_key, 947 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
906 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
907 continue; 948 continue;
908 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 949 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
909 "Checking if %s matches %s\n", 950 "Checking if %s matches %s\n",
910 ds_entry->unresolved_attribute_delegation, 951 ds_entry->unresolved_attribute_delegation,
911 del_pointer->delegate->issuer_attribute); 952 del_pointer->delegate->issuer_attribute);
912 953
913 if (0 954 if (0 != strcmp (ds_entry->unresolved_attribute_delegation,
914 != strcmp (ds_entry->unresolved_attribute_delegation, 955 del_pointer->delegate->issuer_attribute))
915 del_pointer->delegate->issuer_attribute))
916 continue; 956 continue;
917 957
918 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n"); 958 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n");
919 del_pointer->refcount++; 959 del_pointer->refcount++;
920 // Backtrack 960 // Backtrack
921 for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry; 961 for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry;
922 tmp_set = tmp_set->parent_queue_entry->parent_set) { 962 tmp_set = tmp_set->parent_queue_entry->parent_set)
963 {
923 tmp_set->parent_queue_entry->required_solutions--; 964 tmp_set->parent_queue_entry->required_solutions--;
924 if (NULL != tmp_set->delegation_chain_entry) { 965 if (NULL != tmp_set->delegation_chain_entry)
966 {
925 vrh->delegation_chain_size++; 967 vrh->delegation_chain_size++;
926 GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head, 968 GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head,
927 vrh->delegation_chain_tail, 969 vrh->delegation_chain_tail,
@@ -931,63 +973,69 @@ backward_resolution (void *cls,
931 break; 973 break;
932 } 974 }
933 975
934 if (NULL == tmp_set->parent_queue_entry) { 976 if (NULL == tmp_set->parent_queue_entry)
935 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "All solutions found\n"); 977 {
978 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All solutions found\n");
936 // Found match 979 // Found match
937 send_lookup_response (vrh); 980 send_lookup_response (vrh);
938 return; 981 return;
939 } 982 }
940 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Not all solutions found yet.\n"); 983 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not all solutions found yet.\n");
941 continue; 984 continue;
942 } 985 }
943 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 986 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
944 "Building new lookup request from %s\n", 987 "Building new lookup request from %s\n",
945 ds_entry->unresolved_attribute_delegation); 988 ds_entry->unresolved_attribute_delegation);
946 // Continue with backward resolution 989 // Continue with backward resolution
947 char 990 char issuer_attribute_name[strlen (
948 issuer_attribute_name[strlen (ds_entry->unresolved_attribute_delegation) 991 ds_entry->unresolved_attribute_delegation) +
949 + 1]; 992 1];
950 strcpy (issuer_attribute_name, ds_entry->unresolved_attribute_delegation); 993 strcpy (issuer_attribute_name, ds_entry->unresolved_attribute_delegation);
951 char *next_attr = strtok (issuer_attribute_name, "."); 994 char *next_attr = strtok (issuer_attribute_name, ".");
952 if (NULL == next_attr) { 995 if (NULL == next_attr)
996 {
953 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 997 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
954 "Failed to parse next attribute\n"); 998 "Failed to parse next attribute\n");
955 continue; 999 continue;
956 } 1000 }
957 GNUNET_asprintf (&lookup_attribute, "%s", next_attr); 1001 GNUNET_asprintf (&lookup_attribute, "%s", next_attr);
958 GNUNET_asprintf (&ds_entry->lookup_attribute, "%s", next_attr); 1002 GNUNET_asprintf (&ds_entry->lookup_attribute, "%s", next_attr);
959 if (strlen (next_attr) 1003 if (strlen (next_attr) ==
960 == strlen (ds_entry->unresolved_attribute_delegation)) { 1004 strlen (ds_entry->unresolved_attribute_delegation))
1005 {
961 ds_entry->attr_trailer = NULL; 1006 ds_entry->attr_trailer = NULL;
962 } else { 1007 }
1008 else
1009 {
963 next_attr += strlen (next_attr) + 1; 1010 next_attr += strlen (next_attr) + 1;
964 ds_entry->attr_trailer = GNUNET_strdup (next_attr); 1011 ds_entry->attr_trailer = GNUNET_strdup (next_attr);
965 } 1012 }
966 1013
967 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
968 "Looking up %s\n", 1015 "Looking up %s\n",
969 ds_entry->lookup_attribute); 1016 ds_entry->lookup_attribute);
970 if (NULL != ds_entry->attr_trailer) 1017 if (NULL != ds_entry->attr_trailer)
971 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1018 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
972 "%s still to go...\n", 1019 "%s still to go...\n",
973 ds_entry->attr_trailer); 1020 ds_entry->attr_trailer);
974 1021
975 vrh->pending_lookups++; 1022 vrh->pending_lookups++;
976 ds_entry->handle = vrh; 1023 ds_entry->handle = vrh;
977 ds_entry->lookup_request 1024 ds_entry->lookup_request =
978 = GNUNET_GNS_lookup (gns, 1025 GNUNET_GNS_lookup (gns,
979 lookup_attribute, 1026 lookup_attribute,
980 ds_entry->issuer_key, // issuer_key, 1027 ds_entry->issuer_key, // issuer_key,
981 GNUNET_GNSRECORD_TYPE_ATTRIBUTE, 1028 GNUNET_GNSRECORD_TYPE_ATTRIBUTE,
982 GNUNET_GNS_LO_DEFAULT, 1029 GNUNET_GNS_LO_DEFAULT,
983 &backward_resolution, 1030 &backward_resolution,
984 ds_entry); 1031 ds_entry);
985 1032
986 GNUNET_free (lookup_attribute); 1033 GNUNET_free (lookup_attribute);
987 } 1034 }
988 } 1035 }
989 1036
990 if (0 == vrh->pending_lookups) { 1037 if (0 == vrh->pending_lookups)
1038 {
991 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n"); 1039 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "We are all out of attributes...\n");
992 send_lookup_response (vrh); 1040 send_lookup_response (vrh);
993 return; 1041 return;
@@ -1008,20 +1056,22 @@ delegation_chain_bw_resolution_start (void *cls)
1008 struct DelegateRecordEntry *del_entry; 1056 struct DelegateRecordEntry *del_entry;
1009 vrh->lookup_request = NULL; 1057 vrh->lookup_request = NULL;
1010 1058
1011 if (0 == vrh->del_chain_size) { 1059 if (0 == vrh->del_chain_size)
1060 {
1012 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegates found\n"); 1061 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegates found\n");
1013 send_lookup_response (vrh); 1062 send_lookup_response (vrh);
1014 return; 1063 return;
1015 } 1064 }
1016 1065
1017 for (del_entry = vrh->del_chain_head; del_entry != NULL; 1066 for (del_entry = vrh->del_chain_head; del_entry != NULL;
1018 del_entry = del_entry->next) { 1067 del_entry = del_entry->next)
1068 {
1019 if (0 != memcmp (&del_entry->delegate->issuer_key, 1069 if (0 != memcmp (&del_entry->delegate->issuer_key,
1020 &vrh->issuer_key, 1070 &vrh->issuer_key,
1021 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) 1071 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1022 continue; 1072 continue;
1023 if (0 != strcmp (del_entry->delegate->issuer_attribute, 1073 if (0 !=
1024 vrh->issuer_attribute)) 1074 strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute))
1025 continue; 1075 continue;
1026 del_entry->refcount++; 1076 del_entry->refcount++;
1027 // Found match prematurely 1077 // Found match prematurely
@@ -1029,7 +1079,7 @@ delegation_chain_bw_resolution_start (void *cls)
1029 return; 1079 return;
1030 } 1080 }
1031 1081
1032 1082
1033 //Check for attributes from the issuer and follow the chain 1083 //Check for attributes from the issuer and follow the chain
1034 //till you get the required subject's attributes 1084 //till you get the required subject's attributes
1035 char issuer_attribute_name[strlen (vrh->issuer_attribute) + 1]; 1085 char issuer_attribute_name[strlen (vrh->issuer_attribute) + 1];
@@ -1084,20 +1134,23 @@ delegation_chain_fw_resolution_start (void *cls)
1084 // X.x <- C 1134 // X.x <- C
1085 // Y.y <- C 1135 // Y.y <- C
1086 // wenn X.x oder Y.y nicht == A.a dann starte von A 1136 // wenn X.x oder Y.y nicht == A.a dann starte von A
1087 if (0 == vrh->del_chain_size) { 1137 if (0 == vrh->del_chain_size)
1138 {
1088 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegations found\n"); 1139 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No delegations found\n");
1089 send_lookup_response (vrh); 1140 send_lookup_response (vrh);
1090 return; 1141 return;
1091 } 1142 }
1092 1143
1093 // Check if one of the delegations of the subject already match 1144 // Check if one of the delegations of the subject already match
1094 for (del_entry = vrh->del_chain_head; del_entry != NULL; del_entry = del_entry->next) { 1145 for (del_entry = vrh->del_chain_head; del_entry != NULL;
1146 del_entry = del_entry->next)
1147 {
1095 if (0 != memcmp (&del_entry->delegate->issuer_key, 1148 if (0 != memcmp (&del_entry->delegate->issuer_key,
1096 &vrh->issuer_key, 1149 &vrh->issuer_key,
1097 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) 1150 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1098 continue; 1151 continue;
1099 if (0 != strcmp (del_entry->delegate->issuer_attribute, 1152 if (0 !=
1100 vrh->issuer_attribute)) 1153 strcmp (del_entry->delegate->issuer_attribute, vrh->issuer_attribute))
1101 continue; 1154 continue;
1102 del_entry->refcount++; 1155 del_entry->refcount++;
1103 // Found match prematurely 1156 // Found match prematurely
@@ -1110,33 +1163,39 @@ delegation_chain_fw_resolution_start (void *cls)
1110 1163
1111 // ds_entry created belongs to the first lookup, vrh still has the 1164 // ds_entry created belongs to the first lookup, vrh still has the
1112 // issuer+attr we look for 1165 // issuer+attr we look for
1113 for (del_entry = vrh->del_chain_head; del_entry != NULL; del_entry = del_entry->next) { 1166 for (del_entry = vrh->del_chain_head; del_entry != NULL;
1167 del_entry = del_entry->next)
1168 {
1114 1169
1115 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1170 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1116 "Looking for %s.%s\n", 1171 "Looking for %s.%s\n",
1117 GNUNET_CRYPTO_ecdsa_public_key_to_string(&del_entry->delegate->issuer_key), del_entry->delegate->issuer_attribute); 1172 GNUNET_CRYPTO_ecdsa_public_key_to_string (
1118 1173 &del_entry->delegate->issuer_key),
1174 del_entry->delegate->issuer_attribute);
1175
1119 ds_entry = GNUNET_new (struct DelegationSetQueueEntry); 1176 ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
1120 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); 1177 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
1121 // TODO: new ds_entry struct with subject_key (or one for both with contact_key or sth) 1178 // TODO: new ds_entry struct with subject_key (or one for both with contact_key or sth)
1122 GNUNET_memcpy (ds_entry->issuer_key, 1179 GNUNET_memcpy (ds_entry->issuer_key,
1123 &del_entry->delegate->subject_key, 1180 &del_entry->delegate->subject_key,
1124 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 1181 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1125 ds_entry->attr_trailer = GNUNET_strdup(del_entry->delegate->issuer_attribute); 1182 ds_entry->attr_trailer =
1183 GNUNET_strdup (del_entry->delegate->issuer_attribute);
1126 ds_entry->handle = vrh; 1184 ds_entry->handle = vrh;
1127 1185
1128 vrh->root_set = ds_entry; 1186 vrh->root_set = ds_entry;
1129 vrh->pending_lookups ++; 1187 vrh->pending_lookups++;
1130 // Start with forward resolution 1188 // Start with forward resolution
1131 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start Forward Resolution\n"); 1189 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start Forward Resolution\n");
1132 1190
1133 ds_entry->lookup_request = GNUNET_GNS_lookup (gns, 1191 ds_entry->lookup_request =
1134 GNUNET_GNS_EMPTY_LABEL_AT, 1192 GNUNET_GNS_lookup (gns,
1135 &del_entry->delegate->issuer_key, // issuer_key, 1193 GNUNET_GNS_EMPTY_LABEL_AT,
1136 GNUNET_GNSRECORD_TYPE_DELEGATE, 1194 &del_entry->delegate->issuer_key, // issuer_key,
1137 GNUNET_GNS_LO_DEFAULT, 1195 GNUNET_GNSRECORD_TYPE_DELEGATE,
1138 &forward_resolution, 1196 GNUNET_GNS_LO_DEFAULT,
1139 ds_entry); 1197 &forward_resolution,
1198 ds_entry);
1140 } 1199 }
1141} 1200}
1142 1201
@@ -1147,17 +1206,20 @@ check_verify (void *cls, const struct VerifyMessage *v_msg)
1147 const char *attr; 1206 const char *attr;
1148 1207
1149 msg_size = ntohs (v_msg->header.size); 1208 msg_size = ntohs (v_msg->header.size);
1150 if (msg_size < sizeof (struct VerifyMessage)) { 1209 if (msg_size < sizeof (struct VerifyMessage))
1210 {
1151 GNUNET_break (0); 1211 GNUNET_break (0);
1152 return GNUNET_SYSERR; 1212 return GNUNET_SYSERR;
1153 } 1213 }
1154 if (ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) { 1214 if (ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH)
1215 {
1155 GNUNET_break (0); 1216 GNUNET_break (0);
1156 return GNUNET_SYSERR; 1217 return GNUNET_SYSERR;
1157 } 1218 }
1158 attr = (const char *)&v_msg[1]; 1219 attr = (const char *) &v_msg[1];
1159 1220
1160 if (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH) { 1221 if (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH)
1222 {
1161 GNUNET_break (0); 1223 GNUNET_break (0);
1162 return GNUNET_SYSERR; 1224 return GNUNET_SYSERR;
1163 } 1225 }
@@ -1179,7 +1241,7 @@ handle_verify (void *cls, const struct VerifyMessage *v_msg)
1179 const char *utf_in; 1241 const char *utf_in;
1180 1242
1181 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n"); 1243 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n");
1182 utf_in = (const char *)&v_msg[1]; 1244 utf_in = (const char *) &v_msg[1];
1183 GNUNET_STRINGS_utf8_tolower (utf_in, attrptr); 1245 GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1184 GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len)); 1246 GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len));
1185 issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0'; 1247 issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0';
@@ -1190,50 +1252,52 @@ handle_verify (void *cls, const struct VerifyMessage *v_msg)
1190 vrh->issuer_key = v_msg->issuer_key; 1252 vrh->issuer_key = v_msg->issuer_key;
1191 vrh->subject_key = v_msg->subject_key; 1253 vrh->subject_key = v_msg->subject_key;
1192 vrh->issuer_attribute = GNUNET_strdup (issuer_attribute); 1254 vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1193 vrh->resolution_algo = ntohs(v_msg->resolution_algo); 1255 vrh->resolution_algo = ntohs (v_msg->resolution_algo);
1194 1256
1195 GNUNET_SERVICE_client_continue (vrh->client); 1257 GNUNET_SERVICE_client_continue (vrh->client);
1196 if (0 == strlen (issuer_attribute)) { 1258 if (0 == strlen (issuer_attribute))
1259 {
1197 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n"); 1260 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1198 send_lookup_response (vrh); 1261 send_lookup_response (vrh);
1199 return; 1262 return;
1200 } 1263 }
1201 1264
1202 // Parse delegates from verifaction message 1265 // Parse delegates from verifaction message
1203 delegate_count = ntohl (v_msg->d_count); 1266 delegate_count = ntohl (v_msg->d_count);
1204 delegate_data_size = ntohs (v_msg->header.size) 1267 delegate_data_size = ntohs (v_msg->header.size) -
1205 - sizeof (struct VerifyMessage) 1268 sizeof (struct VerifyMessage) -
1206 - ntohs (v_msg->issuer_attribute_len) - 1; 1269 ntohs (v_msg->issuer_attribute_len) - 1;
1207 struct GNUNET_CREDENTIAL_Delegate delegates[delegate_count]; 1270 struct GNUNET_CREDENTIAL_Delegate delegates[delegate_count];
1208 memset (delegates, 1271 memset (delegates,
1209 0, 1272 0,
1210 sizeof (struct GNUNET_CREDENTIAL_Delegate) * delegate_count); 1273 sizeof (struct GNUNET_CREDENTIAL_Delegate) * delegate_count);
1211 delegate_data = (char *)&v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1; 1274 delegate_data = (char *) &v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1;
1212 if (GNUNET_OK 1275 if (GNUNET_OK != GNUNET_CREDENTIAL_delegates_deserialize (delegate_data_size,
1213 != GNUNET_CREDENTIAL_delegates_deserialize (delegate_data_size, 1276 delegate_data,
1214 delegate_data, 1277 delegate_count,
1215 delegate_count, 1278 delegates))
1216 delegates)) { 1279 {
1217 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot deserialize delegates!\n"); 1280 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot deserialize delegates!\n");
1218 send_lookup_response (vrh); 1281 send_lookup_response (vrh);
1219 return; 1282 return;
1220 } 1283 }
1221 1284
1222 // Prepare vrh delegation chain for later validation 1285 // Prepare vrh delegation chain for later validation
1223 for (uint32_t i = 0; i < delegate_count; i++) { 1286 for (uint32_t i = 0; i < delegate_count; i++)
1287 {
1224 del_entry = GNUNET_new (struct DelegateRecordEntry); 1288 del_entry = GNUNET_new (struct DelegateRecordEntry);
1225 del_entry->delegate 1289 del_entry->delegate =
1226 = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) 1290 GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Delegate) +
1227 + delegates[i].issuer_attribute_len + 1); 1291 delegates[i].issuer_attribute_len + 1);
1228 GNUNET_memcpy (del_entry->delegate, 1292 GNUNET_memcpy (del_entry->delegate,
1229 &delegates[i], 1293 &delegates[i],
1230 sizeof (struct GNUNET_CREDENTIAL_Delegate)); 1294 sizeof (struct GNUNET_CREDENTIAL_Delegate));
1231 GNUNET_memcpy (&del_entry->delegate[1], 1295 GNUNET_memcpy (&del_entry->delegate[1],
1232 delegates[i].issuer_attribute, 1296 delegates[i].issuer_attribute,
1233 delegates[i].issuer_attribute_len); 1297 delegates[i].issuer_attribute_len);
1234 del_entry->delegate->issuer_attribute_len 1298 del_entry->delegate->issuer_attribute_len =
1235 = delegates[i].issuer_attribute_len; 1299 delegates[i].issuer_attribute_len;
1236 del_entry->delegate->issuer_attribute = (char *)&del_entry->delegate[1]; 1300 del_entry->delegate->issuer_attribute = (char *) &del_entry->delegate[1];
1237 GNUNET_CONTAINER_DLL_insert_tail (vrh->del_chain_head, 1301 GNUNET_CONTAINER_DLL_insert_tail (vrh->del_chain_head,
1238 vrh->del_chain_tail, 1302 vrh->del_chain_tail,
1239 del_entry); 1303 del_entry);
@@ -1241,11 +1305,16 @@ handle_verify (void *cls, const struct VerifyMessage *v_msg)
1241 } 1305 }
1242 1306
1243 // Switch resolution algo 1307 // Switch resolution algo
1244 if(Backward == vrh->resolution_algo){ 1308 if (GNUNET_CREDENTIAL_FLAG_BACKWARD & vrh->resolution_algo)
1309 {
1245 delegation_chain_bw_resolution_start (vrh); 1310 delegation_chain_bw_resolution_start (vrh);
1246 } else if (Forward == vrh->resolution_algo){ 1311 }
1312 else if (GNUNET_CREDENTIAL_FLAG_FORWARD & vrh->resolution_algo)
1313 {
1247 delegation_chain_fw_resolution_start (vrh); 1314 delegation_chain_fw_resolution_start (vrh);
1248 } else{ 1315 }
1316 else
1317 {
1249 //TODO 1318 //TODO
1250 } 1319 }
1251} 1320}
@@ -1266,21 +1335,26 @@ delegate_collection_finished (void *cls)
1266 struct VerifyRequestHandle *vrh = cls; 1335 struct VerifyRequestHandle *vrh = cls;
1267 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done collecting delegates.\n"); 1336 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done collecting delegates.\n");
1268 1337
1269 if(Backward == vrh->resolution_algo){ 1338 if (GNUNET_CREDENTIAL_FLAG_BACKWARD & vrh->resolution_algo)
1339 {
1270 delegation_chain_bw_resolution_start (vrh); 1340 delegation_chain_bw_resolution_start (vrh);
1271 } else if (Forward == vrh->resolution_algo){ 1341 }
1342 else if (GNUNET_CREDENTIAL_FLAG_FORWARD & vrh->resolution_algo)
1343 {
1272 delegation_chain_fw_resolution_start (vrh); 1344 delegation_chain_fw_resolution_start (vrh);
1273 } else{ 1345 }
1346 else
1347 {
1274 //TODO 1348 //TODO
1275 } 1349 }
1276} 1350}
1277 1351
1278static void 1352static void
1279handle_delegate_collection_cb (void *cls, 1353handle_delegate_collection_cb (void *cls,
1280 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, 1354 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
1281 const char *label, 1355 const char *label,
1282 unsigned int rd_count, 1356 unsigned int rd_count,
1283 const struct GNUNET_GNSRECORD_Data *rd) 1357 const struct GNUNET_GNSRECORD_Data *rd)
1284{ 1358{
1285 struct VerifyRequestHandle *vrh = cls; 1359 struct VerifyRequestHandle *vrh = cls;
1286 struct GNUNET_CREDENTIAL_Delegate *del; 1360 struct GNUNET_CREDENTIAL_Delegate *del;
@@ -1289,25 +1363,31 @@ handle_delegate_collection_cb (void *cls,
1289 cred_record_count = 0; 1363 cred_record_count = 0;
1290 vrh->dele_qe = NULL; 1364 vrh->dele_qe = NULL;
1291 1365
1292 //TODO not all, only private and with sub_attr_len == 0 1366 for (uint32_t i = 0; i < rd_count; i++)
1293 for (uint32_t i = 0; i < rd_count; i++) { 1367 {
1294 if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type) 1368 if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type)
1295 continue; 1369 continue;
1296 cred_record_count++; 1370 cred_record_count++;
1297 del = GNUNET_CREDENTIAL_delegate_deserialize (rd[i].data, rd[i].data_size); 1371 del = GNUNET_CREDENTIAL_delegate_deserialize (rd[i].data, rd[i].data_size);
1298 if (NULL == del) { 1372 if (NULL == del)
1299 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid credential found\n"); 1373 {
1374 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid delegate found\n");
1300 continue; 1375 continue;
1301 } 1376 }
1302 del_entry = GNUNET_new (struct DelegateRecordEntry); 1377 // only add the entries that are explicity marked as private
1303 del_entry->delegate = del; 1378 // and therefor symbolize the end of a chain
1304 GNUNET_CONTAINER_DLL_insert_tail (vrh->del_chain_head, 1379 if (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)
1305 vrh->del_chain_tail, 1380 {
1306 del_entry); 1381 del_entry = GNUNET_new (struct DelegateRecordEntry);
1307 vrh->del_chain_size++; 1382 del_entry->delegate = del;
1383 GNUNET_CONTAINER_DLL_insert_tail (vrh->del_chain_head,
1384 vrh->del_chain_tail,
1385 del_entry);
1386 vrh->del_chain_size++;
1387 }
1308 } 1388 }
1309 1389
1310 delegate_collection_finished(vrh); 1390 delegate_collection_finished (vrh);
1311} 1391}
1312 1392
1313static void 1393static void
@@ -1322,7 +1402,7 @@ handle_collect (void *cls, const struct CollectMessage *c_msg)
1322 1402
1323 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received COLLECT message\n"); 1403 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received COLLECT message\n");
1324 1404
1325 utf_in = (const char *)&c_msg[1]; 1405 utf_in = (const char *) &c_msg[1];
1326 GNUNET_STRINGS_utf8_tolower (utf_in, attrptr); 1406 GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
1327 1407
1328 GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len)); 1408 GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len));
@@ -1334,23 +1414,25 @@ handle_collect (void *cls, const struct CollectMessage *c_msg)
1334 vrh->issuer_key = c_msg->issuer_key; 1414 vrh->issuer_key = c_msg->issuer_key;
1335 GNUNET_CRYPTO_ecdsa_key_get_public (&c_msg->subject_key, &vrh->subject_key); 1415 GNUNET_CRYPTO_ecdsa_key_get_public (&c_msg->subject_key, &vrh->subject_key);
1336 vrh->issuer_attribute = GNUNET_strdup (issuer_attribute); 1416 vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
1337 vrh->resolution_algo = ntohs(c_msg->resolution_algo); 1417 vrh->resolution_algo = ntohs (c_msg->resolution_algo);
1338 1418
1339 if (0 == strlen (issuer_attribute)) { 1419 if (0 == strlen (issuer_attribute))
1420 {
1340 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n"); 1421 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No issuer attribute provided!\n");
1341 send_lookup_response (vrh); 1422 send_lookup_response (vrh);
1342 return; 1423 return;
1343 } 1424 }
1344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting delegates for subject\n"); 1425 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting delegates for subject\n");
1345 1426
1346 // Get all delegates from subject 1427 // Get all delegates from subject
1347 vrh->dele_qe = GNUNET_NAMESTORE_records_lookup (namestore, 1428 vrh->dele_qe =
1348 &c_msg->subject_key, 1429 GNUNET_NAMESTORE_records_lookup (namestore,
1349 GNUNET_GNS_EMPTY_LABEL_AT, 1430 &c_msg->subject_key,
1350 &handle_delegate_collection_error_cb, 1431 GNUNET_GNS_EMPTY_LABEL_AT,
1351 vrh, 1432 &handle_delegate_collection_error_cb,
1352 &handle_delegate_collection_cb, 1433 vrh,
1353 vrh); 1434 &handle_delegate_collection_cb,
1435 vrh);
1354 GNUNET_SERVICE_client_continue (vrh->client); 1436 GNUNET_SERVICE_client_continue (vrh->client);
1355} 1437}
1356 1438
@@ -1362,18 +1444,21 @@ check_collect (void *cls, const struct CollectMessage *c_msg)
1362 const char *attr; 1444 const char *attr;
1363 1445
1364 msg_size = ntohs (c_msg->header.size); 1446 msg_size = ntohs (c_msg->header.size);
1365 if (msg_size < sizeof (struct CollectMessage)) { 1447 if (msg_size < sizeof (struct CollectMessage))
1448 {
1366 GNUNET_break (0); 1449 GNUNET_break (0);
1367 return GNUNET_SYSERR; 1450 return GNUNET_SYSERR;
1368 } 1451 }
1369 if (ntohs (c_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) { 1452 if (ntohs (c_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH)
1453 {
1370 GNUNET_break (0); 1454 GNUNET_break (0);
1371 return GNUNET_SYSERR; 1455 return GNUNET_SYSERR;
1372 } 1456 }
1373 attr = (const char *)&c_msg[1]; 1457 attr = (const char *) &c_msg[1];
1374 1458
1375 if (('\0' != attr[msg_size - sizeof (struct CollectMessage) - 1]) 1459 if (('\0' != attr[msg_size - sizeof (struct CollectMessage) - 1]) ||
1376 || (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH)) { 1460 (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH))
1461 {
1377 GNUNET_break (0); 1462 GNUNET_break (0);
1378 return GNUNET_SYSERR; 1463 return GNUNET_SYSERR;
1379 } 1464 }
@@ -1411,11 +1496,13 @@ run (void *cls,
1411{ 1496{
1412 1497
1413 gns = GNUNET_GNS_connect (c); 1498 gns = GNUNET_GNS_connect (c);
1414 if (NULL == gns) { 1499 if (NULL == gns)
1500 {
1415 fprintf (stderr, _ ("Failed to connect to GNS\n")); 1501 fprintf (stderr, _ ("Failed to connect to GNS\n"));
1416 } 1502 }
1417 namestore = GNUNET_NAMESTORE_connect (c); 1503 namestore = GNUNET_NAMESTORE_connect (c);
1418 if (NULL == namestore) { 1504 if (NULL == namestore)
1505 {
1419 fprintf (stderr, _ ("Failed to connect to namestore\n")); 1506 fprintf (stderr, _ ("Failed to connect to namestore\n"));
1420 } 1507 }
1421 1508