gnunet_service_identity_provider_SOURCES = \
gnunet-service-identity-provider.c \
- identity_token.c
+ identity_token.c \
+ identity_attribute.h
gnunet_service_identity_provider_LDADD = \
$(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/identity/libgnunetidentity.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/credential/libgnunetcredential.la \
+ $(top_builddir)/src/identity-provider/libgnunetidentityprovider.la \
$(top_builddir)/src/gns/libgnunetgns.la \
$(GN_LIBINTL) \
-ljansson
libgnunetidentityprovider_la_SOURCES = \
identity_provider_api.c \
- identity_provider.h
+ identity_provider.h \
+ identity_attribute.c
libgnunetidentityprovider_la_LIBADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(GN_LIBINTL) $(XLIB)
static struct GNUNET_NAMESTORE_Handle *namestore_handle;
/**
- * Namestore iterator
+ * Attribute iterator
*/
-static struct GNUNET_NAMESTORE_ZoneIterator *ns_iterator;
+static struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *attr_iterator;
/**
* Namestore queue
{
if (NULL != ns_qe)
GNUNET_NAMESTORE_cancel (ns_qe);
- if (NULL != ns_iterator)
- GNUNET_NAMESTORE_zone_iteration_stop (ns_iterator);
+ if (NULL != attr_iterator)
+ GNUNET_IDENTITY_PROVIDER_get_attributes_stop (attr_iterator);
+ if (NULL != idp_handle)
+ GNUNET_IDENTITY_PROVIDER_disconnect (idp_handle);
if (NULL != namestore_handle)
GNUNET_NAMESTORE_disconnect (namestore_handle);
if (NULL != identity_handle)
static void
iter_error (void *cls)
{
- ns_iterator = NULL;
+ attr_iterator = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to iterate over attributes\n");
GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
static void
iter_finished (void *cls)
{
- ns_iterator = NULL;
+ attr_iterator = NULL;
GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
}
static void
iter_cb (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
- const char *label,
- unsigned int rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr)
{
- struct GNUNET_CRYPTO_AbeKey *key;
- int i;
- char *attr_value;
- char* attrs[2];
- for (i=0;i<rd_count;i++) {
- if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd[i].record_type)
- continue;
- attrs[0] = (char*)label;
- attrs[1] = 0;
- key = GNUNET_CRYPTO_cpabe_create_key (abe_key,
- attrs);
- GNUNET_CRYPTO_cpabe_decrypt (rd[i].data,
- rd[i].data_size,
- key,
- (void**)&attr_value);
- GNUNET_CRYPTO_cpabe_delete_key (key);
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- "%s: %s\n", label, attr_value);
- }
- GNUNET_NAMESTORE_zone_iterator_next (ns_iterator);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "%s: %s\n", attr->name, (char*)attr->data);
+ GNUNET_IDENTITY_PROVIDER_get_attributes_next (attr_iterator);
}
static void
}
if (list) {
- ns_iterator = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle,
- zone,
- &iter_error,
- NULL,
- &iter_cb,
- NULL,
- &iter_finished,
- NULL);
+ attr_iterator = GNUNET_IDENTITY_PROVIDER_get_attributes_start (idp_handle,
+ zone,
+ &iter_error,
+ NULL,
+ &iter_cb,
+ NULL,
+ &iter_finished,
+ NULL);
return;
}
- struct GNUNET_IDENTITY_PROVIDER_Attribute *attr;
- attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Attribute) + strlen (attr_value) + 1);
- attr->attribute_type = GNUNET_IDENTITY_PROVIDER_AT_STRING;
- attr->data = &attr[1];
- attr->data_size = strlen (attr_value) + 1;
+ struct GNUNET_IDENTITY_PROVIDER_Attribute *attr = GNUNET_IDENTITY_PROVIDER_attribute_new (attr_name,
+ GNUNET_IDENTITY_PROVIDER_AT_STRING,
+ attr_value,
+ strlen (attr_value));
idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (idp_handle,
zone,
- attr_name,
attr,
&store_attr_cont,
NULL);
#include "gnunet_signatures.h"
#include "identity_provider.h"
#include "identity_token.h"
+#include "identity_attribute.h"
#include <inttypes.h>
/**
*/
static const struct GNUNET_CONFIGURATION_Handle *cfg;
+/**
+ * An idp client
+ */
+struct IdpClient;
+
+/**
+ * Callback after an ABE bootstrap
+ *
+ * @param cls closure
+ * @param abe_key the ABE key that exists or was created
+ */
+typedef void
+(*AbeBootstrapResult) (void *cls,
+ struct GNUNET_CRYPTO_AbeMasterKey *abe_key);
+
+
+struct AbeBootstrapHandle
+{
+ /**
+ * Function to call when finished
+ */
+ AbeBootstrapResult proc;
+
+ /**
+ * Callback closure
+ */
+ char *proc_cls;
+
+ /**
+ * Key of the zone we are iterating over.
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * Namestore Queue Entry
+ */
+ struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+ /**
+ * The issuer egos ABE master key
+ */
+ struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
+};
+
+/**
+ * An attribute iteration operation.
+ */
+struct AttributeIterator
+{
+ /**
+ * Next element in the DLL
+ */
+ struct AttributeIterator *next;
+
+ /**
+ * Previous element in the DLL
+ */
+ struct AttributeIterator *prev;
+
+ /**
+ * IDP client which intiated this zone iteration
+ */
+ struct IdpClient *client;
+
+ /**
+ * Key of the zone we are iterating over.
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * The issuer egos ABE master key
+ */
+ struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
+
+ /**
+ * Namestore iterator
+ */
+ struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
+
+ /**
+ * The operation id fot the zone iteration in the response for the client
+ */
+ uint32_t request_id;
+
+};
+
+
+
+/**
+ * An idp client
+ */
+struct IdpClient
+{
+
+ /**
+ * The client
+ */
+ struct GNUNET_SERVICE_Client *client;
+
+ /**
+ * Message queue for transmission to @e client
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * Head of the DLL of
+ * Attribute iteration operations in
+ * progress initiated by this client
+ */
+ struct AttributeIterator *op_head;
+
+ /**
+ * Tail of the DLL of
+ * Attribute iteration operations
+ * in progress initiated by this client
+ */
+ struct AttributeIterator *op_tail;
+};
+
+
+
struct AttributeStoreHandle
{
/**
* Client connection
*/
- struct GNUNET_SERVICE_Client *client;
+ struct IdpClient *client;
/**
* Identity
struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
/**
- * The attribute name
+ * The attribute to store
*/
- char *name;
-
- /**
- * The attribute value
- */
- char *attribute_value;
-
- /**
- * Size of the attribute value
- */
- size_t attribute_value_len;
+ struct GNUNET_IDENTITY_PROVIDER_Attribute *attribute;
/**
* request id
/**
* Client connection
*/
- struct GNUNET_SERVICE_Client *client;
+ struct IdpClient *client;
/**
* Ticket
/**
* Client connection
*/
- struct GNUNET_SERVICE_Client *client;
+ struct IdpClient *client;
/**
* Issuer Key
ticket_str,
token_str,
handle->r_id);
- GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(handle->client),
+ GNUNET_MQ_send (handle->client->mq,
env);
cleanup_issue_handle (handle);
GNUNET_free (ticket_str);
handle->label,
handle->ticket->payload->nonce,
handle->r_id);
- GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(handle->client),
+ GNUNET_MQ_send (handle->client->mq,
env);
cleanup_exchange_handle (handle);
GNUNET_free (token_str);
const struct ExchangeMessage *xm)
{
struct ExchangeHandle *xchange_handle;
- struct GNUNET_SERVICE_Client *client = cls;
+ struct IdpClient *idp = cls;
const char *ticket;
char *lookup_query;
&xchange_handle->ticket))
{
GNUNET_free (xchange_handle);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (idp->client);
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for ABE key under %s\n",
GNUNET_asprintf (&lookup_query,
"%s.gnu",
xchange_handle->ticket->payload->label);
- GNUNET_SERVICE_client_continue (client);
- xchange_handle->client = client;
+ GNUNET_SERVICE_client_continue (idp->client);
+ xchange_handle->client = idp;
xchange_handle->token = token_create (&xchange_handle->ticket->payload->identity_key,
&xchange_handle->ticket->payload->identity_key);
xchange_handle->lookup_request
uint64_t rnd_key;
struct GNUNET_HashCode key;
struct IssueHandle *issue_handle;
- struct GNUNET_SERVICE_Client *client = cls;
+ struct IdpClient *idp = cls;
scopes = (const char *) &im[1];
//v_attrs = (const char *) &im[1] + ntohl(im->scope_len);
&issue_handle->iss_pkey);
issue_handle->expiration = GNUNET_TIME_absolute_ntoh (im->expiration);
issue_handle->nonce = ntohl (im->nonce);
- GNUNET_SERVICE_client_continue (client);
- issue_handle->client = client;
+ GNUNET_SERVICE_client_continue (idp->client);
+ issue_handle->client = idp;
issue_handle->scopes = GNUNET_strdup (scopes);
issue_handle->token = token_create (&issue_handle->iss_pkey,
&issue_handle->aud_key);
static void
cleanup_as_handle (struct AttributeStoreHandle *handle)
{
- if (NULL != handle->name)
- GNUNET_free (handle->name);
- if (NULL != handle->attribute_value)
- GNUNET_free (handle->attribute_value);
+ if (NULL != handle->attribute)
+ GNUNET_free (handle->attribute);
+ if (NULL != handle->abe_key)
+ GNUNET_free (handle->abe_key);
GNUNET_free (handle);
}
GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
acr_msg->id = htonl (as_handle->r_id);
acr_msg->op_result = htonl (GNUNET_OK);
- GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(as_handle->client),
+ GNUNET_MQ_send (as_handle->client->mq,
env);
cleanup_as_handle (as_handle);
}
-void
+static void
attr_store_task (void *cls)
{
struct AttributeStoreHandle *as_handle = cls;
struct GNUNET_GNSRECORD_Data rd[1];
+ char* buf;
+ size_t buf_size;
+
+ buf_size = attribute_serialize_get_size (as_handle->attribute);
+ buf = GNUNET_malloc (buf_size);
+
+ attribute_serialize (as_handle->attribute,
+ buf);
/**
* Encrypt the attribute value and store in namestore
*/
- rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (as_handle->attribute_value,
- as_handle->attribute_value_len,
- as_handle->name, //Policy
+ rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
+ buf_size,
+ as_handle->attribute->name, //Policy
as_handle->abe_key,
(void**)&rd[0].data);
+ GNUNET_free (buf);
rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
- rd[0].flags = GNUNET_GNSRECORD_RF_NONE;
+ rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
&as_handle->identity,
- as_handle->name,
+ as_handle->attribute->name,
1,
rd,
&attr_store_cont,
as_handle);
+ GNUNET_free ((void*)rd[0].data);
}
-void
-store_bootstrap_cont (void *cls,
+static void
+bootstrap_store_cont (void *cls,
int32_t success,
const char *emsg)
{
+ struct AbeBootstrapHandle *abh = cls;
if (GNUNET_SYSERR == success)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to bootstrap ABE master %s\n",
emsg);
- GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ abh->proc (abh->proc_cls, NULL);
+ GNUNET_free (abh->abe_key);
+ GNUNET_free (abh);
return;
}
- GNUNET_SCHEDULER_add_now (&attr_store_task, cls);
+ abh->proc (abh->proc_cls, abh->abe_key);
+ GNUNET_free (abh);
}
-void
-store_bootstrap_task (void *cls)
+static void
+bootstrap_store_task (void *cls)
{
- struct AttributeStoreHandle *as_handle = cls;
+ struct AbeBootstrapHandle *abh = cls;
struct GNUNET_GNSRECORD_Data rd[1];
- rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (as_handle->abe_key,
+ rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key,
(void**)&rd[0].data);
rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
rd[0].flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_PRIVATE;
rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
- as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
- &as_handle->identity,
- "+",
- 1,
- rd,
- &store_bootstrap_cont,
- as_handle);
+ abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
+ &abh->identity,
+ "+",
+ 1,
+ rd,
+ &bootstrap_store_cont,
+ abh);
}
-void
-store_cont_abe_error (void *cls)
+static void
+bootstrap_abe_error (void *cls)
{
- GNUNET_SCHEDULER_add_now (&do_shutdown, cls);
+ struct AbeBootstrapHandle *abh = cls;
+ GNUNET_free (abh);
+ abh->proc (abh->proc_cls, NULL);
+ GNUNET_free (abh);
}
-void
-store_cont_abe_result (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
- const char *label,
- unsigned int rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
+
+
+static void
+bootstrap_abe_result (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const char *label,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
{
- struct AttributeStoreHandle *handle = cls;
+ struct AbeBootstrapHandle *abh = cls;
+ struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
int i;
for (i=0;i<rd_count;i++) {
if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
continue;
- handle->abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
- rd[i].data_size);
- GNUNET_SCHEDULER_add_now (&attr_collect_task, handle);
+ abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
+ rd[i].data_size);
+ abh->proc (abh->proc_cls, abe_key);
+ GNUNET_free (abh);
return;
}
//No ABE master found, bootstrapping...
- handle->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
- GNUNET_SCHEDULER_add_now (&store_bootstrap_task, handle);
+ abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
+ GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
+}
+
+static void
+bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ AbeBootstrapResult proc,
+ void* cls)
+{
+ struct AbeBootstrapHandle *abh;
+
+ abh = GNUNET_new (struct AbeBootstrapHandle);
+ abh->proc = proc;
+ abh->proc_cls = cls;
+ abh->identity = *identity;
+ abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
+ identity,
+ "+",
+ &bootstrap_abe_error,
+ abh,
+ &bootstrap_abe_result,
+ abh);
+
}
+static void
+store_after_abe_bootstrap (void *cls,
+ struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
+{
+ struct AttributeStoreHandle *ash = cls;
+ ash->abe_key = abe_key;
+ GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
+}
/**
* Checks a store message
const struct AttributeStoreMessage *sam)
{
uint16_t size;
- uint32_t name_len;
size = ntohs (sam->header.size);
if (size <= sizeof (struct AttributeStoreMessage))
GNUNET_break (0);
return GNUNET_SYSERR;
}
- name_len = ntohs (sam->name_len);
- if (0 <= name_len)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Malformed store message received!\n");
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
return GNUNET_OK;
}
+
/**
*
* Handler for store message
const struct AttributeStoreMessage *sam)
{
struct AttributeStoreHandle *as_handle;
- struct GNUNET_SERVICE_Client *client = cls;
- size_t name_len;
+ struct IdpClient *idp = cls;
size_t data_len;
- char *attribute_value;
- name_len = ntohs (sam->name_len);
- data_len = ntohs (sam->attr_value_len);
+ data_len = ntohs (sam->attr_len);
as_handle = GNUNET_new (struct AttributeStoreHandle);
- as_handle->name = GNUNET_strndup ((char*)&sam[1], name_len);
- attribute_value = (char*)&sam[1] + name_len;
+ as_handle->attribute = attribute_deserialize ((char*)&sam[1],
+ data_len);
as_handle->r_id = sam->id;
as_handle->identity = sam->identity;
GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
&as_handle->identity_pkey);
- as_handle->attribute_value = GNUNET_malloc (data_len);
- GNUNET_memcpy (as_handle->attribute_value,
- attribute_value,
- data_len);
- as_handle->attribute_value_len = data_len;
-
- GNUNET_SERVICE_client_continue (client);
- as_handle->client = client;
- as_handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
- &as_handle->identity,
- "+",
- &store_cont_abe_error,
- as_handle,
- &store_cont_abe_result,
- as_handle);
+
+ GNUNET_SERVICE_client_continue (idp->client);
+ as_handle->client = idp;
+
+ bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle);
+}
+
+static void
+cleanup_iter_handle (struct AttributeIterator *ai)
+{
+ if (NULL != ai->abe_key)
+ GNUNET_free (ai->abe_key);
+ GNUNET_free (ai);
+}
+
+static void
+attr_iter_error (void *cls)
+{
+ //struct AttributeIterator *ai = cls;
+ //TODO
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to iterate over attributes\n");
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+}
+
+static void
+attr_iter_finished (void *cls)
+{
+ struct AttributeIterator *ai = cls;
+ struct GNUNET_MQ_Envelope *env;
+ struct AttributeResultMessage *arm;
+
+ env = GNUNET_MQ_msg (arm,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
+ arm->id = htonl (ai->request_id);
+ arm->attr_len = htons (0);
+ GNUNET_MQ_send (ai->client->mq, env);
+ cleanup_iter_handle (ai);
+}
+
+static void
+attr_iter_cb (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const char *label,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+ struct AttributeIterator *ai = cls;
+ struct AttributeResultMessage *arm;
+ struct GNUNET_CRYPTO_AbeKey *key;
+ struct GNUNET_MQ_Envelope *env;
+ ssize_t msg_extra_len;
+ char* attr_ser;
+ char* attrs[2];
+ char* data_tmp;
+
+ if (rd_count != 1)
+ {
+ GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
+ return;
+ }
+
+ if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
+ GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
+ return;
+ }
+ attrs[0] = (char*)label;
+ attrs[1] = 0;
+ key = GNUNET_CRYPTO_cpabe_create_key (ai->abe_key,
+ attrs);
+ msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
+ rd->data_size,
+ key,
+ (void**)&attr_ser);
+ GNUNET_CRYPTO_cpabe_delete_key (key);
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Found attribute: %s\n", label);
+ env = GNUNET_MQ_msg_extra (arm,
+ msg_extra_len,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
+ arm->id = htonl (ai->request_id);
+ arm->attr_len = htons (msg_extra_len);
+ arm->identity = *zone;
+ data_tmp = (char *) &arm[1];
+ GNUNET_memcpy (data_tmp,
+ attr_ser,
+ msg_extra_len);
+ GNUNET_MQ_send (ai->client->mq, env);
+ GNUNET_free (attr_ser);
+}
+
+
+void
+iterate_after_abe_bootstrap (void *cls,
+ struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
+{
+ struct AttributeIterator *ai = cls;
+ ai->abe_key = abe_key;
+ ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
+ &ai->identity,
+ &attr_iter_error,
+ ai,
+ &attr_iter_cb,
+ ai,
+ &attr_iter_finished,
+ ai);
+}
+
+
+/**
+ * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_START message
+ *
+ * @param cls the client sending the message
+ * @param zis_msg message from the client
+ */
+static void
+handle_iteration_start (void *cls,
+ const struct AttributeIterationStartMessage *ais_msg)
+{
+ struct IdpClient *idp = cls;
+ struct AttributeIterator *ai;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received ATTRIBUTE_ITERATION_START message\n");
+ ai = GNUNET_new (struct AttributeIterator);
+ ai->request_id = ntohl (ais_msg->id);
+ ai->client = idp;
+ ai->identity = ais_msg->identity;
+
+ GNUNET_CONTAINER_DLL_insert (idp->op_head,
+ idp->op_tail,
+ ai);
+ bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai);
+ GNUNET_SERVICE_client_continue (idp->client);
}
+/**
+ * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_STOP message
+ *
+ * @param cls the client sending the message
+ * @param ais_msg message from the client
+ */
+static void
+handle_iteration_stop (void *cls,
+ const struct AttributeIterationStopMessage *ais_msg)
+{
+ struct IdpClient *idp = cls;
+ struct AttributeIterator *ai;
+ uint32_t rid;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' message\n",
+ "ATTRIBUTE_ITERATION_STOP");
+ rid = ntohl (ais_msg->id);
+ for (ai = idp->op_head; NULL != ai; ai = ai->next)
+ if (ai->request_id == rid)
+ break;
+ if (NULL == ai)
+ {
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (idp->client);
+ return;
+ }
+ GNUNET_CONTAINER_DLL_remove (idp->op_head,
+ idp->op_tail,
+ ai);
+ GNUNET_free (ai);
+ GNUNET_SERVICE_client_continue (idp->client);
+}
+
+
+/**
+ * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT message
+ *
+ * @param cls the client sending the message
+ * @param message message from the client
+ */
+static void
+handle_iteration_next (void *cls,
+ const struct AttributeIterationNextMessage *ais_msg)
+{
+ struct IdpClient *idp = cls;
+ struct AttributeIterator *ai;
+ uint32_t rid;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received ATTRIBUTE_ITERATION_NEXT message\n");
+ rid = ntohl (ais_msg->id);
+ for (ai = idp->op_head; NULL != ai; ai = ai->next)
+ if (ai->request_id == rid)
+ break;
+ if (NULL == ai)
+ {
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (idp->client);
+ return;
+ }
+ GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
+ GNUNET_SERVICE_client_continue (idp->client);
+}
+
+
+
+
/**
* Main function that will be run
*
struct GNUNET_SERVICE_Client *client,
void *app_ctx)
{
+ struct IdpClient *idp = app_ctx;
+ struct AttributeIterator *ai;
+
+ //TODO other operations
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Client %p disconnected\n",
client);
+
+ while (NULL != (ai = idp->op_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (idp->op_head,
+ idp->op_tail,
+ ai);
+ GNUNET_free (ai);
+ }
+ GNUNET_free (idp);
}
struct GNUNET_SERVICE_Client *client,
struct GNUNET_MQ_Handle *mq)
{
+ struct IdpClient *idp;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Client %p connected\n",
client);
- return client;
+ idp = GNUNET_new (struct IdpClient);
+ idp->client = client;
+ idp->mq = mq;
+ return idp;
}
GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
struct AttributeStoreMessage,
NULL),
+ GNUNET_MQ_hd_fixed_size (iteration_start,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
+ struct AttributeIterationStartMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (iteration_next,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
+ struct AttributeIterationNextMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (iteration_stop,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
+ struct AttributeIterationStopMessage,
+ NULL),
GNUNET_MQ_handler_end());
/* end of gnunet-service-identity-provider.c */
--- /dev/null
+/*
+ This file is part of GNUnet
+ Copyright (C) 2010-2015 GNUnet e.V.
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file identity-provider/identity_attribute.c
+ * @brief helper library to manage identity attributes
+ * @author Martin Schanzenbach
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "identity_attribute.h"
+
+/**
+ * Create a new attribute.
+ *
+ * @param name the attribute name
+ * @param type the attribute type
+ * @param data the attribute value
+ * @param data_size the attribute value size
+ * @return the new attribute
+ */
+struct GNUNET_IDENTITY_PROVIDER_Attribute *
+attribute_new (const char* attr_name,
+ uint32_t attr_type,
+ const void* data,
+ size_t data_size)
+{
+ struct GNUNET_IDENTITY_PROVIDER_Attribute *attr;
+ char *write_ptr;
+
+ attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Attribute) +
+ strlen (attr_name) + 1 +
+ data_size);
+ attr->attribute_type = attr_type;
+ attr->data_size = data_size;
+ write_ptr = (char*)&attr[1];
+ GNUNET_memcpy (write_ptr,
+ attr_name,
+ strlen (attr_name) + 1);
+ attr->name = write_ptr;
+ write_ptr += strlen (attr->name) + 1;
+ GNUNET_memcpy (write_ptr,
+ data,
+ data_size);
+ attr->data = write_ptr;
+ return attr;
+}
+
+
+
+size_t
+attribute_serialize_get_size (const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr)
+{
+ return sizeof (struct Attribute)
+ + strlen (attr->name) + 1
+ + attr->data_size; //TODO get data_size from plugin
+}
+
+int
+attribute_serialize (const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr,
+ char *result)
+{
+ size_t data_len_ser;
+ size_t name_len;
+ struct Attribute *attr_ser;
+ char* write_ptr;
+
+ attr_ser = (struct Attribute*)result;
+ attr_ser->attribute_type = htons (attr->attribute_type);
+ name_len = strlen (attr->name);
+ attr_ser->name_len = htons (name_len);
+ write_ptr = (char*)&attr_ser[1];
+ GNUNET_memcpy (write_ptr, attr->name, name_len);
+ write_ptr += name_len;
+ //TODO plugin-ize
+ //data_len_ser = plugin->serialize_attribute_value (attr,
+ // &attr_ser[1]);
+ data_len_ser = attr->data_size;
+ GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
+ attr_ser->data_size = htons (data_len_ser);
+
+ return GNUNET_OK;
+}
+
+struct GNUNET_IDENTITY_PROVIDER_Attribute *
+attribute_deserialize (const char* data,
+ size_t data_size)
+{
+ struct GNUNET_IDENTITY_PROVIDER_Attribute *attr;
+ struct Attribute *attr_ser;
+ size_t data_len;
+ size_t name_len;
+ char* write_ptr;
+
+ if (data_size < sizeof (struct Attribute))
+ return NULL;
+
+ attr_ser = (struct Attribute*)data;
+ //TODO use plugin.
+ data_len = ntohs (attr_ser->data_size);
+ name_len = ntohs (attr_ser->name_len);
+ attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Attribute)
+ + data_len + name_len + 1);
+ attr->attribute_type = ntohs (attr_ser->attribute_type);
+ attr->data_size = ntohs (attr_ser->data_size);
+
+ write_ptr = (char*)&attr[1];
+ GNUNET_memcpy (write_ptr,
+ &attr_ser[1],
+ name_len);
+ write_ptr[name_len] = '\0';
+ attr->name = write_ptr;
+
+ write_ptr += name_len + 1;
+ GNUNET_memcpy (write_ptr,
+ (char*)&attr_ser[1] + name_len,
+ attr->data_size);
+ attr->data = write_ptr;
+ return attr;
+
+}
+
+/* end of identity_attribute.c */
--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2012-2015 GNUnet e.V.
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+/**
+ * @author Martin Schanzenbach
+ * @file identity-provider/identity_attribute.h
+ * @brief GNUnet Identity Provider library
+ *
+ */
+#ifndef IDENTITY_ATTRIBUTE_H
+#define IDENTITY_ATTRIBUTE_H
+
+#include "gnunet_identity_provider_service.h"
+
+struct Attribute
+{
+ /**
+ * Attribute type
+ */
+ uint32_t attribute_type;
+
+ /**
+ * Name length
+ */
+ uint32_t name_len;
+
+ /**
+ * Data size
+ */
+ uint32_t data_size;
+
+ //followed by data_size Attribute value data
+};
+
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the attribute to serialize
+ *
+ * @return the required buffer size
+ */
+size_t
+attribute_serialize_get_size (const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr);
+
+
+
+/**
+ * Serialize an attribute
+ *
+ * @param attr the attribute to serialize
+ * @param result the serialized attribute
+ *
+ * @return GNUNET_OK on success
+ */
+int
+attribute_serialize (const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr,
+ char *result);
+
+/**
+ * Deserialize an attribute
+ *
+ * @param data the serialized attribute
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_IDENTITY_PROVIDER_Attribute *
+attribute_deserialize (const char* data,
+ size_t data_size);
+
+/**
+ * Create a new attribute.
+ *
+ * @param name the attribute name
+ * @param type the attribute type
+ * @param data the attribute value
+ * @param data_size the attribute value size
+ * @return the new attribute
+ */
+struct GNUNET_IDENTITY_PROVIDER_Attribute *
+attribute_new (const char* attr_name,
+ uint32_t attr_type,
+ const void* data,
+ size_t data_size);
+
+
+#endif
uint32_t id GNUNET_PACKED;
/**
- * The attribute type
+ * The length of the attribute
*/
- uint32_t attribute_type GNUNET_PACKED;
-
- /**
- * The length of the attribute name
- */
- uint32_t name_len GNUNET_PACKED;
-
- /**
- * The length of the attribute value
- */
- uint32_t attr_value_len GNUNET_PACKED;
+ uint32_t attr_len GNUNET_PACKED;
/**
* Identity
*/
struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
- /* followed by the name of attribute as string and value data */
+ /* followed by the serialized attribute */
};
};
+/**
+ * Attribute is returned from the idp.
+ */
+struct AttributeResultMessage
+{
+ /**
+ * Message header
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Unique identifier for this request (for key collisions).
+ */
+ uint32_t id GNUNET_PACKED;
+
+ /**
+ * Length of serialized attribute data
+ */
+ uint16_t attr_len GNUNET_PACKED;
+
+ /**
+ * always zero (for alignment)
+ */
+ uint16_t reserved GNUNET_PACKED;
+
+ /**
+ * The private key of the identity.
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /* followed by:
+ * serialized attribute data
+ */
+};
+
+
+/**
+ * Start a attribute iteration for the given identity
+ */
+struct AttributeIterationStartMessage
+{
+ /**
+ * Message
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Unique identifier for this request (for key collisions).
+ */
+ uint32_t id GNUNET_PACKED;
+
+ /**
+ * Identity.
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+};
+
+
+/**
+ * Ask for next result of attribute iteration for the given operation
+ */
+struct AttributeIterationNextMessage
+{
+ /**
+ * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Unique identifier for this request (for key collisions).
+ */
+ uint32_t id GNUNET_PACKED;
+
+};
+
+
+/**
+ * Stop attribute iteration for the given operation
+ */
+struct AttributeIterationStopMessage
+{
+ /**
+ * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Unique identifier for this request (for key collisions).
+ */
+ uint32_t id GNUNET_PACKED;
+
+};
+
+
GNUNET_NETWORK_STRUCT_END
#endif
#include "gnunet_mq_lib.h"
#include "gnunet_identity_provider_service.h"
#include "identity_provider.h"
+#include "identity_attribute.h"
#define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__)
};
+/**
+ * Handle for a attribute iterator operation
+ */
+struct GNUNET_IDENTITY_PROVIDER_AttributeIterator
+{
+
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *prev;
+
+ /**
+ * Main handle to access the idp.
+ */
+ struct GNUNET_IDENTITY_PROVIDER_Handle *h;
+
+ /**
+ * Function to call on completion.
+ */
+ GNUNET_SCHEDULER_TaskCallback finish_cb;
+
+ /**
+ * Closure for @e error_cb.
+ */
+ void *finish_cb_cls;
+
+ /**
+ * The continuation to call with the results
+ */
+ GNUNET_IDENTITY_PROVIDER_AttributeResult proc;
+
+ /**
+ * Closure for @e proc.
+ */
+ void *proc_cls;
+
+ /**
+ * Function to call on errors.
+ */
+ GNUNET_SCHEDULER_TaskCallback error_cb;
+
+ /**
+ * Closure for @e error_cb.
+ */
+ void *error_cb_cls;
+
+ /**
+ * Envelope of the message to send to the service, if not yet
+ * sent.
+ */
+ struct GNUNET_MQ_Envelope *env;
+
+ /**
+ * Private key of the zone.
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * The operation id this zone iteration operation has
+ */
+ uint32_t r_id;
+
+};
+
/**
* Handle for the service.
*/
struct GNUNET_IDENTITY_PROVIDER_Operation *op_tail;
+ /**
+ * Head of active iterations
+ */
+ struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_head;
+
+ /**
+ * Tail of active iterations
+ */
+ struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_tail;
+
/**
* Currently pending transmission request, or NULL for none.
*/
handle);
}
+/**
+ * Free @a it.
+ *
+ * @param it entry to free
+ */
+static void
+free_it (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
+{
+ struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
+
+ GNUNET_CONTAINER_DLL_remove (h->it_head,
+ h->it_tail,
+ it);
+ if (NULL != it->env)
+ GNUNET_MQ_discard (it->env);
+ GNUNET_free (it);
+}
+
+
+
/**
* Generic error handler, called with the appropriate error code and
* the same closure specified at the creation of the message queue.
}
+/**
+ * Handle an incoming message of type
+ * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
+ *
+ * @param cls
+ * @param msg the message we received
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+static int
+check_attribute_result (void *cls,
+ const struct AttributeResultMessage *msg)
+{
+ size_t msg_len;
+ size_t attr_len;
+
+ msg_len = ntohs (msg->header.size);
+ attr_len = ntohs (msg->attr_len);
+ if (msg_len != sizeof (struct AttributeResultMessage) + attr_len)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Handle an incoming message of type
+ * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT
+ *
+ * @param cls
+ * @param msg the message we received
+ */
+static void
+handle_attribute_result (void *cls,
+ const struct AttributeResultMessage *msg)
+{
+ static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
+ struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
+ struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
+ size_t attr_len;
+ uint32_t r_id = ntohl (msg->id);
+
+ attr_len = ntohs (msg->attr_len);
+
+ for (it = h->it_head; NULL != it; it = it->next)
+ if (it->r_id == r_id)
+ break;
+ if (NULL == it)
+ return;
+
+ if ( (0 == (memcmp (&msg->identity,
+ &identity_dummy,
+ sizeof (identity_dummy)))) )
+ {
+ if (NULL == it)
+ {
+ GNUNET_break (0);
+ force_reconnect (h);
+ return;
+ }
+ if (NULL != it->finish_cb)
+ it->finish_cb (it->finish_cb_cls);
+ free_it (it);
+ return;
+ }
+
+ {
+ struct GNUNET_IDENTITY_PROVIDER_Attribute *attr;
+ attr = attribute_deserialize ((char*)&msg[1],
+ attr_len);
+ if (NULL != it)
+ {
+ if (NULL != it->proc)
+ it->proc (it->proc_cls,
+ &msg->identity,
+ attr);
+ GNUNET_free (attr);
+ return;
+ }
+ }
+ GNUNET_assert (0);
+}
+
+
/**
* Try again to connect to the service.
GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT,
struct ExchangeResultMessage,
h),
-
+ GNUNET_MQ_hd_var_size (attribute_result,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT,
+ struct AttributeResultMessage,
+ h),
GNUNET_MQ_handler_end ()
};
struct GNUNET_IDENTITY_PROVIDER_Operation *op;
struct GNUNET_IDENTITY_PROVIDER_Operation *
GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
- const char* name,
- const struct GNUNET_IDENTITY_PROVIDER_Attribute *value,
+ const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr,
GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont,
void *cont_cls)
{
struct GNUNET_IDENTITY_PROVIDER_Operation *op;
struct AttributeStoreMessage *sam;
- size_t name_len;
- char *name_tmp;
- char *attr_ser;
+ size_t attr_len;
-
- name_len = strlen (name) + 1;
- if (name_len >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct AttributeStoreMessage))
- {
- GNUNET_break (0);
- return NULL;
- }
op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
op->h = h;
op->as_cb = cont;
GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
h->op_tail,
op);
+ attr_len = attribute_serialize_get_size (attr);
op->env = GNUNET_MQ_msg_extra (sam,
- name_len + value->data_size,
+ attr_len,
GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE);
sam->identity = *pkey;
sam->id = htonl (op->r_id);
- sam->attr_value_len = htons (value->data_size);
- sam->name_len = htons (name_len);
- name_tmp = (char *) &sam[1];
- GNUNET_memcpy (name_tmp, name, name_len);
- attr_ser = &name_tmp[name_len];
- GNUNET_memcpy (attr_ser, value->data, value->data_size);
+
+ attribute_serialize (attr,
+ (char*)&sam[1]);
+
+ sam->attr_len = htons (attr_len);
if (NULL != h->mq)
GNUNET_MQ_send_copy (h->mq,
op->env);
}
+/**
+ * Create a new attribute.
+ *
+ * @param name the attribute name
+ * @param type the attribute type
+ * @param data the attribute value
+ * @param data_size the attribute value size
+ * @return the new attribute
+ */
+struct GNUNET_IDENTITY_PROVIDER_Attribute *
+GNUNET_IDENTITY_PROVIDER_attribute_new (const char* attr_name,
+ uint32_t attr_type,
+ const void* data,
+ size_t data_size)
+{
+ return attribute_new (attr_name, attr_type, data, data_size);
+}
+
+/**
+ * List all attributes for a local identity.
+ * This MUST lock the `struct GNUNET_IDENTITY_PROVIDER_Handle`
+ * for any other calls than #GNUNET_IDENTITY_PROVIDER_get_attributes_next() and
+ * #GNUNET_IDENTITY_PROVIDER_get_attributes_stop. @a proc will be called once
+ * immediately, and then again after
+ * #GNUNET_IDENTITY_PROVIDER_get_attributes_next() is invoked.
+ *
+ * On error (disconnect), @a error_cb will be invoked.
+ * On normal completion, @a finish_cb proc will be
+ * invoked.
+ *
+ * @param h handle to the idp
+ * @param identity identity to access
+ * @param error_cb function to call on error (i.e. disconnect),
+ * the handle is afterwards invalid
+ * @param error_cb_cls closure for @a error_cb
+ * @param proc function to call on each attribute; it
+ * will be called repeatedly with a value (if available)
+ * @param proc_cls closure for @a proc
+ * @param finish_cb function to call on completion
+ * the handle is afterwards invalid
+ * @param finish_cb_cls closure for @a finish_cb
+ * @return an iterator handle to use for iteration
+ */
+struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *
+GNUNET_IDENTITY_PROVIDER_get_attributes_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ GNUNET_SCHEDULER_TaskCallback error_cb,
+ void *error_cb_cls,
+ GNUNET_IDENTITY_PROVIDER_AttributeResult proc,
+ void *proc_cls,
+ GNUNET_SCHEDULER_TaskCallback finish_cb,
+ void *finish_cb_cls)
+{
+ struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it;
+ struct GNUNET_MQ_Envelope *env;
+ struct AttributeIterationStartMessage *msg;
+ uint32_t rid;
+
+ rid = h->r_id_gen++;
+ it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator);
+ it->h = h;
+ it->error_cb = error_cb;
+ it->error_cb_cls = error_cb_cls;
+ it->finish_cb = finish_cb;
+ it->finish_cb_cls = finish_cb_cls;
+ it->proc = proc;
+ it->proc_cls = proc_cls;
+ it->r_id = rid;
+ it->identity = *identity;
+ GNUNET_CONTAINER_DLL_insert_tail (h->it_head,
+ h->it_tail,
+ it);
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START);
+ msg->id = htonl (rid);
+ msg->identity = *identity;
+ if (NULL == h->mq)
+ it->env = env;
+ else
+ GNUNET_MQ_send (h->mq,
+ env);
+ return it;
+}
+
+
+/**
+ * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_get_attributes_start
+ * for the next record.
+ *
+ * @param it the iterator
+ */
+void
+GNUNET_IDENTITY_PROVIDER_get_attributes_next (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
+{
+ struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
+ struct AttributeIterationNextMessage *msg;
+ struct GNUNET_MQ_Envelope *env;
+
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT);
+ msg->id = htonl (it->r_id);
+ GNUNET_MQ_send (h->mq,
+ env);
+}
+
+
+/**
+ * Stops iteration and releases the idp handle for further calls. Must
+ * be called on any iteration that has not yet completed prior to calling
+ * #GNUNET_IDENTITY_PROVIDER_disconnect.
+ *
+ * @param it the iterator
+ */
+void
+GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it)
+{
+ struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h;
+ struct GNUNET_MQ_Envelope *env;
+ struct AttributeIterationStopMessage *msg;
+
+ if (NULL != h->mq)
+ {
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP);
+ msg->id = htonl (it->r_id);
+ GNUNET_MQ_send (h->mq,
+ env);
+ }
+ free_it (it);
+}
+
+
-/* end of identity_provider_api.c */
+ /* end of identity_provider_api.c */
case GNUNET_GNSRECORD_TYPE_ID_ATTR:
case GNUNET_GNSRECORD_TYPE_ID_TOKEN:
return GNUNET_strndup (data, data_size);
+ case GNUNET_GNSRECORD_TYPE_ABE_KEY:
+ case GNUNET_GNSRECORD_TYPE_ABE_MASTER:
+ return GNUNET_STRINGS_data_to_string_alloc (data, data_size);
case GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA:
ecdhe_privkey = data;
audience_pubkey = data+sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey);
*data = GNUNET_strdup (s);
*data_size = strlen (s);
return GNUNET_OK;
+ case GNUNET_GNSRECORD_TYPE_ABE_KEY:
+ case GNUNET_GNSRECORD_TYPE_ABE_MASTER:
+ return GNUNET_STRINGS_string_to_data (s,
+ strlen (s),
+ *data,
+ *data_size);
case GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA:
- tmp_tok = GNUNET_strdup (s);
+ tmp_tok = GNUNET_strdup (s);
ecdhe_str = strtok (tmp_tok, ";");
if (NULL == ecdhe_str)
{
* Mapping of record type numbers to human-readable
* record type names.
*/
- static struct {
- const char *name;
- uint32_t number;
- } name_map[] = {
- { "ID_ATTR", GNUNET_GNSRECORD_TYPE_ID_ATTR },
- { "ID_TOKEN", GNUNET_GNSRECORD_TYPE_ID_TOKEN },
- { "ID_TOKEN_METADATA", GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA },
- { NULL, UINT32_MAX }
- };
+static struct {
+ const char *name;
+ uint32_t number;
+} name_map[] = {
+ { "ID_ATTR", GNUNET_GNSRECORD_TYPE_ID_ATTR },
+ { "ID_TOKEN", GNUNET_GNSRECORD_TYPE_ID_TOKEN },
+ { "ID_TOKEN_METADATA", GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA },
+ { NULL, UINT32_MAX }
+};
/**
gnunet-identity -C testego -c test_idp.conf
gnunet-idp -e testego --init -c test_idp.conf
gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf
+gnunet-idp -e testego -a name -V John -c test_idp.conf
gnunet-idp -e testego -D -c test_idp.conf
gnunet-arm -e -c test_idp.conf
ssize_t
GNUNET_CRYPTO_cpabe_encrypt (const void *block,
size_t size,
- char *policy,
+ const char *policy,
const struct GNUNET_CRYPTO_AbeMasterKey *key,
void **result);
{
/**
- * Binary value stored as attribute value. Note: "data" must never
- * be individually 'malloc'ed, but instead always points into some
- * existing data area.
+ * Type of Attribute.
*/
- const void *data;
+ uint32_t attribute_type;
/**
* Number of bytes in @e data.
size_t data_size;
/**
- * Type of Attribute.
+ * The name of the attribute. Note "name" must never be individually
+ * free'd
*/
- uint32_t attribute_type;
+ const char* name;
+
+ /**
+ * Binary value stored as attribute value. Note: "data" must never
+ * be individually 'malloc'ed, but instead always points into some
+ * existing data area.
+ */
+ const void *data;
};
*
* @param h handle to the identity provider
* @param pkey private key of the identity
- * @param name the attribute name
- * @param value the attribute value
+ * @param attr the attribute
* @param cont continuation to call when done
* @param cont_cls closure for @a cont
* @return handle to abort the request
struct GNUNET_IDENTITY_PROVIDER_Operation *
GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
- const char* name,
- const struct GNUNET_IDENTITY_PROVIDER_Attribute *value,
+ const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr,
GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont,
void *cont_cls);
+/**
+ * Create a new attribute.
+ *
+ * @param name the attribute name
+ * @param type the attribute type
+ * @param data the attribute value
+ * @param data_size the attribute value size
+ * @return the new attribute
+ */
+struct GNUNET_IDENTITY_PROVIDER_Attribute *
+GNUNET_IDENTITY_PROVIDER_attribute_new (const char* attr_name,
+ uint32_t attr_type,
+ const void* data,
+ size_t data_size);
+
+/**
+ * Process an attribute that was stored in the idp.
+ *
+ * @param cls closure
+ * @param attr the attribute
+ */
+typedef void
+(*GNUNET_IDENTITY_PROVIDER_AttributeResult) (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr);
+
+
+
+/**
+ * List all attributes for a local identity.
+ * This MUST lock the `struct GNUNET_IDENTITY_PROVIDER_Handle`
+ * for any other calls than #GNUNET_IDENTITY_PROVIDER_get_attributes_next() and
+ * #GNUNET_IDENTITY_PROVIDER_get_attributes_stop. @a proc will be called once
+ * immediately, and then again after
+ * #GNUNET_IDENTITY_PROVIDER_get_attributes_next() is invoked.
+ *
+ * On error (disconnect), @a error_cb will be invoked.
+ * On normal completion, @a finish_cb proc will be
+ * invoked.
+ *
+ * @param h handle to the idp
+ * @param identity identity to access
+ * @param error_cb function to call on error (i.e. disconnect),
+ * the handle is afterwards invalid
+ * @param error_cb_cls closure for @a error_cb
+ * @param proc function to call on each attribute; it
+ * will be called repeatedly with a value (if available)
+ * @param proc_cls closure for @a proc
+ * @param finish_cb function to call on completion
+ * the handle is afterwards invalid
+ * @param finish_cb_cls closure for @a finish_cb
+ * @return an iterator handle to use for iteration
+ */
+struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *
+GNUNET_IDENTITY_PROVIDER_get_attributes_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ GNUNET_SCHEDULER_TaskCallback error_cb,
+ void *error_cb_cls,
+ GNUNET_IDENTITY_PROVIDER_AttributeResult proc,
+ void *proc_cls,
+ GNUNET_SCHEDULER_TaskCallback finish_cb,
+ void *finish_cb_cls);
+
+
+/**
+ * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_get_attributes_start
+ * for the next record.
+ *
+ * @param it the iterator
+ */
+void
+GNUNET_IDENTITY_PROVIDER_get_attributes_next (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it);
+
+
+/**
+ * Stops iteration and releases the idp handle for further calls. Must
+ * be called on any iteration that has not yet completed prior to calling
+ * #GNUNET_IDENTITY_PROVIDER_disconnect.
+ *
+ * @param it the iterator
+ */
+void
+GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it);
+
/**
#define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE 966
+#define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START 967
+
+#define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP 968
+
+#define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT 969
+
+#define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT 970
/**************************************************
*
char **attrs)
{
struct GNUNET_CRYPTO_AbeKey *prv_key;
- prv_key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
int size;
char *tmp;
ssize_t
GNUNET_CRYPTO_cpabe_encrypt (const void *block,
size_t size,
- char *policy,
+ const char *policy,
const struct GNUNET_CRYPTO_AbeMasterKey *key,
void **result)
{
int aes_buf_len;
ssize_t result_len;
- if( !(cph = gabe_enc(key->pub, m, policy)) )
+ if( !(cph = gabe_enc(key->pub, m, (char*)policy)) )
return GNUNET_SYSERR;
cph_buf_len = gabe_cph_serialize(cph,
&cph_buf);