X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fcredential%2Fgnunet-service-credential.c;h=be75e485ec375f65b2e573615e93fe7f1f9ad95c;hb=1eb75229e02e5bd678f1a99eae9a6062330ecb46;hp=2b3eb8b4c565911b63426dbdee151bf40eab340d;hpb=73a127e962c5ecbfc002b1b0c9ea9cf441591c6d;p=oweals%2Fgnunet.git diff --git a/src/credential/gnunet-service-credential.c b/src/credential/gnunet-service-credential.c index 2b3eb8b4c..be75e485e 100644 --- a/src/credential/gnunet-service-credential.c +++ b/src/credential/gnunet-service-credential.c @@ -31,22 +31,18 @@ #include "gnunet_protocols.h" #include "gnunet_signatures.h" -// For Looking up GNS request #include #include #include #include #include -#include "gnunet_gns_service.h" - - #define GNUNET_CREDENTIAL_MAX_LENGTH 255 struct VerifyRequestHandle; -struct DelegationSetEntry; +struct DelegationSetQueueEntry; struct DelegationChainEntry @@ -96,17 +92,16 @@ struct CredentialRecordEntry * DLL */ struct CredentialRecordEntry *prev; - - + /** - * Payload + * Number of references in delegation chains */ - struct GNUNET_CREDENTIAL_CredentialRecordData *data; + uint32_t refcount; /** - * Size + * Payload */ - uint64_t data_size; + struct GNUNET_CREDENTIAL_Credential *credential; }; /** @@ -128,17 +123,17 @@ struct DelegationQueueEntry /** * Sets under this Queue */ - struct DelegationSetEntry *set_entries_head; + struct DelegationSetQueueEntry *set_entries_head; /** * Sets under this Queue */ - struct DelegationSetEntry *set_entries_tail; + struct DelegationSetQueueEntry *set_entries_tail; /** * Parent set */ - struct DelegationSetEntry *parent_set; + struct DelegationSetQueueEntry *parent_set; /** * Required solutions @@ -150,17 +145,17 @@ struct DelegationQueueEntry * DLL for delegation sets * Used for AND delegation set */ -struct DelegationSetEntry +struct DelegationSetQueueEntry { /** * DLL */ - struct DelegationSetEntry *next; + struct DelegationSetQueueEntry *next; /** * DLL */ - struct DelegationSetEntry *prev; + struct DelegationSetQueueEntry *prev; /** * GNS handle @@ -299,7 +294,7 @@ struct VerifyRequestHandle /** * Root Delegation Set */ - struct DelegationSetEntry *root_set; + struct DelegationSetQueueEntry *root_set; /** * Current Delegation Pointer @@ -307,24 +302,24 @@ struct VerifyRequestHandle struct DelegationQueueEntry *current_delegation; /** - * The found credential + * request id */ - struct GNUNET_CREDENTIAL_CredentialRecordData *credential; + uint32_t request_id; /** - * Length of the credential + * Pending lookups */ - uint32_t credential_size; + uint64_t pending_lookups; /** - * request id + * Credential iterator */ - uint32_t request_id; + struct GNUNET_NAMESTORE_ZoneIterator *cred_collection_iter; /** - * Pending lookups + * Collect task */ - uint64_t pending_lookups; + struct GNUNET_SCHEDULER_Task *collect_next_task; }; @@ -350,11 +345,16 @@ static struct GNUNET_STATISTICS_Handle *statistics; static struct GNUNET_GNS_Handle *gns; +/** + * Handle to namestore service + */ +static struct GNUNET_NAMESTORE_Handle *namestore; + static void -cleanup_delegation_set (struct DelegationSetEntry *ds_entry) +cleanup_delegation_set (struct DelegationSetQueueEntry *ds_entry) { struct DelegationQueueEntry *dq_entry; - struct DelegationSetEntry *child; + struct DelegationSetQueueEntry *child; if (NULL == ds_entry) return; @@ -414,8 +414,6 @@ cleanup_handle (struct VerifyRequestHandle *vrh) GNUNET_GNS_lookup_cancel (vrh->lookup_request); vrh->lookup_request = NULL; } - if (NULL != vrh->credential) - GNUNET_free (vrh->credential); cleanup_delegation_set (vrh->root_set); if (NULL != vrh->issuer_attribute) GNUNET_free (vrh->issuer_attribute); @@ -426,8 +424,8 @@ cleanup_handle (struct VerifyRequestHandle *vrh) GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head, vrh->cred_chain_tail, cr_entry); - if (NULL != cr_entry->data) - GNUNET_free (cr_entry->data); + if (NULL != cr_entry->credential); + GNUNET_free (cr_entry->credential); GNUNET_free (cr_entry); } GNUNET_free (vrh); @@ -461,6 +459,11 @@ shutdown_task (void *cls) GNUNET_GNS_disconnect (gns); gns = NULL; } + if (NULL != namestore) + { + GNUNET_NAMESTORE_disconnect (namestore); + namestore = NULL; + } if (NULL != statistics) { GNUNET_STATISTICS_destroy (statistics, @@ -470,42 +473,7 @@ shutdown_task (void *cls) } -/** - * Checks a #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY message - * - * @param cls client sending the message - * @param v_msg message of type `struct VerifyMessage` - * @return #GNUNET_OK if @a v_msg is well-formed - */ -static int -check_verify (void *cls, - const struct VerifyMessage *v_msg) -{ - size_t msg_size; - const char* attrs; - msg_size = ntohs (v_msg->header.size); - if (msg_size < sizeof (struct VerifyMessage)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if ((ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) || - (ntohs (v_msg->subject_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - attrs = (const char *) &v_msg[1]; - - if ( ('\0' != attrs[ntohs(v_msg->header.size) - sizeof (struct VerifyMessage) - 1]) || - (strlen (attrs) > GNUNET_CREDENTIAL_MAX_LENGTH * 2) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} /** * Send. @@ -516,50 +484,68 @@ static void send_lookup_response (struct VerifyRequestHandle *vrh) { struct GNUNET_MQ_Envelope *env; - struct VerifyResultMessage *rmsg; + struct DelegationChainResultMessage *rmsg; struct DelegationChainEntry *dce; - size_t size = vrh->credential_size; struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size]; struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size]; - struct GNUNET_CREDENTIAL_CredentialRecordData *crd; struct CredentialRecordEntry *cd; + struct CredentialRecordEntry *tmp; + size_t size; int i; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response\n"); - i = 0; - for (dce = vrh->delegation_chain_head; - NULL != dce; - dce = dce->next) + dce = vrh->delegation_chain_head; + for (i=0;idelegation_chain_size;i++) { dd[i].issuer_key = dce->issuer_key; dd[i].subject_key = dce->subject_key; dd[i].issuer_attribute = dce->issuer_attribute; dd[i].issuer_attribute_len = strlen (dce->issuer_attribute)+1; dd[i].subject_attribute_len = 0; + dd[i].subject_attribute = NULL; if (NULL != dce->subject_attribute) { dd[i].subject_attribute = dce->subject_attribute; dd[i].subject_attribute_len = strlen(dce->subject_attribute)+1; } - i++; + dce = dce->next; + } + + /** + * Remove all credentials not needed + */ + for (cd = vrh->cred_chain_head; NULL != cd;) + { + if (cd->refcount > 0) + { + cd = cd->next; + continue; + } + tmp = cd; + cd = cd->next; + GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head, + vrh->cred_chain_tail, + tmp); + GNUNET_free (tmp->credential); + GNUNET_free (tmp); + vrh->cred_chain_size--; } /** * Get serialized record data * Append at the end of rmsg */ - i = 0; - for (cd = vrh->cred_chain_head; - NULL != cd; - cd = cd->next) + cd = vrh->cred_chain_head; + for (i=0;icred_chain_size;i++) { - crd = cd->data; - cred[i].issuer_key = crd->issuer_key; - cred[i].subject_key = crd->subject_key; - cred[i].issuer_attribute_len = strlen((char*)&crd[1])+1; - cred[i].issuer_attribute = (char*)&crd[1]; - i++; + cred[i].issuer_key = cd->credential->issuer_key; + cred[i].subject_key = cd->credential->subject_key; + cred[i].issuer_attribute_len = strlen(cd->credential->issuer_attribute)+1; + cred[i].issuer_attribute = cd->credential->issuer_attribute; + cred[i].expiration = cd->credential->expiration; + cred[i].signature = cd->credential->signature; + cd = cd->next; } size = GNUNET_CREDENTIAL_delegation_chain_get_size (vrh->delegation_chain_size, dd, @@ -573,18 +559,18 @@ send_lookup_response (struct VerifyRequestHandle *vrh) rmsg->d_count = htonl (vrh->delegation_chain_size); rmsg->c_count = htonl (vrh->cred_chain_size); - if (NULL != vrh->credential) + if (0 < vrh->cred_chain_size) rmsg->cred_found = htonl (GNUNET_YES); else rmsg->cred_found = htonl (GNUNET_NO); GNUNET_assert (-1 != - GNUNET_CREDENTIAL_delegation_chain_serialize (vrh->delegation_chain_size, - dd, - vrh->cred_chain_size, - cred, - size, - (char*)&rmsg[1])); + GNUNET_CREDENTIAL_delegation_chain_serialize (vrh->delegation_chain_size, + dd, + vrh->cred_chain_size, + cred, + size, + (char*)&rmsg[1])); GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(vrh->client), env); @@ -604,12 +590,11 @@ backward_resolution (void* cls, { struct VerifyRequestHandle *vrh; - struct GNUNET_CREDENTIAL_CredentialRecordData *cred; - const struct GNUNET_CREDENTIAL_DelegationRecordData *sets; + const struct GNUNET_CREDENTIAL_DelegationRecord *sets; struct CredentialRecordEntry *cred_pointer; - struct DelegationSetEntry *current_set; - struct DelegationSetEntry *ds_entry; - struct DelegationSetEntry *tmp_set; + struct DelegationSetQueueEntry *current_set; + struct DelegationSetQueueEntry *ds_entry; + struct DelegationSetQueueEntry *tmp_set; struct DelegationQueueEntry *dq_entry; char *expanded_attr; char *lookup_attribute; @@ -631,15 +616,15 @@ backward_resolution (void* cls, continue; sets = rd[i].data; - struct GNUNET_CREDENTIAL_DelegationSetRecord set[ntohl(sets->set_count)]; + struct GNUNET_CREDENTIAL_DelegationSet set[ntohl(sets->set_count)]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found new attribute delegation with %d sets. Creating new Job...\n", - ntohl (sets->set_count)); + ntohl (sets->set_count)); if (GNUNET_OK !=GNUNET_CREDENTIAL_delegation_set_deserialize (GNUNET_ntohll(sets->data_size), - (const char*)&sets[1], - ntohl(sets->set_count), - set)) + (const char*)&sets[1], + ntohl(sets->set_count), + set)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to deserialize!\n"); @@ -654,7 +639,7 @@ backward_resolution (void* cls, // Each AND for (j=0; jset_count); j++) { - ds_entry = GNUNET_new (struct DelegationSetEntry); + ds_entry = GNUNET_new (struct DelegationSetQueueEntry); if (NULL != current_set->attr_trailer) { if (0 == set[j].subject_attribute_len) @@ -706,21 +691,22 @@ backward_resolution (void* cls, for(cred_pointer = vrh->cred_chain_head; cred_pointer != NULL; cred_pointer = cred_pointer->next) { - cred = cred_pointer->data; if(0 != memcmp (&set->subject_key, - &cred_pointer->data->issuer_key, + &cred_pointer->credential->issuer_key, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))) continue; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking if %s matches %s\n", - ds_entry->unresolved_attribute_delegation, (char*)&cred[1]); + ds_entry->unresolved_attribute_delegation, + cred_pointer->credential->issuer_attribute); - if (0 != strcmp (ds_entry->unresolved_attribute_delegation, (char*)&cred[1])) + if (0 != strcmp (ds_entry->unresolved_attribute_delegation, + cred_pointer->credential->issuer_attribute)) continue; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found issuer\n"); - + cred_pointer->refcount++; //Backtrack for (tmp_set = ds_entry; NULL != tmp_set->parent_queue_entry; @@ -742,11 +728,6 @@ backward_resolution (void* cls, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All solutions found\n"); - vrh->credential = GNUNET_malloc (cred_pointer->data_size); - memcpy (vrh->credential, - cred, - cred_pointer->data_size); - vrh->credential_size = cred_pointer->data_size; //Found match send_lookup_response (vrh); return; @@ -791,7 +772,6 @@ backward_resolution (void* cls, ds_entry->issuer_key, //issuer_key, GNUNET_GNSRECORD_TYPE_ATTRIBUTE, GNUNET_GNS_LO_DEFAULT, - NULL, //shorten_key, always NULL &backward_resolution, ds_entry); GNUNET_free (lookup_attribute); @@ -817,56 +797,30 @@ backward_resolution (void* cls, * @param rd the record data */ static void -handle_credential_query (void* cls, - uint32_t rd_count, - const struct GNUNET_GNSRECORD_Data *rd) +delegation_chain_resolution_start (void* cls) { struct VerifyRequestHandle *vrh = cls; - struct DelegationSetEntry *ds_entry; - const struct GNUNET_CREDENTIAL_CredentialRecordData *crd; + struct DelegationSetQueueEntry *ds_entry; struct CredentialRecordEntry *cr_entry; - int cred_record_count; - int i; - vrh->lookup_request = NULL; - cred_record_count = 0; - for (i=0; i < rd_count; i++) + + if (0 == vrh->cred_chain_size) { - if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type) - continue; - cred_record_count++; - crd = rd[i].data; - if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL, - &crd->purpose, - &crd->signature, - &crd->issuer_key)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid credential found\n"); - continue; - } - cr_entry = GNUNET_new (struct CredentialRecordEntry); - cr_entry->data = GNUNET_malloc (rd[i].data_size); - memcpy (cr_entry->data, - crd, - rd[i].data_size); - cr_entry->data_size = rd[i].data_size; - GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head, - vrh->cred_chain_tail, - cr_entry); - vrh->cred_chain_size++; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "No credentials found\n"); + send_lookup_response (vrh); + return; + } - if (0 != memcmp (&crd->issuer_key, + for (cr_entry = vrh->cred_chain_head; cr_entry != NULL; cr_entry = cr_entry->next) + { + if (0 != memcmp (&cr_entry->credential->issuer_key, &vrh->issuer_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) continue; - if (0 != strcmp ((char*)&crd[1], vrh->issuer_attribute)) + if (0 != strcmp (cr_entry->credential->issuer_attribute, vrh->issuer_attribute)) continue; - vrh->credential = GNUNET_malloc (rd[i].data_size); - memcpy (vrh->credential, - rd[i].data, - rd[i].data_size); - vrh->credential_size = rd[i].data_size; + cr_entry->refcount++; //Found match prematurely send_lookup_response (vrh); return; @@ -884,7 +838,7 @@ handle_credential_query (void* cls, ".gnu"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up %s\n", issuer_attribute_name); - ds_entry = GNUNET_new (struct DelegationSetEntry); + ds_entry = GNUNET_new (struct DelegationSetQueueEntry); ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); memcpy (ds_entry->issuer_key, &vrh->issuer_key, @@ -900,11 +854,44 @@ handle_credential_query (void* cls, &vrh->issuer_key, //issuer_key, GNUNET_GNSRECORD_TYPE_ATTRIBUTE, GNUNET_GNS_LO_DEFAULT, - NULL, //shorten_key, always NULL &backward_resolution, ds_entry); } +/** + * Checks a #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY message + * + * @param cls client sending the message + * @param v_msg message of type `struct VerifyMessage` + * @return #GNUNET_OK if @a v_msg is well-formed + */ +static int +check_verify (void *cls, + const struct VerifyMessage *v_msg) +{ + size_t msg_size; + const char* attr; + + msg_size = ntohs (v_msg->header.size); + if (msg_size < sizeof (struct VerifyMessage)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + attr = (const char *) &v_msg[1]; + + if ( strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} /** * Handle Credential verification requests from client @@ -917,26 +904,24 @@ static void handle_verify (void *cls, const struct VerifyMessage *v_msg) { - char attrs[GNUNET_CREDENTIAL_MAX_LENGTH*2 + 1]; - char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; - char subject_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1 + 4]; struct VerifyRequestHandle *vrh; struct GNUNET_SERVICE_Client *client = cls; - char *attrptr = attrs; + struct CredentialRecordEntry *cr_entry; + uint32_t credentials_count; + uint32_t credential_data_size; + int i; + char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; + char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; + char *attrptr = attr; + char *credential_data; const char *utf_in; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received VERIFY message\n"); - utf_in = (const char *) &v_msg[1]; GNUNET_STRINGS_utf8_tolower (utf_in, attrptr); - - GNUNET_memcpy (issuer_attribute, attrs, ntohs (v_msg->issuer_attribute_len)); + GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len)); issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0'; - GNUNET_memcpy (subject_attribute, attrs+strlen(issuer_attribute), ntohs (v_msg->subject_attribute_len)); - strcpy (subject_attribute+ntohs (v_msg->subject_attribute_len), - ".gnu"); - subject_attribute[ntohs (v_msg->subject_attribute_len)+4] = '\0'; vrh = GNUNET_new (struct VerifyRequestHandle); GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh); vrh->client = client; @@ -944,14 +929,167 @@ handle_verify (void *cls, vrh->issuer_key = v_msg->issuer_key; vrh->subject_key = v_msg->subject_key; vrh->issuer_attribute = GNUNET_strdup (issuer_attribute); - - if (NULL == subject_attribute) + if (NULL == issuer_attribute) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "No subject attribute provided!\n"); + "No issuer attribute provided!\n"); send_lookup_response (vrh); return; } + /** + * First, collect credentials + * TODO: cleanup! + */ + credentials_count = ntohl(v_msg->c_count); + credential_data_size = ntohs (v_msg->header.size) + - sizeof (struct VerifyMessage) + - ntohs (v_msg->issuer_attribute_len) + - 1; + struct GNUNET_CREDENTIAL_Credential credentials[credentials_count]; + credential_data = (char*)&v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1; + if (GNUNET_OK != GNUNET_CREDENTIAL_credentials_deserialize (credential_data_size, + credential_data, + credentials_count, + credentials)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Cannot deserialize credentials!\n"); + send_lookup_response (vrh); + return; + } + + for (i=0;icredential = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + + credentials[i].issuer_attribute_len); + GNUNET_memcpy (cr_entry->credential, + &credentials[i], + sizeof (struct GNUNET_CREDENTIAL_Credential)); + GNUNET_memcpy (&cr_entry->credential[1], + credentials[i].issuer_attribute, + credentials[i].issuer_attribute_len); + cr_entry->credential->issuer_attribute = (char*)&cr_entry->credential[1]; + GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head, + vrh->cred_chain_tail, + cr_entry); + vrh->cred_chain_size++; + } + + delegation_chain_resolution_start (vrh); + +} + +/** + * We encountered an error while collecting + */ +static void +handle_cred_collection_error_cb (void *cls) +{ + struct VerifyRequestHandle *vrh = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got disconnected from namestore database.\n"); + vrh->cred_collection_iter = NULL; + send_lookup_response (vrh); +} + +static void +collect_next (void *cls) +{ + struct VerifyRequestHandle *vrh = cls; + vrh->collect_next_task = NULL; + GNUNET_assert (NULL != vrh->cred_collection_iter); + GNUNET_NAMESTORE_zone_iterator_next (vrh->cred_collection_iter); +} + +/** + * Store credential + */ +static void +handle_cred_collection_cb (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, + const char *label, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd) +{ + struct VerifyRequestHandle *vrh = cls; + struct GNUNET_CREDENTIAL_Credential *crd; + struct CredentialRecordEntry *cr_entry; + int cred_record_count; + int i; + + cred_record_count = 0; + for (i=0; i < rd_count; i++) + { + if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type) + continue; + cred_record_count++; + crd = GNUNET_CREDENTIAL_credential_deserialize (rd[i].data, + rd[i].data_size); + if (NULL == crd) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Invalid credential found\n"); + continue; + } + cr_entry = GNUNET_new (struct CredentialRecordEntry); + cr_entry->credential = crd; + GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head, + vrh->cred_chain_tail, + cr_entry); + vrh->cred_chain_size++; + } + vrh->collect_next_task = GNUNET_SCHEDULER_add_now (&collect_next, + vrh); +} + +/** + * We encountered an error while collecting + */ +static void +handle_cred_collection_finished_cb (void *cls) +{ + struct VerifyRequestHandle *vrh = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Done collecting credentials.\n"); + vrh->cred_collection_iter = NULL; + delegation_chain_resolution_start (vrh); +} + +/** + * Handle Credential collection requests from client + * + * @param cls the closure + * @param client the client + * @param message the message + */ +static void +handle_collect (void *cls, + const struct CollectMessage *c_msg) +{ + char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; + char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; + struct VerifyRequestHandle *vrh; + struct GNUNET_SERVICE_Client *client = cls; + char *attrptr = attr; + const char *utf_in; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received COLLECT message\n"); + + utf_in = (const char *) &c_msg[1]; + GNUNET_STRINGS_utf8_tolower (utf_in, attrptr); + + GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len)); + issuer_attribute[ntohs (c_msg->issuer_attribute_len)] = '\0'; + vrh = GNUNET_new (struct VerifyRequestHandle); + GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh); + vrh->client = client; + vrh->request_id = c_msg->id; + vrh->issuer_key = c_msg->issuer_key; + GNUNET_CRYPTO_ecdsa_key_get_public (&c_msg->subject_key, + &vrh->subject_key); + vrh->issuer_attribute = GNUNET_strdup (issuer_attribute); + if (NULL == issuer_attribute) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -960,22 +1098,57 @@ handle_verify (void *cls, return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Looking up %s\n", - subject_attribute); + "Getting credentials for subject\n"); /** * First, get attribute from subject */ - vrh->lookup_request = GNUNET_GNS_lookup (gns, - subject_attribute, - &v_msg->subject_key, //subject_pkey, - GNUNET_GNSRECORD_TYPE_CREDENTIAL, - GNUNET_GNS_LO_DEFAULT, - NULL, //shorten_key, always NULL - &handle_credential_query, - vrh); + vrh->cred_collection_iter = GNUNET_NAMESTORE_zone_iteration_start (namestore, + &c_msg->subject_key, + &handle_cred_collection_error_cb, + vrh, + &handle_cred_collection_cb, + vrh, + &handle_cred_collection_finished_cb, + vrh); } +/** + * Checks a #GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT message + * + * @param cls client sending the message + * @param v_msg message of type `struct CollectMessage` + * @return #GNUNET_OK if @a v_msg is well-formed + */ +static int +check_collect (void *cls, + const struct CollectMessage *c_msg) +{ + size_t msg_size; + const char* attr; + + msg_size = ntohs (c_msg->header.size); + if (msg_size < sizeof (struct CollectMessage)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (ntohs (c_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + attr = (const char *) &c_msg[1]; + + if ( ('\0' != attr[ntohs(c_msg->header.size) - sizeof (struct CollectMessage) - 1]) || + (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + /** * One of our clients disconnected, clean up after it. * @@ -1030,6 +1203,12 @@ run (void *cls, fprintf (stderr, _("Failed to connect to GNS\n")); } + namestore = GNUNET_NAMESTORE_connect (c); + if (NULL == namestore) + { + fprintf (stderr, + _("Failed to connect to namestore\n")); + } statistics = GNUNET_STATISTICS_create ("credential", c); GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); @@ -1050,6 +1229,10 @@ GNUNET_SERVICE_MAIN GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY, struct VerifyMessage, NULL), + GNUNET_MQ_hd_var_size (collect, + GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT, + struct CollectMessage, + NULL), GNUNET_MQ_handler_end()); /* end of gnunet-service-credential.c */