Fixed direct Namestore Access
authorMarkus Voggenreiter <Markus.Voggenreiter@tum.de>
Sat, 12 Oct 2019 12:47:51 +0000 (14:47 +0200)
committerSchanzenbach, Martin <mschanzenbach@posteo.de>
Mon, 13 Jan 2020 12:31:01 +0000 (13:31 +0100)
src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c
src/reclaim/plugin_rest_reclaim.c

index 212425a6ff52e696661b2a030f539c2ffca6d0b9..ade2a27bbddbd29fec83459e81a74d8b54c74cb3 100644 (file)
@@ -160,15 +160,14 @@ static struct
                        { NULL, UINT32_MAX } };
 
 /**
  * Mapping of attribute type numbers to human-readable
  * attribute type names.
  */
* Mapping of attestation type numbers to human-readable
* attestation type names.
+ */
 static struct
 {
   const char *name;
   uint32_t number;
-} gnuid_attest_name_map[] = { { "STRING",
-                                GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING },
+} gnuid_attest_name_map[] = { { "JWT", GNUNET_RECLAIM_ATTESTATION_TYPE_JWT },
                               { NULL, UINT32_MAX } };
 
 /**
index c719f95fdd068f778e2aab4e0759f781415e595b..b423949060da19815674086032ef176db2b7e396 100644 (file)
@@ -241,6 +241,143 @@ struct RequestHandle
   json_t *resp_object;
 };
 
+/**
+ * Handle for attribute store request
+ */
+struct AttributeStoreHandle
+{
+  /**
+   * DLL
+   */
+  struct AttributeStoreHandle *next;
+
+  /**
+   * DLL
+   */
+  struct AttributeStoreHandle *prev;
+
+  /**
+   * Client connection
+   */
+  struct IdpClient *client;
+
+  /**
+   * Identity
+   */
+  struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+  /**
+   * Identity pubkey
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
+
+  /**
+   * QueueEntry
+   */
+  struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+  /**
+   * The attribute to store
+   */
+  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
+
+  /**
+   * The attestation to store
+   */
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+
+  /**
+   * The attribute expiration interval
+   */
+  struct GNUNET_TIME_Relative exp;
+
+  /**
+   * request id
+   */
+  uint32_t r_id;
+};
+
+/**
+ * Handle to the service.
+ */
+struct GNUNET_RECLAIM_Handle
+{
+  /**
+   * Configuration to use.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Socket (if available).
+   */
+  struct GNUNET_CLIENT_Connection *client;
+
+  /**
+   * Closure for 'cb'.
+   */
+  void *cb_cls;
+
+  /**
+   * Head of active operations.
+   */
+  struct GNUNET_RECLAIM_Operation *op_head;
+
+  /**
+   * Tail of active operations.
+   */
+  struct GNUNET_RECLAIM_Operation *op_tail;
+
+  /**
+   * Head of active iterations
+   */
+  struct GNUNET_RECLAIM_AttributeIterator *it_head;
+
+  /**
+   * Tail of active iterations
+   */
+  struct GNUNET_RECLAIM_AttributeIterator *it_tail;
+
+  /**
+   * Head of active iterations
+   */
+  struct GNUNET_RECLAIM_TicketIterator *ticket_it_head;
+
+  /**
+   * Tail of active iterations
+   */
+  struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail;
+
+  /**
+   * Currently pending transmission request, or NULL for none.
+   */
+  struct GNUNET_CLIENT_TransmitHandle *th;
+
+  /**
+   * Task doing exponential back-off trying to reconnect.
+   */
+  struct GNUNET_SCHEDULER_Task *reconnect_task;
+
+  /**
+   * Time for next connect retry.
+   */
+  struct GNUNET_TIME_Relative reconnect_backoff;
+
+  /**
+   * Connection to service (if available).
+   */
+  struct GNUNET_MQ_Handle *mq;
+
+  /**
+   * Request Id generator.  Incremented by one for each request.
+   */
+  uint32_t r_id_gen;
+
+  /**
+   * Are we polling for incoming messages right now?
+   */
+  int in_receive;
+};
+
 /**
  * Cleanup lookup handle
  * @param handle Handle to clean up
@@ -442,9 +579,131 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
                       const char *url,
                       void *cls)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding Attestations not supported\n");
-  GNUNET_SCHEDULER_add_now (&do_error, cls);
-  return;
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
+  const char *identity;
+  struct RequestHandle *handle = cls;
+  struct EgoEntry *ego_entry;
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attribute;
+  struct GNUNET_TIME_Relative exp;
+  char term_data[handle->rest_handle->data_size + 1];
+  json_t *data_json;
+  json_error_t err;
+  struct GNUNET_JSON_Specification attrspec[] =
+  { GNUNET_RECLAIM_JSON_spec_claim_attest (&attribute),
+    GNUNET_JSON_spec_end () };
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Adding an attestation for %s.\n",
+              handle->url);
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
+        handle->url))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity = handle->url + strlen (
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1;
+
+  for (ego_entry = handle->ego_head; NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    if (0 == strcmp (identity, ego_entry->identifier))
+      break;
+
+  if (NULL == ego_entry)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
+    return;
+  }
+  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+
+  if (0 >= handle->rest_handle->data_size)
+  {
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  term_data[handle->rest_handle->data_size] = '\0';
+  GNUNET_memcpy (term_data,
+                 handle->rest_handle->data,
+                 handle->rest_handle->data_size);
+  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
+  json_decref (data_json);
+  if (NULL == attribute)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse attestation from %s\n",
+                term_data);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  /**
+   * New ID for attribute
+   */
+  if (0 == attribute->id)
+    attribute->id =
+      GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  exp = GNUNET_TIME_UNIT_HOURS;
+  /*New  */
+  struct GNUNET_RECLAIM_Handle *h = handle->idp;
+  struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey = identity_priv;
+  /*struct GNUNET_RECLAIM_ATTESTATION_Claim *attr = attribute;*/
+  struct GNUNET_TIME_Relative *exp_interval = &exp;
+  /*GNUNET_RECLAIM_ContinuationWithStatus cont = &finished_cont;*/
+  void *cont_cls = handle;
+
+  struct AttributeStoreHandle *ash;
+  struct GNUNET_GNSRECORD_Data rd[1];
+  char *buf;
+  char *label;
+  size_t buf_size;
+  struct IdpClient *idp = cont_cls;
+  struct GNUNET_NAMESTORE_Handle *nsh;
+  nsh = GNUNET_NAMESTORE_connect (cfg);
+  if (NULL == nsh)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                         "error connecting to namestore");
+  }
+  ash = GNUNET_new (struct AttributeStoreHandle);
+  ash->identity = *pkey;
+  ash->r_id = h->r_id_gen++;
+  ash->exp.rel_value_us = exp_interval->rel_value_us;
+  ash->attest = attribute;
+  ash->client = idp;
+  /*GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Type:%u\n", type);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ID:%s\n", id_str);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Size:%u\n", data_size);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data:%s\n", data);*/
+  buf_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (ash->attest);
+  buf = GNUNET_malloc (buf_size);
+  // Give the ash a new id if unset
+  if (0 == ash->attest->id)
+    ash->attest->id
+      = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+  GNUNET_RECLAIM_ATTESTATION_serialize (ash->attest, buf);
+  label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
+                                               sizeof(uint64_t));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
+
+  rd[0].data_size = buf_size;
+  rd[0].data = buf;
+  rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
+  rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+  rd[0].expiration_time = ash->exp.rel_value_us;
+  ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                               &ash->identity,
+                                               label,
+                                               1,
+                                               rd,
+                                               &finished_cont,
+                                               ash);
+  GNUNET_free (buf);
+  GNUNET_free (label);
+  GNUNET_JSON_parse_free (attrspec);
 }
 /*Placeholder*/
 static void