#include "gnunet_gnsrecord_lib.h"
#include "gnunet_namestore_service.h"
#include "gnunet_rest_lib.h"
+#include "gnunet_jsonapi_lib.h"
+#include "gnunet_jsonapi_util.h"
#include "microhttpd.h"
#include <jansson.h>
#include <inttypes.h>
*/
#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
*/
/**
* Handle to the rest connection
*/
- struct RestConnectionDataHandle *conndata_handle;
+ struct GNUNET_REST_RequestHandle *conndata_handle;
/**
* The processing state
/**
* ID of a task associated with the resolution process.
*/
- struct GNUNET_SCHEDULER_Task * timeout_task;
+ struct GNUNET_SCHEDULER_Task *timeout_task;
/**
* The plugin result processor
*/
char *emsg;
+ /**
+ * Reponse code
+ */
+ int response_code;
+
/**
* Response object
*/
- struct JsonApiObject *resp_object;
+ struct GNUNET_JSONAPI_Document *resp_object;
};
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Cleaning up\n");
if (NULL != handle->resp_object)
- GNUNET_REST_jsonapi_object_delete (handle->resp_object);
+ GNUNET_JSONAPI_document_delete (handle->resp_object);
if (NULL != handle->timeout_task)
GNUNET_SCHEDULER_cancel (handle->timeout_task);
if (NULL != handle->identity_handle)
/**
- * Task run on shutdown. Cleans up everything.
+ * Task run on error, sends error message. Cleans up everything.
*
- * @param cls unused
+ * @param cls the `struct RequestHandle`
*/
static void
do_error (void *cls)
GNUNET_asprintf (&json_error,
"{Error while processing request: %s}",
handle->emsg);
- resp = GNUNET_REST_create_json_response (json_error);
- handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
+ resp = GNUNET_REST_create_response (json_error);
+ handle->proc (handle->proc_cls, resp, handle->response_code);
cleanup_handle (handle);
GNUNET_free (json_error);
}
+/**
+ * Task run on timeout, sends error message. Cleans up everything.
+ *
+ * @param cls the `struct RequestHandle`
+ */
+static void
+do_timeout (void *cls)
+{
+ struct RequestHandle *handle = cls;
+
+ handle->timeout_task = NULL;
+ do_error (handle);
+}
+
+
/**
* Task run on shutdown. Cleans up everything.
*
do_cleanup_handle_delayed (void *cls)
{
struct RequestHandle *handle = cls;
- cleanup_handle(handle);
+
+ cleanup_handle (handle);
}
const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
const struct GNUNET_IDENTITY_PROVIDER_Token *token)
{
- struct JsonApiResource *json_resource;
+ struct GNUNET_JSONAPI_Resource *json_resource;
struct RequestHandle *handle = cls;
struct MHD_Response *resp;
json_t *ticket_json;
return;
}
- handle->resp_object = GNUNET_REST_jsonapi_object_new ();
- json_resource = GNUNET_REST_jsonapi_resource_new (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET,
+ handle->resp_object = GNUNET_JSONAPI_document_new ();
+ json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET,
label);
ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket);
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_JSONAPI_resource_add_attr (json_resource,
GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET,
ticket_json);
- GNUNET_REST_jsonapi_resource_add_attr (json_resource,
+ GNUNET_JSONAPI_resource_add_attr (json_resource,
GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TOKEN,
token_json);
GNUNET_free (ticket_str);
GNUNET_free (token_str);
json_decref (ticket_json);
json_decref (token_json);
- GNUNET_REST_jsonapi_object_resource_add (handle->resp_object, json_resource);
+ GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource);
- GNUNET_REST_jsonapi_data_serialize (handle->resp_object, &result_str);
+ GNUNET_JSONAPI_document_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);
+ resp = GNUNET_REST_create_response (result_str);
handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
GNUNET_free (result_str);
GNUNET_SCHEDULER_add_now (&do_cleanup_handle_delayed, handle);
-
-
}
+
/**
* Continueationf for token issue request
*
* @param cls the request handle
*/
static void
-issue_token_cont (struct RestConnectionDataHandle *con,
+issue_token_cont (struct GNUNET_REST_RequestHandle *con,
const char *url,
void *cls)
{
char *exp_str;
char *nonce_str;
char *scopes;
+ char *vattrs;
uint64_t time;
uint64_t nonce;
GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "URL invalid: %s\n", handle->url);
- resp = GNUNET_REST_create_json_response (NULL);
+ resp = GNUNET_REST_create_response (NULL);
handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
cleanup_handle (handle);
return;
GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
&key) )
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Issuer not found\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Issuer not found\n");
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
if (NULL == ego_val)
{
GNUNET_SCHEDULER_add_now (&do_error, handle);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Ego invalid: %s\n", ego_val);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Ego invalid: %s\n",
+ ego_val);
return;
}
for (ego_entry = handle->ego_head;
egoname = ego_entry->identifier;
break;
}
- if (NULL == egoname || NULL == ego_entry)
+ if ( (NULL == egoname) ||
+ (NULL == ego_entry) )
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Ego not found: %s\n", ego_val);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Ego not found: %s\n",
+ ego_val);
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego to issue token for: %s\n", egoname);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Ego to issue token for: %s\n",
+ egoname);
//Meta info
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,
GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
&key) )
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Audience missing!\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "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);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "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,
}
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, "%"SCNu64, &nonce);
+ GNUNET_assert (NULL != nonce_str);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Request nonce: %s\n",
+ nonce_str);
+ GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &nonce));
//Get expiration for token from URL parameter
GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_EXP_STRING,
priv_key,
&aud_key,
scopes,
+ vattrs,
exp_time,
nonce,
&token_creat_cont,
struct RequestHandle *handle = cls;
struct MHD_Response *resp;
- GNUNET_REST_jsonapi_data_serialize (handle->resp_object, &result_str);
+ GNUNET_JSONAPI_document_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);
+ resp = GNUNET_REST_create_response (result_str);
handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
GNUNET_free (result_str);
cleanup_handle (handle);
}
+
+static void
+token_collect_error_cb (void *cls)
+{
+ struct RequestHandle *handle = cls;
+
+ do_error (handle);
+}
+
+
/**
* Collect all tokens for an ego
*
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 JsonApiResource *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);
+ 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;
- }
-
- 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)
rd[i].data,
rd[i].data_size);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token: %s\n", data);
- json_resource = GNUNET_REST_jsonapi_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
- label);
+ json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
+ label);
issuer = json_string (handle->ego_head->identifier);
- GNUNET_REST_jsonapi_resource_add_attr (json_resource,
- GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST,
- issuer);
+ GNUNET_JSONAPI_resource_add_attr (json_resource,
+ GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST,
+ issuer);
json_decref (issuer);
token = json_string (data);
- GNUNET_REST_jsonapi_resource_add_attr (json_resource,
- GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
- token);
+ GNUNET_JSONAPI_resource_add_attr (json_resource,
+ GNUNET_REST_JSONAPI_IDENTITY_TOKEN,
+ token);
json_decref (token);
- GNUNET_REST_jsonapi_object_resource_add (handle->resp_object, json_resource);
+ GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource);
GNUNET_free (data);
}
}
* @param cls the RequestHandle
*/
static void
-list_token_cont (struct RestConnectionDataHandle *con_handle,
+list_token_cont (struct GNUNET_REST_RequestHandle *con_handle,
const char* url,
void *cls)
{
}
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;)
GNUNET_free (ego_tmp);
}
}
- handle->resp_object = GNUNET_REST_jsonapi_object_new ();
+ handle->resp_object = GNUNET_JSONAPI_document_new ();
if (NULL == handle->ego_head)
{
//Done
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);
}
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);
GNUNET_free (token_str);
result = json_dumps (root, JSON_INDENT(1));
- resp = GNUNET_REST_create_json_response (result);
+ resp = GNUNET_REST_create_response (result);
GNUNET_free (result);
handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
cleanup_handle (handle);
* @param cls the RequestHandle
*/
static void
-exchange_token_ticket_cont (struct RestConnectionDataHandle *con_handle,
+exchange_token_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
const char* url,
void *cls)
{
* @param cls the RequestHandle
*/
static void
-options_cont (struct RestConnectionDataHandle *con_handle,
+options_cont (struct GNUNET_REST_RequestHandle *con_handle,
const char* url,
void *cls)
{
struct RequestHandle *handle = cls;
//For now, independent of path return all options
- resp = GNUNET_REST_create_json_response (NULL);
+ resp = GNUNET_REST_create_response (NULL);
MHD_add_response_header (resp,
"Access-Control-Allow-Methods",
allow_methods);
static void
init_cont (struct RequestHandle *handle)
{
- static const struct GNUNET_REST_RestConnectionHandler handlers[] = {
+ struct GNUNET_REST_RequestHandlerError err;
+ static const struct GNUNET_REST_RequestHandler handlers[] = {
{MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE, &issue_token_cont},
//{MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK, &check_token_cont},
{MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PROVIDER, &list_token_cont},
GNUNET_REST_HANDLER_END
};
- if (GNUNET_NO == GNUNET_REST_handle_request (handle->conndata_handle, handlers, handle))
+ if (GNUNET_NO == GNUNET_REST_handle_request (handle->conndata_handle,
+ handlers,
+ &err,
+ handle))
{
- handle->emsg = GNUNET_strdup ("Request unsupported");
+ handle->response_code = err.error_code;
GNUNET_SCHEDULER_add_now (&do_error, handle);
}
}
ego_entry->keystring =
GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
ego_entry->ego = ego;
- GNUNET_asprintf (&ego_entry->identifier, "%s", identifier);
+ ego_entry->identifier = GNUNET_strdup (identifier);
GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry);
}
* @return GNUNET_OK if request accepted
*/
static void
-rest_identity_process_request(struct RestConnectionDataHandle *conndata_handle,
+rest_identity_process_request(struct GNUNET_REST_RequestHandle *conndata_handle,
GNUNET_REST_ResultProcessor proc,
void *proc_cls)
{
handle->conndata_handle = conndata_handle;
- GNUNET_asprintf (&handle->url, "%s", conndata_handle->url);
+ handle->url = GNUNET_strdup (conndata_handle->url);
if (handle->url[strlen (handle->url)-1] == '/')
handle->url[strlen (handle->url)-1] = '\0';
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
handle);
handle->timeout_task =
GNUNET_SCHEDULER_add_delayed (handle->timeout,
- &do_error,
+ &do_timeout,
handle);
-
-
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Connected\n");
}