- fix warnings
[oweals/gnunet.git] / src / identity-provider / identity_provider_api.c
index c22151534cdcf6cff27c793e079e5c94b698dac2..f3280cb18a8ae393f03c9cfdb63e76dfcb01542c 100644 (file)
@@ -1,6 +1,6 @@
 /*
      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
@@ -96,11 +96,6 @@ struct GNUNET_IDENTITY_PROVIDER_Handle
    */
   struct GNUNET_CLIENT_Connection *client;
 
-  /**
-   * Function to call when we receive updates.
-   */
-  GNUNET_IDENTITY_PROVIDER_Callback cb;
-
   /**
    * Closure for 'cb'.
    */
@@ -143,11 +138,9 @@ struct GNUNET_IDENTITY_PROVIDER_Handle
  * 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);
 
 
 /**
@@ -156,7 +149,7 @@ 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);
 
@@ -196,12 +189,13 @@ message_handler (void *cls,
   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)
   {
@@ -215,52 +209,82 @@ message_handler (void *cls,
   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;
@@ -269,12 +293,13 @@ message_handler (void *cls,
                                 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);
@@ -322,8 +347,8 @@ send_next_message (void *cls,
        "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,
@@ -370,14 +395,11 @@ transmit_next (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
  * 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,
@@ -385,20 +407,6 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   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);
 }
@@ -417,9 +425,6 @@ GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
 
   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;
@@ -440,7 +445,8 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id
                     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)
 {
@@ -455,18 +461,19 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id
     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,
@@ -488,36 +495,42 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id
  * @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;
@@ -535,7 +548,7 @@ GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_Handle *id,
 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) )
@@ -544,8 +557,8 @@ GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op)
     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;
   }
@@ -557,8 +570,8 @@ GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op)
     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;
@@ -594,10 +607,9 @@ GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
   }
   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)
@@ -608,4 +620,82 @@ GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
   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 */