[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.
- [taler-anastasis] branch master updated: implement redux recovery initialization logic,
gnunet <=