gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-anastasis] branch master updated: implement redux recovery initia


From: gnunet
Subject: [taler-anastasis] branch master updated: implement redux recovery initialization logic
Date: Sat, 20 Feb 2021 21:34:03 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new 70d05c5  implement redux recovery initialization logic
70d05c5 is described below

commit 70d05c52142fc2f6b35ca135a5d274b6f6cc5b8a
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Feb 20 21:34:00 2021 +0100

    implement redux recovery initialization logic
---
 src/include/anastasis.h                    |   5 +
 src/lib/anastasis_recovery.c               |  19 +-
 src/reducer/anastasis_api_recovery_redux.c | 548 ++++++++++++++---------------
 3 files changed, 278 insertions(+), 294 deletions(-)

diff --git a/src/include/anastasis.h b/src/include/anastasis.h
index d6ca715..2ec97b5 100644
--- a/src/include/anastasis.h
+++ b/src/include/anastasis.h
@@ -49,6 +49,11 @@ struct ANASTASIS_Challenge;
 struct ANASTASIS_ChallengeDetails
 {
 
+  /**
+   * UUID which identifies this challenge
+   */
+  struct ANASTASIS_CRYPTO_TruthUUIDP uuid;
+
   /**
    * Cost to solve this challenge
    */
diff --git a/src/lib/anastasis_recovery.c b/src/lib/anastasis_recovery.c
index ca99de6..a270549 100644
--- a/src/lib/anastasis_recovery.c
+++ b/src/lib/anastasis_recovery.c
@@ -39,11 +39,6 @@ struct ANASTASIS_Challenge
    */
   struct ANASTASIS_ChallengeDetails ci;
 
-  /**
-   * UUID which identifies this challenge
-   */
-  struct ANASTASIS_CRYPTO_TruthUUIDP uuid;
-
   /**
    * Key used to encrypt the truth passed to the server
    */
@@ -428,7 +423,7 @@ ANASTASIS_challenge_start (struct ANASTASIS_Challenge *c,
   c->af_cls = af_cls;
   c->kslo = ANASTASIS_keyshare_lookup (c->recovery->ctx,
                                        c->url,
-                                       &c->uuid,
+                                       &c->ci.uuid,
                                        &c->truth_key,
                                        psp,
                                        hashed_answer,
@@ -673,7 +668,7 @@ policy_lookup_cb (void *cls,
     const char *escrow_method;
     struct GNUNET_JSON_Specification spec[] = {
       GNUNET_JSON_spec_fixed_auto ("uuid",
-                                   &cs->uuid),
+                                   &cs->ci.uuid),
       GNUNET_JSON_spec_string ("url",
                                &url),
       GNUNET_JSON_spec_string ("instructions",
@@ -780,7 +775,7 @@ policy_lookup_cb (void *cls,
       {
         if (0 !=
             GNUNET_memcmp (&uuid,
-                           &r->cs[i].uuid))
+                           &r->cs[i].ci.uuid))
           continue;
         found = true;
         dp->pub_details.challenges[n_index] = &r->cs[i];
@@ -885,7 +880,7 @@ ANASTASIS_recovery_serialize (const struct 
ANASTASIS_Recovery *r)
 
       cs = json_pack ("{s:o}",
                       "uuid",
-                      GNUNET_JSON_from_data_auto (&c->uuid));
+                      GNUNET_JSON_from_data_auto (&c->ci.uuid));
       GNUNET_assert (NULL != cs);
       GNUNET_assert (0 ==
                      json_array_append_new (dps_arr,
@@ -913,7 +908,7 @@ ANASTASIS_recovery_serialize (const struct 
ANASTASIS_Recovery *r)
     cs = json_pack ("{s:o,s:o,s:o,s:o?,"
                     " s:s,s:s,s:s,s:o}",
                     "uuid",
-                    GNUNET_JSON_from_data_auto (&c->uuid),
+                    GNUNET_JSON_from_data_auto (&c->ci.uuid),
                     "truth_key",
                     GNUNET_JSON_from_data_auto (&c->truth_key),
                     "truth_salt",
@@ -989,7 +984,7 @@ parse_cs_array (struct ANASTASIS_Recovery *r,
     const char *escrow_method;
     struct GNUNET_JSON_Specification spec[] = {
       GNUNET_JSON_spec_fixed_auto ("uuid",
-                                   &c->uuid),
+                                   &c->ci.uuid),
       GNUNET_JSON_spec_string ("url",
                                &url),
       GNUNET_JSON_spec_string ("instructions",
@@ -1112,7 +1107,7 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
         {
           if (0 !=
               GNUNET_memcmp (&uuid,
-                             &r->cs[i].uuid))
+                             &r->cs[i].ci.uuid))
             continue;
           dp->pub_details.challenges[c_index] = &r->cs[i];
           found = true;
diff --git a/src/reducer/anastasis_api_recovery_redux.c 
b/src/reducer/anastasis_api_recovery_redux.c
index c5b0d92..f960f40 100644
--- a/src/reducer/anastasis_api_recovery_redux.c
+++ b/src/reducer/anastasis_api_recovery_redux.c
@@ -61,21 +61,6 @@ ANASTASIS_recovery_state_to_string_ (enum 
ANASTASIS_RecoveryState rs)
 }
 
 
-/**
- * Callback function FIXME: Description.
- *
- * @param state FIXME: Description
- * @param arguments FIXME: Description
- * @param cb FIXME: Description
- * @param cb_cls FIXME: Description
- */
-typedef struct ANASTASIS_ReduxAction *
-(*DispatchHandler)(json_t *state,
-                   const json_t *arguments,
-                   ANASTASIS_ActionCallback cb,
-                   void *cb_cls);
-
-
 /**
  * State for a "challenge answer" CMD.
  */
@@ -471,73 +456,6 @@ check_policy_fulfilled (json_t *state)
 }
 
 
-/**
- * State for a "recover secret" CMD.
- */
-struct RecoverSecretState
-{
-  /**
-   * URL of the anastasis backend.
-   */
-  const char *anastasis_url;
-
-  /**
-   * The /policy GET operation handle.
-   */
-  struct ANASTASIS_Recovery *recovery;
-
-  /**
-   * Identification data from the user
-   */
-  json_t *id_data;
-
-  /**
-   * Salt to be used to derive the id
-   */
-  struct ANASTASIS_CRYPTO_PowSalt *salt;
-
-  /**
-   * Recovery information from the lookup
-   */
-  struct ANASTASIS_RecoveryInformation *ri;
-
-  /**
-   * Information about the challenges.
-   */
-  struct ANASTASIS_Challenge **challenges;
-
-  /**
-   * Reference to a state.
-   */
-  json_t *state;
-
-  /**
-   * callback (#DispatchHandler) to call during/after operation
-   */
-  ANASTASIS_ActionCallback cb;
-
-  /**
-   * closure fpr action callback
-   */
-  void *cb_cls;
-
-  /**
-   * Expected status code.
-   */
-  unsigned int http_status;
-
-  /**
-   * version of the recovery document
-   */
-  unsigned int version;
-
-  /**
-   * Amount of challenges.
-   */
-  unsigned int challenges_length;
-};
-
-
 // static
 void
 challenge_answer_cb (void *af_cls,
@@ -651,6 +569,21 @@ back_challenge_solving (json_t *state,
 }
 
 
+/**
+ * Signature of callback function that implements a state transition.
+ *
+ *  @param state current state
+ *  @param arguments arguments for the state transition
+ *  @param cb function to call when done
+ *  @param cb_cls closure for @a cb
+ */
+typedef struct ANASTASIS_ReduxAction *
+(*DispatchHandler)(json_t *state,
+                   const json_t *arguments,
+                   ANASTASIS_ActionCallback cb,
+                   void *cb_cls);
+
+
 /**
  * Operates on a recovery state depending on given #ANASTASIS_RecoveryState
  * and #ANASTASIS_RecoveryAction. The new #ANASTASIS_RecoveryState is returned
@@ -741,144 +674,98 @@ ANASTASIS_recovery_action_ (json_t *state,
 }
 
 
-static void
-policy_lookup_cb (void *cls,
-                  const struct ANASTASIS_RecoveryInformation *ri)
+/**
+ * State for a "recover secret" CMD.
+ */
+struct RecoverSecretState;
+
+
+/**
+ * State for a "policy download" as part of a recovery operation.
+ */
+struct PolicyDownloadEntry
 {
-  struct RecoverSecretState *rss = cls;
-  json_t *policies;
-  json_t *challenges;
-  json_t *recovery_information;
 
-  recovery_information = json_object_get (rss->state,
-                                          "recovery_information");
-  if (NULL == recovery_information)
-  {
-    recovery_information = json_object ();
-    GNUNET_assert (json_is_object (recovery_information));
-    policies = json_array ();
-    GNUNET_assert (json_is_array (policies));
-    challenges = json_array ();
-    GNUNET_assert (json_is_array (challenges));
-  }
-  else
-  {
-    GNUNET_assert (
-      json_is_array (
-        json_object_get (recovery_information,
-                         "policies")));
-    GNUNET_assert (
-      json_is_array (
-        json_object_get (recovery_information,
-                         "challenges")));
-    return;
-  }
+  /**
+   * Kept in a DLL.
+   */
+  struct PolicyDownloadEntry *prev;
 
-  if (NULL == ri)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  rss->ri = (struct ANASTASIS_RecoveryInformation *) ri;
-  rss->http_status = MHD_HTTP_OK;
+  /**
+   * Kept in a DLL.
+   */
+  struct PolicyDownloadEntry *next;
 
-  for (unsigned int i = 0; i < rss->ri->cs_len; i++)
-  {
-    struct ANASTASIS_Challenge *ci = rss->ri->cs[i];
-    bool contains = false;
+  /**
+   * Backend we are querying.
+   */
+  char *backend_url;
 
-    for (unsigned int i = 0; i < rss->challenges_length; i++)
-    {
-      if (rss->challenges[i] == rss->ri->cs[i])
-      {
-        contains = true;
-        break;
-      }
-    }
-    if (! contains)
-    {
-      GNUNET_array_append (rss->challenges,
-                           rss->challenges_length,
-                           ci);
-#if FIXME
-      /* should probably only serialize the uuid and
-         what the UI needs! */
-      GNUNET_assert (
-        0 == json_array_append_new (
-          challenges,
-          ANASTASIS_challenge_information_to_json (ci)));
-#endif
-    }
-  }
-  for (unsigned int i = 0; i < ri->dps_len; i++)
-  {
-    json_t *policy = json_array ();
+  /**
+   * Salt to be used to derive the id for this provider
+   */
+  struct ANASTASIS_CRYPTO_PowSalt salt;
 
-    GNUNET_assert (json_is_array (policy));
-    for (unsigned int j = 0; j < ri->dps[i]->challenges_length; j++)
-    {
-      for (unsigned int k = 0; k < rss->challenges_length; k++)
-      {
-        if (ri->dps[i]->challenges[j] == rss->challenges[k])
-          GNUNET_assert (
-            0 == json_array_append_new (policy,
-                                        json_integer ((json_int_t) k)));
-      }
-    }
-    if (0 < json_array_size (policy))
-      GNUNET_assert (
-        0 == json_array_append_new (policies,
-                                    policy));
-  }
-  if ((0 < json_array_size (challenges))
-      && (0 < json_array_size (policies)))
-  {
-    GNUNET_assert (
-      0 == json_object_set_new (recovery_information,
-                                "provider_url",
-                                json_string (rss->anastasis_url)));
-    GNUNET_assert (
-      0 == json_object_set_new (recovery_information,
-                                "version",
-                                json_integer (rss->version)));
-    GNUNET_assert (
-      0 == json_object_set_new (recovery_information,
-                                "policies",
-                                policies));
-    GNUNET_assert (
-      0 == json_object_set_new (recovery_information,
-                                "challenges",
-                                challenges));
-    GNUNET_assert (
-      0 == json_object_set_new (rss->state,
-                                "recovery_information",
-                                recovery_information));
-    rss->cb (NULL,
-             TALER_EC_NONE,
-             rss->state);
-    // rss->cb = NULL;
-  }
-  else
-  {
-    json_decref (challenges);
-    json_decref (policies);
-    json_decref (recovery_information);
-    ANASTASIS_redux_fail_ (rss->cb,
-                           rss->cb_cls,
-                           TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID, // 
FIXME: Error code
-                           "Failed fetching recovery information!");
-  }
-  rss->recovery = NULL;
-}
+  /**
+   * Context we operate in.
+   */
+  struct RecoverSecretState *rss;
+
+  /**
+   * The /policy GET operation handle.
+   */
+  struct ANASTASIS_Recovery *recovery;
 
+};
 
-static void
-delayed_abort (void *cls)
+
+/**
+ * State for a "recover secret" CMD.
+ */
+struct RecoverSecretState
 {
-  struct ANASTASIS_Recovery *recovery = cls;
 
-  ANASTASIS_recovery_abort (recovery);
-}
+  /**
+   * Redux action handle associated with this state.
+   */
+  struct ANASTASIS_ReduxAction ra;
+
+  /**
+   * Identification data from the user
+   */
+  json_t *id_data;
+
+  /**
+   * Head of DLL of policy downloads.
+   */
+  struct PolicyDownloadEntry *pd_head;
+
+  /**
+   * Tail of DLL of policy downloads.
+   */
+  struct PolicyDownloadEntry *pd_tail;
+
+  /**
+   * Reference to our state.
+   */
+  json_t *state;
+
+  /**
+   * callback to call during/after operation
+   */
+  ANASTASIS_ActionCallback cb;
+
+  /**
+   * closure fpr action callback
+   */
+  void *cb_cls;
+
+  /**
+   * version of the recovery document to request.
+   */
+  unsigned int version;
+
+};
 
 
 /**
@@ -887,26 +774,113 @@ delayed_abort (void *cls)
  * @param cls closure for a #RecoverSecretState.
  */
 static void
-free_enter_user_attributes (void *cls)
+free_rss (void *cls)
 {
   struct RecoverSecretState *rss = cls;
+  struct PolicyDownloadEntry *pd;
 
-  if (NULL != rss->recovery)
+  while (NULL != (pd = rss->pd_head))
   {
-    /* must run first, or at least before #core_secret_cb */
-    (void) GNUNET_SCHEDULER_add_with_priority (
-      GNUNET_SCHEDULER_PRIORITY_SHUTDOWN,
-      &delayed_abort,
-      rss->recovery);
-    rss->recovery = NULL;
+    GNUNET_CONTAINER_DLL_remove (rss->pd_head,
+                                 rss->pd_tail,
+                                 pd);
+    if (NULL != pd->recovery)
+    {
+      ANASTASIS_recovery_abort (pd->recovery);
+      pd->recovery = NULL;
+    }
+    GNUNET_free (pd->backend_url);
+    GNUNET_free (pd);
   }
-  GNUNET_free (rss->challenges);
   json_decref (rss->state);
   json_decref (rss->id_data);
   GNUNET_free (rss);
 }
 
 
+static void
+policy_lookup_cb (void *cls,
+                  const struct ANASTASIS_RecoveryInformation *ri)
+{
+  struct PolicyDownloadEntry *pd = cls;
+  struct RecoverSecretState *rss = pd->rss;
+  json_t *policies;
+  json_t *challenges;
+  json_t *recovery_information;
+
+  pd->recovery = NULL;
+  policies = json_array ();
+  GNUNET_assert (NULL != policies);
+  for (unsigned int i = 0; i<ri->dps_len; i++)
+  {
+    struct ANASTASIS_DecryptionPolicy *dps = ri->dps[i];
+    json_t *pchallenges;
+
+    pchallenges = json_array ();
+    GNUNET_assert (NULL != pchallenges);
+    for (unsigned int j = 0; j<dps->challenges_length; j++)
+    {
+      struct ANASTASIS_Challenge *c = dps->challenges[j];
+      const struct ANASTASIS_ChallengeDetails *cd;
+      json_t *cj;
+
+      cd = ANASTASIS_challenge_get_details (c);
+      cj = json_pack ("{s:o}",
+                      "uuid",
+                      GNUNET_JSON_from_data_auto (&cd->uuid));
+      GNUNET_assert (NULL != cj);
+      GNUNET_assert (0 ==
+                     json_array_append_new (pchallenges,
+                                            cj));
+
+    }
+    GNUNET_assert (0 ==
+                   json_array_append_new (policies,
+                                          pchallenges));
+  } /* end for all policies */
+  challenges = json_array ();
+  GNUNET_assert (NULL != challenges);
+  for (unsigned int i = 0; i<ri->cs_len; i++)
+  {
+    struct ANASTASIS_Challenge *c = ri->cs[i];
+    const struct ANASTASIS_ChallengeDetails *cd;
+    json_t *cj;
+
+    cd = ANASTASIS_challenge_get_details (c);
+    cj = json_pack ("{s:o,s:o,s:s,s:s,s:b}",
+                    "uuid",
+                    GNUNET_JSON_from_data_auto (&cd->uuid),
+                    "cost",
+                    TALER_JSON_from_amount (&cd->cost),
+                    "method",
+                    cd->method,
+                    "instructions",
+                    cd->instructions,
+                    "solved",
+                    cd->solved);
+    GNUNET_assert (NULL != cj);
+    GNUNET_assert (0 ==
+                   json_array_append_new (challenges,
+                                          cj));
+  } /* end for all challenges */
+  recovery_information = json_pack ("{s:o, s:o, s:I}",
+                                    "challenges", challenges,
+                                    "policies", policies,
+                                    "version", (json_int_t) ri->version);
+  GNUNET_assert (NULL != recovery_information);
+  GNUNET_assert (0 ==
+                 json_object_set_new (rss->state,
+                                      "recovery_information",
+                                      recovery_information));
+  set_state (rss->state,
+             ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING);
+  rss->cb (rss->cb_cls,
+           TALER_EC_NONE,
+           rss->state);
+  free_rss (rss);
+}
+
+
 struct ANASTASIS_ReduxAction *
 ANASTASIS_REDUX_recovery_challenge_begin_ (json_t *state,
                                            const json_t *arguments,
@@ -915,91 +889,101 @@ ANASTASIS_REDUX_recovery_challenge_begin_ (json_t *state,
 {
   json_t *version;
   json_t *providers;
-  json_t *p_value;
   const json_t *attributes;
-  const char *p_key;
-  struct RecoverSecretState *rss
-    = GNUNET_new (struct RecoverSecretState);
+  struct RecoverSecretState *rss;
 
   providers = json_object_get (state,
                                "authentication_providers");
-  GNUNET_assert (NULL != providers);
+  if ( (NULL == providers) ||
+       (! json_is_object (providers)) )
+  {
+    GNUNET_break (0);
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'authentication_providers' missing");
+    return NULL;
+  }
   attributes = json_object_get (arguments,
                                 "identity_attributes");
-  GNUNET_assert (NULL != attributes); /* already checked by caller */
+  if ( (NULL == attributes) ||
+       (! json_is_object (attributes)) )
+  {
+    GNUNET_break (0);
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'identity_attributes' missing");
+    return NULL;
+  }
+  rss = GNUNET_new (struct RecoverSecretState);
   rss->id_data = json_incref ((json_t *) attributes);
   version = json_object_get (arguments,
                              "version");
   if (NULL != version)
     rss->version = (unsigned int) json_integer_value (version);
-  rss->challenges_length = 0;
   rss->state = json_incref (state);
   rss->cb = cb;
   rss->cb_cls = cb_cls;
 
-  json_object_foreach (providers, p_key, p_value)
   {
-    json_t *m_value;
-    size_t m_index;
+    bool launched = false;
+    json_t *p_cfg;
+    const char *provider_url;
 
-    GNUNET_assert (json_is_array (p_value));
-    json_array_foreach (p_value, m_index, m_value)
+    json_object_foreach (providers, provider_url, p_cfg)
     {
-      struct ANASTASIS_CRYPTO_PowSalt salt;
-      json_t *provider_data;
-      json_t *provider_url;
-      const char *salt_str;
-      void *iter = json_object_iter (m_value);
-      const char *key = json_object_iter_key (iter);
-
-      provider_data = json_object_get (m_value,
-                                       key);
-      GNUNET_assert (NULL != provider_data);
-      provider_url = json_object_get (provider_data,
-                                      "provider_url");
-      rss->anastasis_url = json_string_value (provider_url);
-      GNUNET_assert (NULL != provider_url);
-      salt_str = json_string_value (
-        json_object_get (provider_data,
-                         "provider_salt"));
-      GNUNET_assert (NULL != salt_str);
-      GNUNET_assert (
-        GNUNET_OK ==
-        GNUNET_STRINGS_string_to_data (salt_str,
-                                       strlen (salt_str),
-                                       &salt,
-                                       sizeof (struct
-                                               ANASTASIS_CRYPTO_PowSalt)));
-      rss->recovery =
-        ANASTASIS_recovery_begin (
-          ANASTASIS_REDUX_ctx_,
-          rss->id_data,
-          (NULL != version)
-            ? rss->version
-            : 0,
-          rss->anastasis_url,
-          &salt,
-          &policy_lookup_cb,
-          rss,
-          NULL,
-          NULL);
-
-      if (NULL == rss->recovery)
+      struct PolicyDownloadEntry *pd = GNUNET_new (struct PolicyDownloadEntry);
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_fixed_auto ("salt",
+                                     &pd->salt),
+        GNUNET_JSON_spec_end ()
+      };
+
+      GNUNET_CONTAINER_DLL_insert (rss->pd_head,
+                                   rss->pd_tail,
+                                   pd);
+      pd->backend_url = GNUNET_strdup (provider_url);
+      if (GNUNET_OK !=
+          GNUNET_JSON_parse (p_cfg,
+                             spec,
+                             NULL, NULL))
       {
         GNUNET_break (0);
-        cb (cb_cls,
-            TALER_EC_NONE,
-            state);
+        ANASTASIS_redux_fail_ (cb,
+                               cb_cls,
+                               TALER_EC_INVALID,
+                               "could not begin parse provider configuration");
+        free_rss (rss);
         return NULL;
       }
+      pd->rss = rss;
+      pd->recovery = ANASTASIS_recovery_begin (ANASTASIS_REDUX_ctx_,
+                                               rss->id_data,
+                                               (NULL != version)
+                                                  ? rss->version
+                                                  : 0,
+                                               pd->backend_url,
+                                               &pd->salt,
+                                               &policy_lookup_cb,
+                                               pd,
+                                               NULL,
+                                               NULL);
+      if (NULL != pd->recovery)
+        launched = true;
+    }
+    if (! launched)
+    {
+      GNUNET_break (0);
+      ANASTASIS_redux_fail_ (cb,
+                             cb_cls,
+                             TALER_EC_INVALID,
+                             "could not begin recovery operation");
+      free_rss (rss);
+      return NULL;
     }
   }
-  {
-    struct ANASTASIS_ReduxAction *ra;
-
-    ra = GNUNET_new (struct ANASTASIS_ReduxAction);
-    ra->cleanup_cls = rss;
-    ra->cleanup = free_enter_user_attributes;
-    return ra;
-  }
+  rss->ra.cleanup = &free_rss;
+  rss->ra.cleanup_cls = rss;
+  return &rss->ra;
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]