/*
This file is part of GNUnet.
- Copyright (C) 2016 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2016 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public Liceidentity as published
*/
struct GNUNET_CLIENT_Connection *client;
- /**
- * Function to call when we receive updates.
- */
- GNUNET_IDENTITY_PROVIDER_Callback cb;
-
/**
* Closure for 'cb'.
*/
* Try again to connect to the service.
*
* @param cls handle to the service.
- * @param tc scheduler context
*/
static void
-reconnect (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc);
+reconnect (void *cls);
/**
* @param h transport service to reconnect
*/
static void
-reschedule_connect (struct GNUNET_IDENTITY_Handle *h)
+reschedule_connect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
{
GNUNET_assert (h->reconnect_task == NULL);
struct GNUNET_IDENTITY_PROVIDER_Token token;
struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
const struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm;
- const struct GNUNET_IDENTITY_ExchangeResultMessage *erm;
- struct GNUNET_CRYPTO_EcdsaPublicKey pub;
- struct GNUNET_HashCode id;
- const char *str;
+ const struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *erm;
+ char *str;
+ char *ticket_str;
+ char *token_str;
+ char *label_str;
uint16_t size;
- uint16_t name_len;
+ uint64_t ticket_nonce;
if (NULL == msg)
{
switch (ntohs (msg->type))
{
case GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT:
- if (size < sizeof (struct GNUNET_IDENTITY_IssueResultMessage))
+ if (size < sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage))
{
GNUNET_break (0);
reschedule_connect (h);
return;
}
- irm = (const struct GNUNET_IDENTITY_IssueResultMessage *) msg;
- str = (const char *) &irm[1];
- if ( (size > sizeof (struct GNUNET_IDENTITY_IssueResultMessage)) &&
- ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_IssueResultMessage) - 1]) )
+ irm = (const struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *) msg;
+ str = GNUNET_strdup ((char *) &irm[1]);
+ if ( (size > sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)) &&
+ ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage) - 1]) )
{
+ GNUNET_free (str);
GNUNET_break (0);
reschedule_connect (h);
return;
}
- if (size == sizeof (struct GNUNET_IDENTITY_IssueResultMessage))
+ if (size == sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage))
+ {
+ GNUNET_free (str);
str = NULL;
+ }
+ label_str = strtok (str, ",");
+ if (NULL == label_str)
+ {
+ GNUNET_free (str);
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ ticket_str = strtok (NULL, ",");
+ if (NULL == ticket_str)
+ {
+ GNUNET_free (str);
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
+ token_str = strtok (NULL, ",");
+ if (NULL == token_str)
+ {
+ GNUNET_free (str);
+ GNUNET_break (0);
+ reschedule_connect (h);
+ return;
+ }
op = h->op_head;
GNUNET_CONTAINER_DLL_remove (h->op_head,
h->op_tail,
op);
GNUNET_CLIENT_receive (h->client, &message_handler, h,
GNUNET_TIME_UNIT_FOREVER_REL);
- ticket->data = str;
+ ticket.data = ticket_str;
+ token.data = token_str;
if (NULL != op->iss_cb)
- op->iss_cb (op->cls, &ticket);
+ op->iss_cb (op->cls, label_str, &ticket, &token);
+ GNUNET_free (str);
GNUNET_free (op);
break;
case GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT:
- if (size < sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage))
+ if (size < sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage))
{
GNUNET_break (0);
reschedule_connect (h);
return;
}
- erm = (const struct GNUNET_IDENTITY_ExchangeResultMessage *) msg;
- str = (const char *) &erm[1];
- if ( (size > sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage)) &&
- ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage) - 1]) )
+ erm = (const struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *) msg;
+ str = (char *) &erm[1];
+ if ( (size > sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)) &&
+ ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage) - 1]) )
{
GNUNET_break (0);
reschedule_connect (h);
return;
}
- if (size == sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage))
+ if (size == sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage))
str = NULL;
op = h->op_head;
op);
GNUNET_CLIENT_receive (h->client, &message_handler, h,
GNUNET_TIME_UNIT_FOREVER_REL);
- token->data = str;
+ token.data = str;
+ ticket_nonce = ntohl (erm->ticket_nonce);
if (NULL != op->ex_cb)
- op->ex_cb (op->cls, token);
+ op->ex_cb (op->cls, &token, ticket_nonce);
GNUNET_free (op);
break;
-
+
default:
GNUNET_break (0);
reschedule_connect (h);
"Sending message of type %d to identity provider service\n",
ntohs (op->msg->type));
memcpy (buf, op->msg, ret);
- if ( (NULL == op->cont) &&
- (NULL == op->cb) )
+ if ( (NULL == op->iss_cb) &&
+ (NULL == op->ex_cb) )
{
GNUNET_CONTAINER_DLL_remove (h->op_head,
h->op_tail,
* Try again to connect to the service.
*
* @param cls handle to the identity provider service.
- * @param tc scheduler context
*/
static void
-reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+reconnect (void *cls)
{
- struct GNUNET_IDENTITY_Handle *h = cls;
- struct GNUNET_IDENTITY_Operation *op;
- struct GNUNET_MessageHeader msg;
+ struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
h->reconnect_task = NULL;
LOG (GNUNET_ERROR_TYPE_DEBUG,
GNUNET_assert (NULL == h->client);
h->client = GNUNET_CLIENT_connect ("identity-provider", h->cfg);
GNUNET_assert (NULL != h->client);
- if ( (NULL == h->op_head) ||
- (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_START != ntohs (h->op_head->msg->type)) )
- {
- op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) +
- sizeof (struct GNUNET_MessageHeader));
- op->h = h;
- op->msg = (const struct GNUNET_MessageHeader *) &op[1];
- msg.size = htons (sizeof (msg));
- msg.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_START);
- memcpy (&op[1], &msg, sizeof (msg));
- GNUNET_CONTAINER_DLL_insert (h->op_head,
- h->op_tail,
- op);
- }
transmit_next (h);
GNUNET_assert (NULL != h->th);
}
h = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Handle);
h->cfg = cfg;
- h->cb = cb;
- h->cb_cls = cb_cls;
- h->egos = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES);
h->reconnect_delay = GNUNET_TIME_UNIT_ZERO;
h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, h);
return h;
const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key,
const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
const char* scopes,
- const struct GNUNET_TIME_Absolute exp,
+ struct GNUNET_TIME_Absolute expiration,
+ uint64_t nonce,
GNUNET_IDENTITY_PROVIDER_IssueCallback cb,
void *cb_cls)
{
return NULL;
}
op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) +
- sizeof (struct GNUNET_IDENTITY_IssueMessage) +
+ sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage) +
slen);
op->h = id;
- op->cb = cb;
+ op->iss_cb = cb;
op->cls = cb_cls;
- im = (struct GNUNET_IDENTITY_GetDefaultMessage *) &op[1];
+ im = (struct GNUNET_IDENTITY_PROVIDER_IssueMessage *) &op[1];
im->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE);
im->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage) +
slen);
im->iss_key = *iss_key;
- im->aud_key = *aud_ley;
- im->exp = exp.abs_value_ul;
+ im->aud_key = *aud_key;
+ im->nonce = htonl (nonce);
+ im->expiration = GNUNET_TIME_absolute_hton (expiration);
memcpy (&im[1], scopes, slen);
op->msg = &im->header;
GNUNET_CONTAINER_DLL_insert_tail (id->op_head,
* @return handle to abort the operation
*/
struct GNUNET_IDENTITY_PROVIDER_Operation *
-GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_Handle *id,
- const char *ticket,
- GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont,
- void *cont_cls)
+GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle *id,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *aud_privkey,
+ GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont,
+ void *cont_cls)
{
struct GNUNET_IDENTITY_PROVIDER_Operation *op;
struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *em;
size_t slen;
+ char *ticket_str;
+
+ ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket);
- slen = strlen (ticket) + 1;
- if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_ExchangeMessage))
+ slen = strlen (ticket_str) + 1;
+ if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage))
{
GNUNET_break (0);
return NULL;
}
op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) +
- sizeof (struct GNUNET_IDENTITY_ExchangeMessage) +
- slen);
+ sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage) +
+ slen);
op->h = id;
- op->cont = cont;
+ op->ex_cb = cont;
op->cls = cont_cls;
- em = (struct GNUNET_IDENTITY_ExchangeMessage *) &op[1];
+ em = (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *) &op[1];
em->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE);
- em->header.size = htons (sizeof (struct GNUNET_IDENTITY_ExchangeMessage) +
- slen);
- memcpy (&em[1], ticket, slen);
+ em->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage) +
+ slen);
+ em->aud_privkey = *aud_privkey;
+ memcpy (&em[1], ticket_str, slen);
+ GNUNET_free (ticket_str);
op->msg = &em->header;
GNUNET_CONTAINER_DLL_insert_tail (id->op_head,
- id->op_tail,
- op);
+ id->op_tail,
+ op);
if (NULL == id->th)
transmit_next (id);
return op;
void
GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op)
{
- struct GNUNET_IDENTITY_Handle *h = op->h;
+ struct GNUNET_IDENTITY_PROVIDER_Handle *h = op->h;
if ( (h->op_head != op) ||
(NULL == h->client) )
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Client aborted non-head operation, simply removing it\n");
GNUNET_CONTAINER_DLL_remove (h->op_head,
- h->op_tail,
- op);
+ h->op_tail,
+ op);
GNUNET_free (op);
return;
}
GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
h->th = NULL;
GNUNET_CONTAINER_DLL_remove (h->op_head,
- h->op_tail,
- op);
+ h->op_tail,
+ op);
GNUNET_free (op);
transmit_next (h);
return;
}
while (NULL != (op = h->op_head))
{
- GNUNET_break (NULL == op->cont);
GNUNET_CONTAINER_DLL_remove (h->op_head,
- h->op_tail,
- op);
+ h->op_tail,
+ op);
GNUNET_free (op);
}
if (NULL != h->client)
GNUNET_free (h);
}
+/**
+ * Convenience API
+ */
+
+
+/**
+ * Destroy token
+ *
+ * @param token the token
+ */
+void
+GNUNET_IDENTITY_PROVIDER_token_destroy(struct GNUNET_IDENTITY_PROVIDER_Token *token)
+{
+ GNUNET_assert (NULL != token);
+ if (NULL != token->data)
+ GNUNET_free (token->data);
+ GNUNET_free (token);
+}
+
+/**
+ * Returns string representation of token. A JSON-Web-Token.
+ *
+ * @param token the token
+ * @return The JWT (must be freed)
+ */
+char *
+GNUNET_IDENTITY_PROVIDER_token_to_string (const struct GNUNET_IDENTITY_PROVIDER_Token *token)
+{
+ return GNUNET_strdup (token->data);
+}
+
+/**
+ * Returns string representation of ticket. Base64-Encoded
+ *
+ * @param ticket the ticket
+ * @return the Base64-Encoded ticket
+ */
+char *
+GNUNET_IDENTITY_PROVIDER_ticket_to_string (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
+{
+ return GNUNET_strdup (ticket->data);
+}
+
+/**
+ * Created a ticket from a string (Base64 encoded ticket)
+ *
+ * @param input Base64 encoded ticket
+ * @param ticket pointer where the ticket is stored
+ * @return GNUNET_OK
+ */
+int
+GNUNET_IDENTITY_PROVIDER_string_to_ticket (const char* input,
+ struct GNUNET_IDENTITY_PROVIDER_Ticket **ticket)
+{
+ *ticket = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
+ (*ticket)->data = GNUNET_strdup (input);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Destroys a ticket
+ *
+ * @param ticket the ticket to destroy
+ */
+void
+GNUNET_IDENTITY_PROVIDER_ticket_destroy(struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
+{
+ GNUNET_assert (NULL != ticket);
+ if (NULL != ticket->data)
+ GNUNET_free (ticket->data);
+ GNUNET_free (ticket);
+}
+
+
+
+
+
/* end of identity_provider_api.c */