From fc76f42d3f8df9fc88648ad052f46c7ddf518879 Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Fri, 6 Oct 2017 10:04:20 +0200 Subject: -add ticket iteration --- .../gnunet-service-identity-provider.c | 10 +- src/identity-provider/identity_provider_api.c | 293 ++++++++++++++++++++- .../plugin_identity_provider_sqlite.c | 23 +- src/include/gnunet_identity_provider_service.h | 99 ++++--- 4 files changed, 371 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c index 3b3af331e..3dcb2792e 100644 --- a/src/identity-provider/gnunet-service-identity-provider.c +++ b/src/identity-provider/gnunet-service-identity-provider.c @@ -1770,11 +1770,7 @@ send_ticket_result (struct IdpClient *client, { struct TicketResultMessage *irm; struct GNUNET_MQ_Envelope *env; - size_t attrs_size; struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket_buf; - char *attrs_buf; - - attrs_size = attribute_list_serialize_get_size (attrs); /* store ticket in DB */ if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls, @@ -1787,15 +1783,11 @@ send_ticket_result (struct IdpClient *client, } env = GNUNET_MQ_msg_extra (irm, - sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket2) + attrs_size, + sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket2), GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT); ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket2 *)&irm[1]; *ticket_buf = *ticket; - attrs_buf = (char*)&ticket_buf[1]; - attribute_list_serialize (attrs, - attrs_buf); irm->id = htonl (r_id); - GNUNET_MQ_send (client->mq, env); } diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c index 371dce86d..6ef1d470e 100644 --- a/src/identity-provider/identity_provider_api.c +++ b/src/identity-provider/identity_provider_api.c @@ -107,6 +107,71 @@ struct GNUNET_IDENTITY_PROVIDER_Operation }; +/** + * Handle for a ticket iterator operation + */ +struct GNUNET_IDENTITY_PROVIDER_TicketIterator +{ + + /** + * Kept in a DLL. + */ + struct GNUNET_IDENTITY_PROVIDER_TicketIterator *next; + + /** + * Kept in a DLL. + */ + struct GNUNET_IDENTITY_PROVIDER_TicketIterator *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_TicketCallback tr_cb; + + /** + * Closure for @e tr_cb. + */ + void *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; + + /** + * The operation id this zone iteration operation has + */ + uint32_t r_id; + +}; + + /** * Handle for a attribute iterator operation */ @@ -217,6 +282,17 @@ struct GNUNET_IDENTITY_PROVIDER_Handle */ struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_tail; + /** + * Head of active iterations + */ + struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it_head; + + /** + * Tail of active iterations + */ + struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it_tail; + + /** * Currently pending transmission request, or NULL for none. */ @@ -747,22 +823,54 @@ handle_ticket_result (void *cls, { struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; struct GNUNET_IDENTITY_PROVIDER_Operation *op; + struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it; const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket; uint32_t r_id = ntohl (msg->id); + size_t msg_len; for (op = handle->op_head; NULL != op; op = op->next) if (op->r_id == r_id) break; - if (NULL == op) + for (it = handle->ticket_it_head; NULL != it; it = it->next) + if (it->r_id == r_id) + break; + if ((NULL == op) && (NULL == it)) return; - GNUNET_CONTAINER_DLL_remove (handle->op_head, - handle->op_tail, - op); - ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket2 *)&msg[1]; - if (NULL != op->tr_cb) - op->tr_cb (op->cls, ticket); - GNUNET_free (op); + msg_len = ntohs (msg->header.size); + if (NULL != op) + { + GNUNET_CONTAINER_DLL_remove (handle->op_head, + handle->op_tail, + op); + if (msg_len == sizeof (struct TicketResultMessage)) + { + if (NULL != op->tr_cb) + op->tr_cb (op->cls, NULL); + } else { + ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket2 *)&msg[1]; + if (NULL != op->tr_cb) + op->tr_cb (op->cls, ticket); + } + GNUNET_free (op); + return; + } else if (NULL != it) { + GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head, + handle->ticket_it_tail, + it); + if (msg_len == sizeof (struct TicketResultMessage)) + { + if (NULL != it->tr_cb) + it->finish_cb (it->finish_cb_cls); + } else { + ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket2 *)&msg[1]; + if (NULL != it->tr_cb) + it->tr_cb (it->cls, ticket); + } + GNUNET_free (it); + return; + } + GNUNET_break (0); } @@ -1353,6 +1461,175 @@ GNUNET_IDENTITY_PROVIDER_rp_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Hand } +/** + * Lists all tickets that have been issued to remote + * identites (relying parties) + * + * @param h the identity provider to use + * @param identity the issuing identity + * @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 ticket; 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_TicketIterator * +GNUNET_IDENTITY_PROVIDER_idp_ticket_iteration_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_TicketCallback proc, + void *proc_cls, + GNUNET_SCHEDULER_TaskCallback finish_cb, + void *finish_cb_cls) +{ + struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it; + struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub; + struct GNUNET_MQ_Envelope *env; + struct TicketIterationStartMessage *msg; + uint32_t rid; + + GNUNET_CRYPTO_ecdsa_key_get_public (identity, + &identity_pub); + rid = h->r_id_gen++; + it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator); + 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->tr_cb = proc; + it->cls = proc_cls; + it->r_id = rid; + GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, + h->ticket_it_tail, + it); + env = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START); + msg->id = htonl (rid); + msg->identity = identity_pub; + msg->is_audience = htonl (GNUNET_NO); + if (NULL == h->mq) + it->env = env; + else + GNUNET_MQ_send (h->mq, + env); + return it; + +} + + +/** + * Lists all tickets that have been issued to remote + * identites (relying parties) + * + * @param id the identity provider to use + * @param identity the issuing identity + * @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 ticket; 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_TicketIterator * +GNUNET_IDENTITY_PROVIDER_ticket_iteration_start_rp (struct GNUNET_IDENTITY_PROVIDER_Handle *h, + const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + GNUNET_SCHEDULER_TaskCallback error_cb, + void *error_cb_cls, + GNUNET_IDENTITY_PROVIDER_TicketCallback proc, + void *proc_cls, + GNUNET_SCHEDULER_TaskCallback finish_cb, + void *finish_cb_cls) +{ + struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it; + struct GNUNET_MQ_Envelope *env; + struct TicketIterationStartMessage *msg; + uint32_t rid; + + rid = h->r_id_gen++; + it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator); + 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->tr_cb = proc; + it->cls = proc_cls; + it->r_id = rid; + GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, + h->ticket_it_tail, + it); + env = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START); + msg->id = htonl (rid); + msg->identity = *identity; + msg->is_audience = htonl (GNUNET_YES); + 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_ticket_iteration_start + * for the next record. + * + * @param it the iterator + */ +void +GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it) +{ + struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h; + struct TicketIterationNextMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_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_ticket_iteration_stop (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it) +{ + struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h; + struct GNUNET_MQ_Envelope *env; + struct TicketIterationStopMessage *msg; + + if (NULL != h->mq) + { + env = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP); + msg->id = htonl (it->r_id); + GNUNET_MQ_send (h->mq, + env); + } + GNUNET_free (it); +} + /* end of identity_provider_api.c */ diff --git a/src/identity-provider/plugin_identity_provider_sqlite.c b/src/identity-provider/plugin_identity_provider_sqlite.c index f31e2e68a..464ea29cb 100644 --- a/src/identity-provider/plugin_identity_provider_sqlite.c +++ b/src/identity-provider/plugin_identity_provider_sqlite.c @@ -376,7 +376,28 @@ identity_provider_sqlite_store_ticket (void *cls, attribute_list_serialize (attrs, attrs_serialized); - { + { + /* First delete duplicates */ + struct GNUNET_SQ_QueryParam dparams[] = { + GNUNET_SQ_query_param_auto_from_type (&ticket->identity), + GNUNET_SQ_query_param_uint64 (&ticket->rnd), + GNUNET_SQ_query_param_end + }; + if (GNUNET_OK != + GNUNET_SQ_bind (plugin->delete_ticket, + dparams)) + { + LOG_SQLITE (plugin, + GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + "sqlite3_bind_XXXX"); + GNUNET_SQ_reset (plugin->dbh, + plugin->delete_ticket); + return GNUNET_SYSERR; + } + n = sqlite3_step (plugin->delete_ticket); + GNUNET_SQ_reset (plugin->dbh, + plugin->delete_ticket); + struct GNUNET_SQ_QueryParam sparams[] = { GNUNET_SQ_query_param_auto_from_type (&ticket->identity), GNUNET_SQ_query_param_auto_from_type (&ticket->audience), diff --git a/src/include/gnunet_identity_provider_service.h b/src/include/gnunet_identity_provider_service.h index 02cd15959..198e2f918 100644 --- a/src/include/gnunet_identity_provider_service.h +++ b/src/include/gnunet_identity_provider_service.h @@ -342,20 +342,6 @@ typedef void (*GNUNET_IDENTITY_PROVIDER_TicketCallback)(void *cls, const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket); -/** - * Method called when issued tickets are retrieved. Also returns the attributes - * that were issued at the time. - * - * @param cls closure - * @param ticket the ticket - * @param attrs the attributes as list - */ -typedef void -(*GNUNET_IDENTITY_PROVIDER_TicketResult)(void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket, - const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs); - - /** * Issues a ticket to another identity. The identity may use * @GNUNET_IDENTITY_PROVIDER_authorization_ticket_consume to consume the ticket @@ -415,37 +401,78 @@ GNUNET_IDENTITY_PROVIDER_rp_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Hand GNUNET_IDENTITY_PROVIDER_AttributeResult cb, void *cb_cls); -/** TODO +/** + * Lists all tickets that have been issued to remote + * identites (relying parties) + * + * @param h the identity provider to use + * @param identity the issuing identity + * @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 ticket; 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_TicketIterator * +GNUNET_IDENTITY_PROVIDER_idp_ticket_iteration_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_TicketCallback proc, + void *proc_cls, + GNUNET_SCHEDULER_TaskCallback finish_cb, + void *finish_cb_cls); + +/** * Lists all tickets that have been issued to remote * identites (relying parties) * * @param id the identity provider to use * @param identity the issuing identity - * @param cb the callback to use - * @param cb_cls the callback closure - * @return handle to abort the operation + * @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 ticket; 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_Operation * -GNUNET_IDENTITY_PROVIDER_idp_tickets_list (struct GNUNET_IDENTITY_PROVIDER_Handle *id, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, - GNUNET_IDENTITY_PROVIDER_TicketCallback *cb, - void *cb_cls); +struct GNUNET_IDENTITY_PROVIDER_TicketIterator * +GNUNET_IDENTITY_PROVIDER_ticket_iteration_start_rp (struct GNUNET_IDENTITY_PROVIDER_Handle *h, + const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + GNUNET_SCHEDULER_TaskCallback error_cb, + void *error_cb_cls, + GNUNET_IDENTITY_PROVIDER_TicketCallback proc, + void *proc_cls, + GNUNET_SCHEDULER_TaskCallback finish_cb, + void *finish_cb_cls); -/** TODO - * Lists all attributes that are shared with this identity - * by remote parties +/** + * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_ticket_iteration_start + * for the next record. * - * @param id identity provider service to use - * @param identity the identity (relying party) - * @param cb the result callback - * @param cb_cls the result callback closure - * @return handle to abort the operation + * @param it the iterator */ -struct GNUNET_IDENTITY_PROVIDER_Operation * -GNUNET_IDENTITY_PROVIDER_rp_attributes_list (struct GNUNET_IDENTITY_PROVIDER_Handle *id, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, - GNUNET_IDENTITY_PROVIDER_AttributeResult *cb, - void *cb_cls); +void +GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *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_ticket_iteration_stop (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it); /** TODO remove DEPRECATED * Issue a token for a specific audience. -- cgit v1.2.3