2 This file is part of GNUnet.
3 Copyright (C) 2011-2013 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @file gns/gnunet-service-credential.c
22 * @brief GNU Credential Service (main service)
23 * @author Adnan Husain
26 #include "gnunet_util_lib.h"
27 #include "gnunet_credential_service.h"
28 #include "gnunet_statistics_service.h"
29 #include "credential.h"
30 #include "credential_serialization.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_signatures.h"
34 // For Looking up GNS request
35 #include <gnunet_dnsparser_lib.h>
36 #include <gnunet_identity_service.h>
37 #include <gnunet_gnsrecord_lib.h>
38 #include <gnunet_namestore_service.h>
39 #include <gnunet_gns_service.h>
40 #include "gnunet_gns_service.h"
45 #define GNUNET_CREDENTIAL_MAX_LENGTH 255
47 struct VerifyRequestHandle;
49 struct DelegationSetQueueEntry;
52 struct DelegationChainEntry
57 struct DelegationChainEntry *next;
62 struct DelegationChainEntry *prev;
67 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
72 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
75 * The issued attribute
77 char *issuer_attribute;
80 * The delegated attribute
82 char *subject_attribute;
88 struct CredentialRecordEntry
93 struct CredentialRecordEntry *next;
98 struct CredentialRecordEntry *prev;
104 struct GNUNET_CREDENTIAL_Credential *credential;
108 * DLL used for delegations
109 * Used for OR delegations
111 struct DelegationQueueEntry
116 struct DelegationQueueEntry *next;
121 struct DelegationQueueEntry *prev;
124 * Sets under this Queue
126 struct DelegationSetQueueEntry *set_entries_head;
129 * Sets under this Queue
131 struct DelegationSetQueueEntry *set_entries_tail;
136 struct DelegationSetQueueEntry *parent_set;
141 uint32_t required_solutions;
145 * DLL for delegation sets
146 * Used for AND delegation set
148 struct DelegationSetQueueEntry
153 struct DelegationSetQueueEntry *next;
158 struct DelegationSetQueueEntry *prev;
163 struct GNUNET_GNS_LookupRequest *lookup_request;
168 struct VerifyRequestHandle *handle;
171 * Parent attribute delegation
173 struct DelegationQueueEntry *parent;
178 struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key;
181 * Queue entries of this set
183 struct DelegationQueueEntry *queue_entries_head;
186 * Queue entries of this set
188 struct DelegationQueueEntry *queue_entries_tail;
193 struct DelegationQueueEntry *parent_queue_entry;
196 * Issuer attribute delegated to
198 char *issuer_attribute;
201 * The current attribute to look up
203 char *lookup_attribute;
206 * Trailing attribute context
211 * Still to resolve delegation as string
213 char *unresolved_attribute_delegation;
216 * The delegation chain entry
218 struct DelegationChainEntry *delegation_chain_entry;
224 * Handle to a lookup operation from api
226 struct VerifyRequestHandle
230 * We keep these in a DLL.
232 struct VerifyRequestHandle *next;
235 * We keep these in a DLL.
237 struct VerifyRequestHandle *prev;
240 * Handle to the requesting client
242 struct GNUNET_SERVICE_Client *client;
247 struct GNUNET_GNS_LookupRequest *lookup_request;
250 * Size of delegation tree
252 uint32_t delegation_chain_size;
255 * Children of this attribute
257 struct DelegationChainEntry *delegation_chain_head;
260 * Children of this attribute
262 struct DelegationChainEntry *delegation_chain_tail;
267 struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
272 char *issuer_attribute;
277 struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
282 struct CredentialRecordEntry *cred_chain_head;
287 struct CredentialRecordEntry *cred_chain_tail;
290 * Credential DLL size
292 uint32_t cred_chain_size;
295 * Root Delegation Set
297 struct DelegationSetQueueEntry *root_set;
300 * Current Delegation Pointer
302 struct DelegationQueueEntry *current_delegation;
312 uint64_t pending_lookups;
320 static struct VerifyRequestHandle *vrh_head;
325 static struct VerifyRequestHandle *vrh_tail;
328 * Handle to the statistics service
330 static struct GNUNET_STATISTICS_Handle *statistics;
333 * Handle to GNS service.
335 static struct GNUNET_GNS_Handle *gns;
339 cleanup_delegation_set (struct DelegationSetQueueEntry *ds_entry)
341 struct DelegationQueueEntry *dq_entry;
342 struct DelegationSetQueueEntry *child;
344 if (NULL == ds_entry)
347 for (dq_entry = ds_entry->queue_entries_head;
349 dq_entry = ds_entry->queue_entries_head)
351 GNUNET_CONTAINER_DLL_remove (ds_entry->queue_entries_head,
352 ds_entry->queue_entries_tail,
354 for (child = dq_entry->set_entries_head;
356 child = dq_entry->set_entries_head)
358 GNUNET_CONTAINER_DLL_remove (dq_entry->set_entries_head,
359 dq_entry->set_entries_tail,
361 cleanup_delegation_set (child);
363 GNUNET_free (dq_entry);
365 if (NULL != ds_entry->issuer_key)
366 GNUNET_free (ds_entry->issuer_key);
367 if (NULL != ds_entry->lookup_attribute)
368 GNUNET_free (ds_entry->lookup_attribute);
369 if (NULL != ds_entry->issuer_attribute)
370 GNUNET_free (ds_entry->issuer_attribute);
371 if (NULL != ds_entry->unresolved_attribute_delegation)
372 GNUNET_free (ds_entry->unresolved_attribute_delegation);
373 if (NULL != ds_entry->attr_trailer)
374 GNUNET_free (ds_entry->attr_trailer);
375 if (NULL != ds_entry->lookup_request)
377 GNUNET_GNS_lookup_cancel (ds_entry->lookup_request);
378 ds_entry->lookup_request = NULL;
380 if (NULL != ds_entry->delegation_chain_entry)
382 if (NULL != ds_entry->delegation_chain_entry->subject_attribute)
383 GNUNET_free (ds_entry->delegation_chain_entry->subject_attribute);
384 if (NULL != ds_entry->delegation_chain_entry->issuer_attribute)
385 GNUNET_free (ds_entry->delegation_chain_entry->issuer_attribute);
386 GNUNET_free (ds_entry->delegation_chain_entry);
388 GNUNET_free (ds_entry);
392 cleanup_handle (struct VerifyRequestHandle *vrh)
394 struct CredentialRecordEntry *cr_entry;
395 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
397 if (NULL != vrh->lookup_request)
399 GNUNET_GNS_lookup_cancel (vrh->lookup_request);
400 vrh->lookup_request = NULL;
402 cleanup_delegation_set (vrh->root_set);
403 if (NULL != vrh->issuer_attribute)
404 GNUNET_free (vrh->issuer_attribute);
405 for (cr_entry = vrh->cred_chain_head;
406 NULL != vrh->cred_chain_head;
407 cr_entry = vrh->cred_chain_head)
409 GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head,
410 vrh->cred_chain_tail,
412 if (NULL != cr_entry->credential);
413 GNUNET_free (cr_entry->credential);
414 GNUNET_free (cr_entry);
420 * Task run during shutdown.
426 shutdown_task (void *cls)
428 struct VerifyRequestHandle *vrh;
430 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
433 while (NULL != (vrh = vrh_head))
435 //CREDENTIAL_resolver_lookup_cancel (clh->lookup);
436 GNUNET_CONTAINER_DLL_remove (vrh_head,
439 cleanup_handle (vrh);
444 GNUNET_GNS_disconnect (gns);
447 if (NULL != statistics)
449 GNUNET_STATISTICS_destroy (statistics,
457 * Checks a #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY message
459 * @param cls client sending the message
460 * @param v_msg message of type `struct VerifyMessage`
461 * @return #GNUNET_OK if @a v_msg is well-formed
464 check_verify (void *cls,
465 const struct VerifyMessage *v_msg)
470 msg_size = ntohs (v_msg->header.size);
471 if (msg_size < sizeof (struct VerifyMessage))
474 return GNUNET_SYSERR;
476 if ((ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) ||
477 (ntohs (v_msg->subject_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH))
480 return GNUNET_SYSERR;
482 attrs = (const char *) &v_msg[1];
484 if ( ('\0' != attrs[ntohs(v_msg->header.size) - sizeof (struct VerifyMessage) - 1]) ||
485 (strlen (attrs) > GNUNET_CREDENTIAL_MAX_LENGTH * 2) )
488 return GNUNET_SYSERR;
496 * @param handle the handle to the request
499 send_lookup_response (struct VerifyRequestHandle *vrh)
501 struct GNUNET_MQ_Envelope *env;
502 struct VerifyResultMessage *rmsg;
503 struct DelegationChainEntry *dce;
504 struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size];
505 struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size];
506 struct CredentialRecordEntry *cd;
510 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
511 "Sending response\n");
512 dce = vrh->delegation_chain_head;
513 for (i=0;i<vrh->delegation_chain_size;i++)
515 dd[i].issuer_key = dce->issuer_key;
516 dd[i].subject_key = dce->subject_key;
517 dd[i].issuer_attribute = dce->issuer_attribute;
518 dd[i].issuer_attribute_len = strlen (dce->issuer_attribute)+1;
519 dd[i].subject_attribute_len = 0;
520 dd[i].subject_attribute = NULL;
521 if (NULL != dce->subject_attribute)
523 dd[i].subject_attribute = dce->subject_attribute;
524 dd[i].subject_attribute_len = strlen(dce->subject_attribute)+1;
530 * Get serialized record data
531 * Append at the end of rmsg
533 cd = vrh->cred_chain_head;
534 for (i=0;i<vrh->cred_chain_size;i++)
536 cred[i].issuer_key = cd->credential->issuer_key;
537 cred[i].subject_key = cd->credential->subject_key;
538 cred[i].issuer_attribute_len = strlen(cd->credential->issuer_attribute)+1;
539 cred[i].issuer_attribute = cd->credential->issuer_attribute;
540 cred[i].expiration = cd->credential->expiration;
541 cred[i].signature = cd->credential->signature;
544 size = GNUNET_CREDENTIAL_delegation_chain_get_size (vrh->delegation_chain_size,
546 vrh->cred_chain_size,
548 env = GNUNET_MQ_msg_extra (rmsg,
550 GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT);
551 //Assign id so that client can find associated request
552 rmsg->id = vrh->request_id;
553 rmsg->d_count = htonl (vrh->delegation_chain_size);
554 rmsg->c_count = htonl (vrh->cred_chain_size);
556 if (0 < vrh->cred_chain_size)
557 rmsg->cred_found = htonl (GNUNET_YES);
559 rmsg->cred_found = htonl (GNUNET_NO);
562 GNUNET_CREDENTIAL_delegation_chain_serialize (vrh->delegation_chain_size,
564 vrh->cred_chain_size,
569 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(vrh->client),
571 GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh);
574 GNUNET_STATISTICS_update (statistics,
575 "Completed verifications", 1,
581 backward_resolution (void* cls,
583 const struct GNUNET_GNSRECORD_Data *rd)
586 struct VerifyRequestHandle *vrh;
587 const struct GNUNET_CREDENTIAL_DelegationRecord *sets;
588 struct CredentialRecordEntry *cred_pointer;
589 struct DelegationSetQueueEntry *current_set;
590 struct DelegationSetQueueEntry *ds_entry;
591 struct DelegationSetQueueEntry *tmp_set;
592 struct DelegationQueueEntry *dq_entry;
594 char *lookup_attribute;
600 current_set->lookup_request = NULL;
601 vrh = current_set->handle;
602 vrh->pending_lookups--;
603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
604 "Got %d attrs\n", rd_count);
607 for (i=0; i < rd_count; i++)
609 if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
613 struct GNUNET_CREDENTIAL_DelegationSet set[ntohl(sets->set_count)];
614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
615 "Found new attribute delegation with %d sets. Creating new Job...\n",
616 ntohl (sets->set_count));
618 if (GNUNET_OK !=GNUNET_CREDENTIAL_delegation_set_deserialize (GNUNET_ntohll(sets->data_size),
619 (const char*)&sets[1],
620 ntohl(sets->set_count),
623 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
624 "Failed to deserialize!\n");
627 dq_entry = GNUNET_new (struct DelegationQueueEntry);
628 dq_entry->required_solutions = ntohl(sets->set_count);
629 dq_entry->parent_set = current_set;
630 GNUNET_CONTAINER_DLL_insert (current_set->queue_entries_head,
631 current_set->queue_entries_tail,
634 for (j=0; j<ntohl(sets->set_count); j++)
636 ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
637 if (NULL != current_set->attr_trailer)
639 if (0 == set[j].subject_attribute_len)
641 GNUNET_asprintf (&expanded_attr,
643 current_set->attr_trailer);
646 GNUNET_asprintf (&expanded_attr,
648 set[j].subject_attribute,
649 current_set->attr_trailer);
651 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
652 "Expanded to %s\n", expanded_attr);
653 ds_entry->unresolved_attribute_delegation = expanded_attr;
655 if (0 != set[j].subject_attribute_len)
657 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
658 "Not Expanding %s\n", set[j].subject_attribute);
659 ds_entry->unresolved_attribute_delegation = GNUNET_strdup (set[j].subject_attribute);
663 //Add a credential chain entry
664 ds_entry->delegation_chain_entry = GNUNET_new (struct DelegationChainEntry);
665 ds_entry->delegation_chain_entry->subject_key = set[j].subject_key;
666 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
667 GNUNET_memcpy (ds_entry->issuer_key,
669 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
670 if (0 < set[j].subject_attribute_len)
671 ds_entry->delegation_chain_entry->subject_attribute = GNUNET_strdup (set[j].subject_attribute);
672 ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key;
673 ds_entry->delegation_chain_entry->issuer_attribute = GNUNET_strdup (current_set->lookup_attribute);
675 ds_entry->parent_queue_entry = dq_entry; //current_delegation;
676 GNUNET_CONTAINER_DLL_insert (dq_entry->set_entries_head,
677 dq_entry->set_entries_tail,
680 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
681 "Checking for cred match\n");
683 * Check if this delegation already matches one of our credentials
685 for(cred_pointer = vrh->cred_chain_head; cred_pointer != NULL;
686 cred_pointer = cred_pointer->next)
688 if(0 != memcmp (&set->subject_key,
689 &cred_pointer->credential->issuer_key,
690 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
692 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
693 "Checking if %s matches %s\n",
694 ds_entry->unresolved_attribute_delegation,
695 cred_pointer->credential->issuer_attribute);
697 if (0 != strcmp (ds_entry->unresolved_attribute_delegation,
698 cred_pointer->credential->issuer_attribute))
701 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
705 for (tmp_set = ds_entry;
706 NULL != tmp_set->parent_queue_entry;
707 tmp_set = tmp_set->parent_queue_entry->parent_set)
709 tmp_set->parent_queue_entry->required_solutions--;
710 if (NULL != tmp_set->delegation_chain_entry)
712 vrh->delegation_chain_size++;
713 GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head,
714 vrh->delegation_chain_tail,
715 tmp_set->delegation_chain_entry);
717 if (0 < tmp_set->parent_queue_entry->required_solutions)
721 if (NULL == tmp_set->parent_queue_entry)
723 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
724 "All solutions found\n");
726 send_lookup_response (vrh);
729 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
730 "Not all solutions found yet.\n");
734 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
735 "Building new lookup request from %s\n",
736 ds_entry->unresolved_attribute_delegation);
737 //Continue with backward resolution
738 char issuer_attribute_name[strlen (ds_entry->unresolved_attribute_delegation)+1];
739 strcpy (issuer_attribute_name,
740 ds_entry->unresolved_attribute_delegation);
741 char *next_attr = strtok (issuer_attribute_name, ".");
742 GNUNET_asprintf (&lookup_attribute,
745 GNUNET_asprintf (&ds_entry->lookup_attribute,
748 if (strlen (next_attr) == strlen (ds_entry->unresolved_attribute_delegation))
750 ds_entry->attr_trailer = NULL;
752 next_attr += strlen (next_attr) + 1;
753 ds_entry->attr_trailer = GNUNET_strdup (next_attr);
756 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
757 "Looking up %s\n", ds_entry->lookup_attribute);
758 if (NULL != ds_entry->attr_trailer)
759 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
760 "%s still to go...\n", ds_entry->attr_trailer);
762 vrh->pending_lookups++;
763 ds_entry->handle = vrh;
764 ds_entry->lookup_request = GNUNET_GNS_lookup (gns,
766 ds_entry->issuer_key, //issuer_key,
767 GNUNET_GNSRECORD_TYPE_ATTRIBUTE,
768 GNUNET_GNS_LO_DEFAULT,
769 NULL, //shorten_key, always NULL
770 &backward_resolution,
772 GNUNET_free (lookup_attribute);
776 if(0 == vrh->pending_lookups)
778 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
779 "We are all out of attributes...\n");
780 send_lookup_response (vrh);
788 * Result from GNS lookup.
790 * @param cls the closure (our client lookup handle)
791 * @param rd_count the number of records in @a rd
792 * @param rd the record data
795 handle_credential_query (void* cls,
797 const struct GNUNET_GNSRECORD_Data *rd)
799 struct VerifyRequestHandle *vrh = cls;
800 struct DelegationSetQueueEntry *ds_entry;
801 struct GNUNET_CREDENTIAL_Credential *crd;
802 struct CredentialRecordEntry *cr_entry;
803 int cred_record_count;
806 vrh->lookup_request = NULL;
807 cred_record_count = 0;
808 for (i=0; i < rd_count; i++)
810 if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type)
813 crd = GNUNET_CREDENTIAL_credential_deserialize (rd[i].data,
817 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
818 "Invalid credential found\n");
821 cr_entry = GNUNET_new (struct CredentialRecordEntry);
822 cr_entry->credential = crd;
823 GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head,
824 vrh->cred_chain_tail,
826 vrh->cred_chain_size++;
828 if (0 != memcmp (&crd->issuer_key,
830 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
832 if (0 != strcmp (crd->issuer_attribute, vrh->issuer_attribute))
834 //Found match prematurely
835 send_lookup_response (vrh);
841 * Check for attributes from the issuer and follow the chain
842 * till you get the required subject's attributes
844 char issuer_attribute_name[strlen (vrh->issuer_attribute)];
845 strcpy (issuer_attribute_name,
846 vrh->issuer_attribute);
847 strcpy (issuer_attribute_name + strlen (vrh->issuer_attribute),
849 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
850 "Looking up %s\n", issuer_attribute_name);
851 ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
852 ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
853 memcpy (ds_entry->issuer_key,
855 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
856 ds_entry->issuer_attribute = GNUNET_strdup (vrh->issuer_attribute);
857 ds_entry->handle = vrh;
858 ds_entry->lookup_attribute = GNUNET_strdup (vrh->issuer_attribute);
859 vrh->root_set = ds_entry;
860 vrh->pending_lookups = 1;
861 //Start with backward resolution
862 ds_entry->lookup_request = GNUNET_GNS_lookup (gns,
863 issuer_attribute_name,
864 &vrh->issuer_key, //issuer_key,
865 GNUNET_GNSRECORD_TYPE_ATTRIBUTE,
866 GNUNET_GNS_LO_DEFAULT,
867 NULL, //shorten_key, always NULL
868 &backward_resolution,
874 * Handle Credential verification requests from client
876 * @param cls the closure
877 * @param client the client
878 * @param message the message
881 handle_verify (void *cls,
882 const struct VerifyMessage *v_msg)
884 char attrs[GNUNET_CREDENTIAL_MAX_LENGTH*2 + 1];
885 char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
886 char subject_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1 + 4];
887 struct VerifyRequestHandle *vrh;
888 struct GNUNET_SERVICE_Client *client = cls;
889 char *attrptr = attrs;
892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
893 "Received VERIFY message\n");
895 utf_in = (const char *) &v_msg[1];
896 GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
898 GNUNET_memcpy (issuer_attribute, attrs, ntohs (v_msg->issuer_attribute_len));
899 issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0';
900 GNUNET_memcpy (subject_attribute, attrs+strlen(issuer_attribute), ntohs (v_msg->subject_attribute_len));
901 strcpy (subject_attribute+ntohs (v_msg->subject_attribute_len),
903 subject_attribute[ntohs (v_msg->subject_attribute_len)+4] = '\0';
904 vrh = GNUNET_new (struct VerifyRequestHandle);
905 GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
906 vrh->client = client;
907 vrh->request_id = v_msg->id;
908 vrh->issuer_key = v_msg->issuer_key;
909 vrh->subject_key = v_msg->subject_key;
910 vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
912 if (NULL == subject_attribute)
914 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
915 "No subject attribute provided!\n");
916 send_lookup_response (vrh);
919 if (NULL == issuer_attribute)
921 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
922 "No issuer attribute provided!\n");
923 send_lookup_response (vrh);
926 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
930 * First, get attribute from subject
932 vrh->lookup_request = GNUNET_GNS_lookup (gns,
934 &v_msg->subject_key, //subject_pkey,
935 GNUNET_GNSRECORD_TYPE_CREDENTIAL,
936 GNUNET_GNS_LO_DEFAULT,
937 NULL, //shorten_key, always NULL
938 &handle_credential_query,
944 * One of our clients disconnected, clean up after it.
947 * @param client the client that disconnected
950 client_disconnect_cb (void *cls,
951 struct GNUNET_SERVICE_Client *client,
954 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
955 "Client %p disconnected\n",
960 * Add a client to our list of active clients.
963 * @param client client to add
964 * @param mq message queue for @a client
965 * @return this client
968 client_connect_cb (void *cls,
969 struct GNUNET_SERVICE_Client *client,
970 struct GNUNET_MQ_Handle *mq)
972 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
973 "Client %p connected\n",
979 * Process Credential requests.
982 * @param server the initialized server
983 * @param c configuration to use
987 const struct GNUNET_CONFIGURATION_Handle *c,
988 struct GNUNET_SERVICE_Handle *handle)
991 gns = GNUNET_GNS_connect (c);
995 _("Failed to connect to GNS\n"));
998 statistics = GNUNET_STATISTICS_create ("credential", c);
999 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
1004 * Define "main" method using service macro
1008 GNUNET_SERVICE_OPTION_NONE,
1011 &client_disconnect_cb,
1013 GNUNET_MQ_hd_var_size (verify,
1014 GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY,
1015 struct VerifyMessage,
1017 GNUNET_MQ_handler_end());
1019 /* end of gnunet-service-credential.c */