*/
static char* revoke_ticket;
+/**
+ * Ticket listing
+ */
+static int list_tickets;
+
/**
* Ego name
*/
*/
static struct GNUNET_RECLAIM_AttributeIterator *attr_iterator;
+/**
+ * Ticket iterator
+ */
+static struct GNUNET_RECLAIM_TicketIterator *ticket_iterator;
+
/**
* Master ABE key
*/
GNUNET_RECLAIM_cancel (reclaim_op);
if (NULL != attr_iterator)
GNUNET_RECLAIM_get_attributes_stop (attr_iterator);
+ if (NULL != ticket_iterator)
+ GNUNET_RECLAIM_ticket_iteration_stop (ticket_iterator);
if (NULL != reclaim_handle)
GNUNET_RECLAIM_disconnect (reclaim_handle);
if (NULL != identity_handle)
attr->name, value_str, attr_type, attr->version, attr->id);
}
+static void
+ticket_iter_err (void *cls)
+{
+ ticket_iterator = NULL;
+ fprintf (stderr,
+ "Failed to iterate over tickets\n");
+ cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
+}
+
+static void
+ticket_iter_fin (void *cls)
+{
+ ticket_iterator = NULL;
+ cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
+}
+
+static void
+ticket_iter (void *cls,
+ const struct GNUNET_RECLAIM_Ticket *ticket)
+{
+ fprintf (stdout,
+ "Found ticket\n");
+ GNUNET_RECLAIM_ticket_iteration_next (ticket_iterator);
+}
static void
iter_error (void *cls)
}
static void
-start_get_attributes ()
+start_process ()
{
if (NULL == pkey)
{
return;
}
+ if (list_tickets)
+ {
+ ticket_iterator = GNUNET_RECLAIM_ticket_iteration_start (reclaim_handle,
+ pkey,
+ &ticket_iter_err,
+ NULL,
+ &ticket_iter,
+ NULL,
+ &ticket_iter_fin,
+ NULL);
+ return;
+ }
+
if (NULL != rp)
GNUNET_CRYPTO_ecdsa_public_key_from_string (rp,
strlen (rp),
if (NULL == name) {
if (GNUNET_YES == init) {
init = GNUNET_NO;
- start_get_attributes();
+ start_process ();
}
return;
}
"TYPE",
gettext_noop ("Type of attribute"),
&type_str),
+ GNUNET_GETOPT_option_flag ('T',
+ "tickets",
+ gettext_noop ("List tickets of ego"),
+ &list_tickets),
GNUNET_GETOPT_option_relative_time ('E',
"expiration",
"INTERVAL",
*/
struct IdpClient *client;
- /**
- * Key of the identity we are iterating over.
- */
- struct GNUNET_CRYPTO_EcdsaPublicKey identity;
-
- /**
- * Identity is audience
- */
- uint32_t is_audience;
-
/**
* The operation id fot the iteration in the response for the client
*/
uint32_t r_id;
/**
- * Offset of the iteration used to address next result of the
- * iteration in the store
- *
- * Initialy set to 0 in handle_iteration_start
- * Incremented with by every call to handle_iteration_next
+ * The ticket iterator
*/
- uint32_t offset;
-
+ struct RECLAIM_TICKETS_Iterator *iter;
};
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Cleaning up\n");
+ RECLAIM_TICKETS_deinit ();
if (NULL != stats)
{
GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
GNUNET_SERVICE_client_continue (idp->client);
}
-/**
- * Ticket iteration processor result
- */
-enum ZoneIterationResult
-{
- /**
- * Iteration start.
- */
- IT_START = 0,
-
- /**
- * Found tickets,
- * Continue to iterate with next iteration_next call
- */
- IT_SUCCESS_MORE_AVAILABLE = 1,
-
- /**
- * Iteration complete
- */
- IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
-};
-
-
-/**
- * Context for ticket iteration
- */
-struct TicketIterationProcResult
-{
- /**
- * The ticket iteration handle
- */
- struct TicketIteration *ti;
-
- /**
- * Iteration result: iteration done?
- * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
- * we got one for now and have sent it to the client
- * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
- * #IT_START: if we are still trying to find a result.
- */
- int res_iteration_finished;
-
-};
-
static void
-cleanup_ticket_iter_handle (struct TicketIteration *ti)
+ticket_iter_cb (void *cls,
+ struct GNUNET_RECLAIM_Ticket *ticket)
{
- GNUNET_free (ti);
-}
-
-/**
- * Process ticket from database
- *
- * @param cls struct TicketIterationProcResult
- * @param ticket the ticket
- * @param attrs the attributes
- */
-static void
-ticket_iterate_proc (void *cls,
- const struct GNUNET_RECLAIM_Ticket *ticket,
- const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
-{
- struct TicketIterationProcResult *proc = cls;
-
- if (NULL == ticket)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Iteration done\n");
- proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
- return;
- }
- proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
- send_ticket_result (proc->ti->client,
- proc->ti->r_id,
- ticket,
- GNUNET_OK);
-
-}
-
-/**
- * Perform ticket iteration step
- *
- * @param ti ticket iterator to process
- */
-static void
-run_ticket_iteration_round (struct TicketIteration *ti)
-{
- struct TicketIterationProcResult proc;
+ struct TicketIteration *ti = cls;
struct GNUNET_MQ_Envelope *env;
struct TicketResultMessage *trm;
- int ret;
- memset (&proc, 0, sizeof (proc));
- proc.ti = ti;
- proc.res_iteration_finished = IT_START;
- while (IT_START == proc.res_iteration_finished)
- {
- if (GNUNET_SYSERR ==
- (ret = TKT_database->iterate_tickets (TKT_database->cls,
- &ti->identity,
- ti->is_audience,
- ti->offset,
- &ticket_iterate_proc,
- &proc)))
- {
- GNUNET_break (0);
- break;
- }
- if (GNUNET_NO == ret)
- proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
- ti->offset++;
- }
- if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
+ if (NULL == ticket)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "More results available\n");
- return; /* more later */
+ /* send empty response to indicate end of list */
+ env = GNUNET_MQ_msg (trm,
+ GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
+ GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
+ ti->client->ticket_iter_tail,
+ ti);
+ } else {
+ env = GNUNET_MQ_msg_extra (trm,
+ sizeof (struct GNUNET_RECLAIM_Ticket),
+ GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
}
- /* send empty response to indicate end of list */
- env = GNUNET_MQ_msg (trm,
- GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
trm->id = htonl (ti->r_id);
GNUNET_MQ_send (ti->client->mq,
env);
- GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
- ti->client->ticket_iter_tail,
- ti);
- cleanup_ticket_iter_handle (ti);
+ if (NULL == ticket)
+ GNUNET_free (ti);
}
static void
"Received TICKET_ITERATION_START message\n");
ti = GNUNET_new (struct TicketIteration);
ti->r_id = ntohl (tis_msg->id);
- ti->offset = 0;
ti->client = client;
- ti->identity = tis_msg->identity;
- ti->is_audience = ntohl (tis_msg->is_audience);
GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
client->ticket_iter_tail,
ti);
- run_ticket_iteration_round (ti);
+ ti->iter = RECLAIM_TICKETS_iteration_start (&tis_msg->identity,
+ &ticket_iter_cb,
+ ti);
GNUNET_SERVICE_client_continue (client->client);
}
GNUNET_SERVICE_client_drop (client->client);
return;
}
+ RECLAIM_TICKETS_iteration_stop (ti->iter);
GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
client->ticket_iter_tail,
ti);
- cleanup_ticket_iter_handle (ti);
+ GNUNET_free (ti);
GNUNET_SERVICE_client_continue (client->client);
}
GNUNET_SERVICE_client_drop (client->client);
return;
}
- run_ticket_iteration_round (ti);
+ RECLAIM_TICKETS_iteration_next (ti->iter);
GNUNET_SERVICE_client_continue (client->client);
}
GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
idp->ticket_iter_tail,
ti);
- cleanup_ticket_iter_handle (ti);
+ GNUNET_free (ti);
}
GNUNET_free (idp);
}
};
+/**
+ * Ticket iterator
+ */
+struct RECLAIM_TICKETS_Iterator
+{
+ /**
+ * Issuer Key
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * Issuer pubkey
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
+
+ /**
+ * Namestore queue entry
+ */
+ struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+ /**
+ * Iter callback
+ */
+ RECLAIM_TICKETS_TicketIter cb;
+
+ /**
+ * Iter cls
+ */
+ void *cb_cls;
+
+ /**
+ * Ticket reference list
+ */
+ struct TicketReference *tickets_head;
+
+ /**
+ * Ticket reference list
+ */
+ struct TicketReference *tickets_tail;
+};
+
static struct GNUNET_NAMESTORE_Handle *nsh;
/**
}
+static void
+cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter)
+{
+ struct TicketReference *tr;
+ struct TicketReference *tr_tmp;
+ if (NULL != iter->ns_qe)
+ GNUNET_NAMESTORE_cancel (iter->ns_qe);
+ for (tr = iter->tickets_head; NULL != tr;)
+ {
+ if (NULL != tr->attrs)
+ GNUNET_RECLAIM_ATTRIBUTE_list_destroy (tr->attrs);
+ tr_tmp = tr;
+ tr = tr->next;
+ GNUNET_free (tr_tmp);
+ }
+ GNUNET_free (iter);
+}
+
+static void
+do_cleanup_iter (void* cls)
+{
+ struct RECLAIM_TICKETS_Iterator *iter = cls;
+ cleanup_iter (iter);
+}
+
+/**
+ * Perform ticket iteration step
+ *
+ * @param ti ticket iterator to process
+ */
+static void
+run_ticket_iteration_round (struct RECLAIM_TICKETS_Iterator *iter)
+{
+ struct TicketReference *tr;
+ if (NULL == iter->tickets_head)
+ {
+ //No more tickets
+ iter->cb (iter->cb_cls,
+ NULL);
+ GNUNET_SCHEDULER_add_now (&do_cleanup_iter, iter);
+ return;
+ }
+ tr = iter->tickets_head;
+ GNUNET_CONTAINER_DLL_remove (iter->tickets_head,
+ iter->tickets_tail,
+ tr);
+ iter->cb (iter->cb_cls,
+ &tr->ticket);
+ if (NULL != tr->attrs)
+ GNUNET_RECLAIM_ATTRIBUTE_list_destroy (tr->attrs);
+ GNUNET_free (tr);
+}
+
+static void
+collect_tickets_cb (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const char *label,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+ struct RECLAIM_TICKETS_Iterator *iter = cls;
+ struct TicketReference *tr;
+ size_t attr_data_len;
+ const char* attr_data;
+ iter->ns_qe = NULL;
+
+ for (int i = 0; i < rd_count; i++)
+ {
+ if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF != rd[i].record_type)
+ continue;
+ tr = GNUNET_new (struct TicketReference);
+ memcpy (&tr->ticket, rd[i].data,
+ sizeof (struct GNUNET_RECLAIM_Ticket));
+ if (0 != memcmp (&tr->ticket.identity,
+ &iter->identity_pub,
+ sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
+ {
+ //Not our ticket
+ GNUNET_free (tr);
+ continue;
+ }
+ attr_data = rd[i].data + sizeof (struct GNUNET_RECLAIM_Ticket);
+ attr_data_len = rd[i].data_size - sizeof (struct GNUNET_RECLAIM_Ticket);
+ tr->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attr_data,
+ attr_data_len);
+ GNUNET_CONTAINER_DLL_insert (iter->tickets_head,
+ iter->tickets_tail,
+ tr);
+ }
+ run_ticket_iteration_round (iter);
+}
+
+static void
+collect_tickets_error_cb (void *cls)
+{
+ struct RECLAIM_TICKETS_Iterator *iter = cls;
+ iter->ns_qe = NULL;
+ iter->cb (iter->cb_cls,
+ NULL);
+ cleanup_iter (iter);
+}
+
+void
+RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter)
+{
+ run_ticket_iteration_round (iter);
+}
+
+void
+RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter)
+{
+ cleanup_iter (iter);
+}
+
+struct RECLAIM_TICKETS_Iterator*
+RECLAIM_TICKETS_iteration_start (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ RECLAIM_TICKETS_TicketIter cb,
+ void* cb_cls)
+{
+ struct RECLAIM_TICKETS_Iterator *iter;
+
+ iter = GNUNET_new (struct RECLAIM_TICKETS_Iterator);
+ iter->identity = *identity;
+ GNUNET_CRYPTO_ecdsa_key_get_public (identity,
+ &iter->identity_pub);
+ iter->cb = cb;
+ iter->cb_cls = cb_cls;
+ iter->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
+ identity,
+ GNUNET_GNS_EMPTY_LABEL_AT,
+ &collect_tickets_error_cb,
+ iter,
+ &collect_tickets_cb,
+ iter);
+ return iter;
+}
+
+
+
+
int
RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
{
}
return GNUNET_OK;
}
+
+void
+RECLAIM_TICKETS_deinit (void)
+{
+ if (NULL != nsh)
+ GNUNET_NAMESTORE_disconnect (nsh);
+ nsh = NULL;
+}
#include "gnunet_signatures.h"
#include "reclaim.h"
+struct RECLAIM_TICKETS_Iterator;
+
+/**
+ * Continuation called with ticket.
+ *
+ * @param cls closure
+ * @param ticket the ticket
+ */
+typedef void
+(*RECLAIM_TICKETS_TicketIter) (void *cls,
+ struct GNUNET_RECLAIM_Ticket *ticket);
+
+
/**
* Continuation called with ticket.
*
RECLAIM_TICKETS_TicketResult cb,
void* cb_cls);
+void
+RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter);
+
+
+void
+RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter);
+
+
+struct RECLAIM_TICKETS_Iterator*
+RECLAIM_TICKETS_iteration_start (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ RECLAIM_TICKETS_TicketIter cb,
+ void* cb_cls);
+
+
int
RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c);
+
+void
+RECLAIM_TICKETS_deinit (void);
+
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
* Message header
*/
struct GNUNET_MessageHeader header;
-
+
/**
* Unique identifier for this request (for key collisions).
*/
/**
* Identity.
*/
- struct GNUNET_CRYPTO_EcdsaPublicKey identity;
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
- /**
- * Identity is audience or issuer
- */
- uint32_t is_audience GNUNET_PACKED;
};
void *proc_cls,
GNUNET_SCHEDULER_TaskCallback finish_cb,
void *finish_cb_cls)
-{
- struct GNUNET_RECLAIM_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_RECLAIM_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_RECLAIM_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 h the reclaim 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_RECLAIM_TicketIterator *
-GNUNET_RECLAIM_ticket_iteration_start_rp (struct GNUNET_RECLAIM_Handle *h,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
- GNUNET_SCHEDULER_TaskCallback error_cb,
- void *error_cb_cls,
- GNUNET_RECLAIM_TicketCallback proc,
- void *proc_cls,
- GNUNET_SCHEDULER_TaskCallback finish_cb,
- void *finish_cb_cls)
{
struct GNUNET_RECLAIM_TicketIterator *it;
struct GNUNET_MQ_Envelope *env;
GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
msg->id = htonl (rid);
msg->identity = *identity;
- msg->is_audience = htonl (GNUNET_YES);
if (NULL == h->mq)
it->env = env;
else
env);
return it;
-
}
+
/**
* Calls the record processor specified in #GNUNET_RECLAIM_ticket_iteration_start
* for the next record.