Boston, MA 02110-1301, USA.
*/
/**
- * @file gns/gnunet-service-credential.c
- * @brief GNU Credential Service (main service)
- * @author Adnan Husain
+ * @file credential/gnunet-service-credential.c
+ * @brief GNUnet Credential Service (main service)
+ * @author Martin Schanzenbach
*/
#include "platform.h"
#include "gnunet_util_lib.h"
* The issuer
*/
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
-
+
/**
* The subject
*/
struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
-
+
/**
* The issued attribute
*/
char *issuer_attribute;
-
+
/**
* The delegated attribute
*/
*/
struct CredentialRecordEntry *prev;
+ /**
+ * Number of references in delegation chains
+ */
+ uint32_t refcount;
/**
* Payload
}
GNUNET_free (dq_entry);
}
- if (NULL != ds_entry->issuer_key)
- GNUNET_free (ds_entry->issuer_key);
- if (NULL != ds_entry->lookup_attribute)
- GNUNET_free (ds_entry->lookup_attribute);
- if (NULL != ds_entry->issuer_attribute)
- GNUNET_free (ds_entry->issuer_attribute);
- if (NULL != ds_entry->unresolved_attribute_delegation)
- GNUNET_free (ds_entry->unresolved_attribute_delegation);
- if (NULL != ds_entry->attr_trailer)
- GNUNET_free (ds_entry->attr_trailer);
+ GNUNET_free_non_null (ds_entry->issuer_key);
+ GNUNET_free_non_null (ds_entry->lookup_attribute);
+ GNUNET_free_non_null (ds_entry->issuer_attribute);
+ GNUNET_free_non_null (ds_entry->unresolved_attribute_delegation);
+ GNUNET_free_non_null (ds_entry->attr_trailer);
if (NULL != ds_entry->lookup_request)
{
GNUNET_GNS_lookup_cancel (ds_entry->lookup_request);
}
if (NULL != ds_entry->delegation_chain_entry)
{
- if (NULL != ds_entry->delegation_chain_entry->subject_attribute)
- GNUNET_free (ds_entry->delegation_chain_entry->subject_attribute);
- if (NULL != ds_entry->delegation_chain_entry->issuer_attribute)
- GNUNET_free (ds_entry->delegation_chain_entry->issuer_attribute);
+ GNUNET_free_non_null (ds_entry->delegation_chain_entry->subject_attribute);
+ GNUNET_free_non_null (ds_entry->delegation_chain_entry->issuer_attribute);
GNUNET_free (ds_entry->delegation_chain_entry);
}
GNUNET_free (ds_entry);
vrh->lookup_request = NULL;
}
cleanup_delegation_set (vrh->root_set);
- if (NULL != vrh->issuer_attribute)
- GNUNET_free (vrh->issuer_attribute);
- for (cr_entry = vrh->cred_chain_head;
+ GNUNET_free_non_null (vrh->issuer_attribute);
+ for (cr_entry = vrh->cred_chain_head;
NULL != vrh->cred_chain_head;
cr_entry = vrh->cred_chain_head)
{
GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head,
vrh->cred_chain_tail,
cr_entry);
- if (NULL != cr_entry->credential);
- GNUNET_free (cr_entry->credential);
+ GNUNET_free_non_null (cr_entry->credential);
GNUNET_free (cr_entry);
}
GNUNET_free (vrh);
}
-/**
- * Task run during shutdown.
- *
- * @param cls unused
- * @param tc unused
- */
static void
shutdown_task (void *cls)
{
-/**
- * Send.
- *
- * @param handle the handle to the request
- */
static void
send_lookup_response (struct VerifyRequestHandle *vrh)
{
struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size];
struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size];
struct CredentialRecordEntry *cd;
+ struct CredentialRecordEntry *tmp;
size_t size;
- int i;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending response\n");
dce = vrh->delegation_chain_head;
- for (i=0;i<vrh->delegation_chain_size;i++)
+ for (uint32_t i=0;i<vrh->delegation_chain_size;i++)
{
dd[i].issuer_key = dce->issuer_key;
dd[i].subject_key = dce->subject_key;
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
*/
cd = vrh->cred_chain_head;
- for (i=0;i<vrh->cred_chain_size;i++)
+ for (uint32_t i=0;i<vrh->cred_chain_size;i++)
{
cred[i].issuer_key = cd->credential->issuer_key;
cred[i].subject_key = cd->credential->subject_key;
else
rmsg->cred_found = htonl (GNUNET_NO);
- GNUNET_assert (-1 !=
+ GNUNET_assert (-1 !=
GNUNET_CREDENTIAL_delegation_chain_serialize (vrh->delegation_chain_size,
dd,
vrh->cred_chain_size,
struct DelegationQueueEntry *dq_entry;
char *expanded_attr;
char *lookup_attribute;
- int i;
- int j;
current_set = cls;
"Got %d attrs\n", rd_count);
// Each OR
- for (i=0; i < rd_count; i++)
+ for (uint32_t i=0; i < rd_count; i++)
{
if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type)
continue;
current_set->queue_entries_tail,
dq_entry);
// Each AND
- for (j=0; j<ntohl(sets->set_count); j++)
+ for (uint32_t j=0; j<ntohl(sets->set_count); j++)
{
ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
if (NULL != current_set->attr_trailer)
/**
* Check if this delegation already matches one of our credentials
*/
- for(cred_pointer = vrh->cred_chain_head; cred_pointer != NULL;
+ for(cred_pointer = vrh->cred_chain_head; cred_pointer != NULL;
cred_pointer = cred_pointer->next)
{
- if(0 != memcmp (&set->subject_key,
+ if(0 != memcmp (&set->subject_key,
&cred_pointer->credential->issuer_key,
sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
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;
strcpy (issuer_attribute_name,
ds_entry->unresolved_attribute_delegation);
char *next_attr = strtok (issuer_attribute_name, ".");
+ if (NULL == next_attr)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to parse next attribute\n");
+ continue;
+ }
GNUNET_asprintf (&lookup_attribute,
"%s.gnu",
next_attr);
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);
return;
}
-}
+}
/**
* Result from GNS lookup.
*
* @param cls the closure (our client lookup handle)
- * @param rd_count the number of records in @a rd
- * @param rd the record data
*/
static void
delegation_chain_resolution_start (void* cls)
continue;
if (0 != strcmp (cr_entry->credential->issuer_attribute, vrh->issuer_attribute))
continue;
+ cr_entry->refcount++;
//Found match prematurely
send_lookup_response (vrh);
return;
}
/**
- * Check for attributes from the issuer and follow the chain
+ * Check for attributes from the issuer and follow the chain
* till you get the required subject's attributes
*/
- char issuer_attribute_name[strlen (vrh->issuer_attribute)];
+ char issuer_attribute_name[strlen (vrh->issuer_attribute) + strlen (".gnu") + 1];
strcpy (issuer_attribute_name,
vrh->issuer_attribute);
strcpy (issuer_attribute_name + strlen (vrh->issuer_attribute),
"Looking up %s\n", issuer_attribute_name);
ds_entry = GNUNET_new (struct DelegationSetQueueEntry);
ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey);
- memcpy (ds_entry->issuer_key,
- &vrh->issuer_key,
- sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+ GNUNET_memcpy (ds_entry->issuer_key,
+ &vrh->issuer_key,
+ sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
ds_entry->issuer_attribute = GNUNET_strdup (vrh->issuer_attribute);
ds_entry->handle = vrh;
ds_entry->lookup_attribute = GNUNET_strdup (vrh->issuer_attribute);
&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)
return GNUNET_OK;
}
-/**
- * Handle Credential verification requests from client
- *
- * @param cls the closure
- * @param client the client
- * @param message the message
- */
static void
handle_verify (void *cls,
- const struct VerifyMessage *v_msg)
+ const struct VerifyMessage *v_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;
+ struct CredentialRecordEntry *cr_entry;
+ uint32_t credentials_count;
+ uint32_t credential_data_size;
+ 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, attr, 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';
vrh = GNUNET_new (struct VerifyRequestHandle);
GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh);
vrh->issuer_key = v_msg->issuer_key;
vrh->subject_key = v_msg->subject_key;
vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
- if (NULL == issuer_attribute)
+ if (0 == strlen (issuer_attribute))
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"No issuer attribute provided!\n");
send_lookup_response (vrh);
return;
* First, collect credentials
* TODO: cleanup!
*/
- uint32_t credentials_count = ntohl(v_msg->c_count);
- int i;
- uint32_t credential_data_size = ntohs (v_msg->header.size)
+ 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];
- char *credential_data = (char*)&v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1;
- struct CredentialRecordEntry *cr_entry;
+ 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,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Cannot deserialize credentials!\n");
send_lookup_response (vrh);
return;
}
- for (i=0;i<credentials_count;i++) {
+ for (uint32_t i=0;i<credentials_count;i++) {
cr_entry = GNUNET_new (struct CredentialRecordEntry);
cr_entry->credential = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) +
- strlen (credentials[i].issuer_attribute) + 1);
+ 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,
- strlen (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,
}
-/**
- * We encountered an error while collecting
- */
static void
handle_cred_collection_error_cb (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);
+ GNUNET_NAMESTORE_zone_iterator_next (vrh->cred_collection_iter,
+ 1);
}
-/**
- * Store credential
- */
+
static void
handle_cred_collection_cb (void *cls,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
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++)
+ for (uint32_t i=0; i < rd_count; i++)
{
if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type)
continue;
vrh);
}
-/**
- * We encountered an error while collecting
- */
static void
handle_cred_collection_finished_cb (void *cls)
{
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)
+ const struct CollectMessage *c_msg)
{
char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
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));
+ 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->subject_key);
vrh->issuer_attribute = GNUNET_strdup (issuer_attribute);
- if (NULL == issuer_attribute)
+ if (0 == strlen (issuer_attribute))
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"No issuer attribute provided!\n");
send_lookup_response (vrh);
return;
}
-/**
- * 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)
}
attr = (const char *) &c_msg[1];
- if ( ('\0' != attr[ntohs(c_msg->header.size) - sizeof (struct CollectMessage) - 1]) ||
+ if ( ('\0' != attr[msg_size - sizeof (struct CollectMessage) - 1]) ||
(strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH) )
{
GNUNET_break (0);
return GNUNET_OK;
}
-/**
- * One of our clients disconnected, clean up after it.
- *
- * @param cls NULL
- * @param client the client that disconnected
- */
static void
client_disconnect_cb (void *cls,
struct GNUNET_SERVICE_Client *client,
client);
}
-/**
- * Add a client to our list of active clients.
- *
- * @param cls NULL
- * @param client client to add
- * @param mq message queue for @a client
- * @return this client
- */
static void *
client_connect_cb (void *cls,
struct GNUNET_SERVICE_Client *client,
* Process Credential requests.
*
* @param cls closure
- * @param server the initialized server
* @param c configuration to use
+ * @param handle service handle
*/
static void
run (void *cls,