- fix
[oweals/gnunet.git] / src / identity-provider / plugin_rest_identity_provider.c
index 3250a9fbd35e27459caf3797f23335213e8226c3..3a615168226514690a9faf3dd850d6dc65c5477a 100644 (file)
@@ -1,6 +1,6 @@
 /*
    This file is part of GNUnet.
-   Copyright (C) 2012-2015 Christian Grothoff (and other contributing authors)
+   Copyright (C) 2012-2015 GNUnet e.V.
 
    GNUnet is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published
@@ -33,6 +33,7 @@
 #include "gnunet_rest_lib.h"
 #include "microhttpd.h"
 #include <jansson.h>
+#include <inttypes.h>
 #include "gnunet_signatures.h"
 #include "gnunet_identity_provider_service.h"
 
 #define GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN "/idp/token"
 
 /**
- * The URL parameter name in which the ticket must be provided
+ * The parameter name in which the ticket must be provided
  */
 #define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET "ticket"
 
+/**
+ * The parameter name in which the expected nonce must be provided
+ */
+#define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE "expected_nonce"
+
+/**
+ * The parameter name in which the ticket must be provided
+ */
+#define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TOKEN "token"
+
 /**
  * The URL parameter name in which the nonce must be provided
  */
@@ -354,13 +365,17 @@ do_cleanup_handle_delayed (void *cls,
  */
 static void
 token_creat_cont (void *cls,
-                  const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
+                  const char *label,
+                  const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+                  const struct GNUNET_IDENTITY_PROVIDER_Token *token)
 {
   struct JsonApiResource *json_resource;
   struct RequestHandle *handle = cls;
   struct MHD_Response *resp;
-  json_t *token_ticket_json;
+  json_t *ticket_json;
+  json_t *token_json;
   char *ticket_str;
+  char *token_str;
   char *result_str;
   
   if (NULL == ticket)
@@ -369,18 +384,26 @@ token_creat_cont (void *cls,
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-    
+
   handle->resp_object = GNUNET_REST_jsonapi_object_new ();
   json_resource = GNUNET_REST_jsonapi_resource_new (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET,
-                                                    "tmpid"); //TODO
+                                                    label);
   ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket);
-  token_ticket_json = json_string (ticket_str);
+  token_str = GNUNET_IDENTITY_PROVIDER_token_to_string (token);
+  ticket_json = json_string (ticket_str);
+  token_json = json_string (token_str);
   GNUNET_REST_jsonapi_resource_add_attr (json_resource,
                                          GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET,
-                                         token_ticket_json);
+                                         ticket_json);
+  GNUNET_REST_jsonapi_resource_add_attr (json_resource,
+                                         GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TOKEN,
+                                         token_json);
   GNUNET_free (ticket_str);
-  json_decref (token_ticket_json);
+  GNUNET_free (token_str);
+  json_decref (ticket_json);
+  json_decref (token_json);
   GNUNET_REST_jsonapi_object_resource_add (handle->resp_object, json_resource);
+
   GNUNET_REST_jsonapi_data_serialize (handle->resp_object, &result_str);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
   resp = GNUNET_REST_create_json_response (result_str);
@@ -405,7 +428,7 @@ issue_token_cont (struct RestConnectionDataHandle *con,
 {
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
   const char *egoname;
-  
+
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
   struct GNUNET_HashCode key;
@@ -436,7 +459,7 @@ issue_token_cont (struct RestConnectionDataHandle *con,
   GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST,
                       strlen (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST),
                       &key);
-  if ( GNUNET_YES ==
+  if ( GNUNET_YES !=
        GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
                                                &key) )
   {
@@ -529,7 +552,7 @@ issue_token_cont (struct RestConnectionDataHandle *con,
   nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
                                                  &key);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str);
-  sscanf (nonce_str, "%lu", &nonce);
+  sscanf (nonce_str, "%"SCNu64, &nonce);
 
   //Get expiration for token from URL parameter
   GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_EXP_STRING,
@@ -750,22 +773,52 @@ list_token_cont (struct RestConnectionDataHandle *con_handle,
  */
 static void
 exchange_cont (void *cls,
-               const struct GNUNET_IDENTITY_PROVIDER_Token *token)
+               const struct GNUNET_IDENTITY_PROVIDER_Token *token,
+               uint64_t ticket_nonce)
 {
   json_t *root;
   struct RequestHandle *handle = cls;
   struct MHD_Response *resp;
+  struct GNUNET_HashCode key;
   char* result;
   char* token_str;
+  char* nonce_str;
+  uint64_t expected_nonce;
+  
+  //Get nonce
+  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE,
+                      strlen (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE),
+                      &key);
+
+  if ( GNUNET_NO ==
+       GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
+                                               &key) )
+  {
+    handle->emsg = GNUNET_strdup ("No nonce given.");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
+                                                  &key);
+  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, expected_nonce);
+    handle->emsg = GNUNET_strdup ("Ticket nonce does not match expected nonce\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
 
   root = json_object ();
   token_str = GNUNET_IDENTITY_PROVIDER_token_to_string (token);
-  json_object_set_new (root, "identity_token", json_string (token_str));
+  json_object_set_new (root, "token", json_string (token_str));
   json_object_set_new (root, "token_type", json_string ("jwt"));
   GNUNET_free (token_str);
 
   result = json_dumps (root, JSON_INDENT(1));
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", result);
   resp = GNUNET_REST_create_json_response (result);
   GNUNET_free (result);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
@@ -804,6 +857,7 @@ exchange_token_ticket_cb (void *cls,
     return;
   }
 
+  //Get ticket
   GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET,
                       strlen (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET),
                       &key);
@@ -818,7 +872,6 @@ exchange_token_ticket_cb (void *cls,
   }
   ticket_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
                                                   &key);
-
   handle->priv_key = GNUNET_IDENTITY_ego_get_private_key (ego);
   GNUNET_IDENTITY_PROVIDER_string_to_ticket (ticket_str,
                                              &ticket);
@@ -1016,7 +1069,7 @@ rest_identity_process_request(struct RestConnectionDataHandle *conndata_handle,
  * @return NULL on error, otherwise the plugin context
  */
 void *
-libgnunet_plugin_rest_identity_token_init (void *cls)
+libgnunet_plugin_rest_identity_provider_init (void *cls)
 {
   static struct Plugin plugin;
   struct GNUNET_REST_Plugin *api;
@@ -1051,7 +1104,7 @@ libgnunet_plugin_rest_identity_token_init (void *cls)
  * @return always NULL
  */
 void *
-libgnunet_plugin_rest_identity_token_done (void *cls)
+libgnunet_plugin_rest_identity_provider_done (void *cls)
 {
   struct GNUNET_REST_Plugin *api = cls;
   struct Plugin *plugin = api->cls;