- merge with master
[oweals/gnunet.git] / src / identity-provider / plugin_rest_identity_provider.c
index c0b018798e6d2630bc8f46c9b35313bfadf460ed..5ea7b28219f97903f1407f9f8ca6ada23114cb75 100644 (file)
  */
 #define GNUNET_IDENTITY_TOKEN_ATTR_LIST "requested_attrs"
 
+/**
+ * Attributes passed to issue request
+ */
+#define GNUNET_IDENTITY_TOKEN_V_ATTR_LIST "requested_verified_attrs"
+
+
 /**
  * Token expiration string
  */
@@ -460,6 +466,7 @@ issue_token_cont (struct GNUNET_REST_RequestHandle *con,
   char *exp_str;
   char *nonce_str;
   char *scopes;
+  char *vattrs;
   uint64_t time;
   uint64_t nonce;
 
@@ -536,6 +543,21 @@ issue_token_cont (struct GNUNET_REST_RequestHandle *con,
   scopes = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
                                               &key);
 
+  //vattrs
+  GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_V_ATTR_LIST,
+                      strlen (GNUNET_IDENTITY_TOKEN_V_ATTR_LIST),
+                      &key);
+
+  vattrs = NULL;
+  if ( GNUNET_YES ==
+       GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
+                                               &key) )
+  {
+    vattrs = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
+                                                &key);
+  }
+
+
 
   //Token audience
   GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST,
@@ -547,15 +569,15 @@ issue_token_cont (struct GNUNET_REST_RequestHandle *con,
                                                &key) )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-               "Audience missing!\n");
+                "Audience missing!\n");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
   audience = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
                                                 &key);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Audience to issue token for: %s\n",
-             audience);
+              "Audience to issue token for: %s\n",
+              audience);
 
   priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
   GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
@@ -580,9 +602,10 @@ issue_token_cont (struct GNUNET_REST_RequestHandle *con,
   }
   nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
                                                  &key);
+  GNUNET_assert (NULL != nonce_str);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Request nonce: %s\n",
-             nonce_str);
+              "Request nonce: %s\n",
+              nonce_str);
   GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &nonce));
 
   //Get expiration for token from URL parameter
@@ -619,6 +642,7 @@ issue_token_cont (struct GNUNET_REST_RequestHandle *con,
                                                          priv_key,
                                                          &aud_key,
                                                          scopes,
+                                                         vattrs,
                                                          exp_time,
                                                          nonce,
                                                          &token_creat_cont,
@@ -647,6 +671,16 @@ return_token_list (void *cls)
   cleanup_handle (handle);
 }
 
+
+static void
+token_collect_error_cb (void *cls)
+{
+  struct RequestHandle *handle = cls;
+
+  do_error (handle);
+}
+
+
 /**
  * Collect all tokens for an ego
  *
@@ -658,45 +692,68 @@ token_collect (void *cls,
                const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
                const char *label,
                unsigned int rd_count,
-               const struct GNUNET_GNSRECORD_Data *rd)
+               const struct GNUNET_GNSRECORD_Data *rd);
+
+
+static void
+token_collect_finished_cb (void *cls)
 {
-  int i;
-  char* data;
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_tmp;
-  struct GNUNET_JSONAPI_Resource *json_resource;
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
-  json_t *issuer;
-  json_t *token;
-
-  if (NULL == label)
-  {
-    ego_tmp = handle->ego_head;
-    GNUNET_CONTAINER_DLL_remove (handle->ego_head,
-                                 handle->ego_tail,
-                                 ego_tmp);
-    GNUNET_free (ego_tmp->identifier);
-    GNUNET_free (ego_tmp->keystring);
-    GNUNET_free (ego_tmp);
 
-    if (NULL == handle->ego_head)
-    {
-      //Done
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token END\n");
-      handle->ns_it = NULL;
-      GNUNET_SCHEDULER_add_now (&return_token_list, handle);
-      return;
-    }
+  ego_tmp = handle->ego_head;
+  GNUNET_CONTAINER_DLL_remove (handle->ego_head,
+                               handle->ego_tail,
+                               ego_tmp);
+  GNUNET_free (ego_tmp->identifier);
+  GNUNET_free (ego_tmp->keystring);
+  GNUNET_free (ego_tmp);
 
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Next ego: %s\n", handle->ego_head->identifier);
-    priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego);
-    handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
-                                                           priv_key,
-                                                           &token_collect,
-                                                           handle);
+  if (NULL == handle->ego_head)
+  {
+    //Done
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token END\n");
+    handle->ns_it = NULL;
+    GNUNET_SCHEDULER_add_now (&return_token_list, handle);
     return;
   }
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Next ego: %s\n",
+              handle->ego_head->identifier);
+  priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego);
+  handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
+                                                         priv_key,
+                                                         &token_collect_error_cb,
+                                                         handle,
+                                                         &token_collect,
+                                                         handle,
+                                                         &token_collect_finished_cb,
+                                                         handle);
+}
+
+
+/**
+ * Collect all tokens for an ego
+ *
+ * TODO move this into the identity-provider service
+ *
+ */
+static void
+token_collect (void *cls,
+               const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+               const char *label,
+               unsigned int rd_count,
+               const struct GNUNET_GNSRECORD_Data *rd)
+{
+  struct RequestHandle *handle = cls;
+  int i;
+  char* data;
+  struct GNUNET_JSONAPI_Resource *json_resource;
+  json_t *issuer;
+  json_t *token;
+
   for (i = 0; i < rd_count; i++)
   {
     if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN)
@@ -706,16 +763,16 @@ token_collect (void *cls,
                                                rd[i].data_size);
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token: %s\n", data);
       json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
-                                                        label);
+                                                   label);
       issuer = json_string (handle->ego_head->identifier);
       GNUNET_JSONAPI_resource_add_attr (json_resource,
-                                             GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST,
-                                             issuer);
+                                        GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST,
+                                        issuer);
       json_decref (issuer);
       token = json_string (data);
       GNUNET_JSONAPI_resource_add_attr (json_resource,
-                                             GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
-                                             token);
+                                        GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
+                                        token);
       json_decref (token);
 
       GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource);
@@ -761,6 +818,7 @@ list_token_cont (struct GNUNET_REST_RequestHandle *con_handle,
   }
   ego_val = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
                                                &key);
+  GNUNET_assert (NULL != ego_val);
   //Remove non-matching egos
   for (ego_entry = handle->ego_head;
        NULL != ego_entry;)
@@ -789,7 +847,11 @@ list_token_cont (struct GNUNET_REST_RequestHandle *con_handle,
   handle->ns_handle = GNUNET_NAMESTORE_connect (cfg);
   handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
                                                          priv_key,
+                                                         &token_collect_error_cb,
+                                                         handle,
                                                          &token_collect,
+                                                         handle,
+                                                         &token_collect_finished_cb,
                                                          handle);
 
 }
@@ -828,13 +890,14 @@ exchange_cont (void *cls,
     return;
   }
   nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
-                                                  &key);
+                                                 &key);
+  GNUNET_assert (NULL != nonce_str);
   GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &expected_nonce));
 
   if (ticket_nonce != expected_nonce)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Ticket nonce %lu does not match expected nonce %lu\n",
+                "Ticket nonce %"SCNu64" does not match expected nonce %"SCNu64"\n",
                 ticket_nonce, expected_nonce);
     handle->emsg = GNUNET_strdup ("Ticket nonce does not match expected nonce\n");
     GNUNET_SCHEDULER_add_now (&do_error, handle);