From 697ea51cbbe8a32b8484630433c51a5c5ddb595a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 30 Jan 2022 13:55:51 +0100 Subject: -more work towards nicer policy discovery logic --- src/include/anastasis_redux.h | 31 ++++++++++- src/reducer/anastasis_api_backup_redux.c | 30 +++++----- src/reducer/anastasis_api_discovery.c | 88 +++++++++++++++++++++--------- src/reducer/anastasis_api_recovery_redux.c | 83 +++++++++++++++++++++++++++- src/reducer/anastasis_api_redux.c | 6 +- src/reducer/anastasis_api_redux.h | 6 +- 6 files changed, 192 insertions(+), 52 deletions(-) diff --git a/src/include/anastasis_redux.h b/src/include/anastasis_redux.h index fc7bd56..a62b89e 100644 --- a/src/include/anastasis_redux.h +++ b/src/include/anastasis_redux.h @@ -118,9 +118,7 @@ struct ANASTASIS_PolicyDiscovery; /** - * Function called on each discovered recovery policy. Called - * with all arguments NULL if we have received all policies that - * we could possibly receive for the current operation. + * Function called on each discovered recovery policy. * * The client can then start a new policy discovery process, using the * smallest (also most recent) @a version received per @a provider_url @@ -167,6 +165,20 @@ ANASTASIS_policy_discovery_start (const json_t *state, ANASTASIS_PolicyDiscoveryCallback cb, void *cb_cls); + +/** + * Add another provider to the list of providers to do discovery + * on. + * + * @param[in,out] pd policy discovery to expand + * @param provider_url the provider to add to the set of providers + * @param provider_state configuration state for that provider + */ +void +ANASTASIS_policy_discovery_more (struct ANASTASIS_PolicyDiscovery *pd, + const char *provider_url, + json_t *provider_state); + /** * Stop policy discovery. * @@ -190,5 +202,18 @@ ANASTASIS_mask_id_data (const json_t *state, const json_t *master_id, json_int_t mask); +/** + * Lookup @a salt of @a provider_url in @a state. + * + * @param state the state to inspect + * @param provider_url provider to look into + * @param[out] salt value to extract + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +ANASTASIS_reducer_lookup_salt (const json_t *state, + const char *provider_url, + struct ANASTASIS_CRYPTO_ProviderSaltP *salt); + #endif /* _ANASTASIS_REDUX_H */ diff --git a/src/reducer/anastasis_api_backup_redux.c b/src/reducer/anastasis_api_backup_redux.c index fb30cbc..a2e22cc 100644 --- a/src/reducer/anastasis_api_backup_redux.c +++ b/src/reducer/anastasis_api_backup_redux.c @@ -1743,9 +1743,9 @@ done_authentication (json_t *state, struct ANASTASIS_CRYPTO_ProviderSaltP salt; if (GNUNET_OK != - ANASTASIS_reducer_lookup_salt_ (state, - url, - &salt)) + ANASTASIS_reducer_lookup_salt (state, + url, + &salt)) continue; /* skip providers that are down */ provider = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("provider_url", @@ -1772,9 +1772,9 @@ done_authentication (json_t *state, url_str = json_string_value (url); if ( (NULL == url_str) || (GNUNET_OK != - ANASTASIS_reducer_lookup_salt_ (state, - url_str, - &salt)) ) + ANASTASIS_reducer_lookup_salt (state, + url_str, + &salt)) ) { GNUNET_break (0); ANASTASIS_redux_fail_ (cb, @@ -3374,9 +3374,9 @@ share_secret (struct UploadContext *uc) ispec, NULL, NULL)) || (GNUNET_OK != - ANASTASIS_reducer_lookup_salt_ (uc->state, - pds[i].provider_url, - &pds[i].provider_salt)) ) + ANASTASIS_reducer_lookup_salt (uc->state, + pds[i].provider_url, + &pds[i].provider_salt)) ) { GNUNET_break (0); ANASTASIS_redux_fail_ (uc->cb, @@ -3659,9 +3659,9 @@ add_truth_object (struct UploadContext *uc, }; if (GNUNET_OK != - ANASTASIS_reducer_lookup_salt_ (uc->state, - provider_url, - &salt)) + ANASTASIS_reducer_lookup_salt (uc->state, + provider_url, + &salt)) { GNUNET_break (0); return GNUNET_SYSERR; @@ -3828,9 +3828,9 @@ check_truth_upload (struct UploadContext *uc, tue->am_idx = am_idx; tue->policies_length = 1; if (GNUNET_OK != - ANASTASIS_reducer_lookup_salt_ (uc->state, - provider_url, - &provider_salt)) + ANASTASIS_reducer_lookup_salt (uc->state, + provider_url, + &provider_salt)) { GNUNET_break (0); GNUNET_JSON_parse_free (spec); diff --git a/src/reducer/anastasis_api_discovery.c b/src/reducer/anastasis_api_discovery.c index 0ac7c92..727f00b 100644 --- a/src/reducer/anastasis_api_discovery.c +++ b/src/reducer/anastasis_api_discovery.c @@ -95,6 +95,16 @@ struct ANASTASIS_PolicyDiscovery * have already seen to the value "dummy". */ struct GNUNET_CONTAINER_MultiHashMap *dd_map; + + /** + * State we are operating on. + */ + json_t *state; + + /** + * Number of optional fields in our identity attributes. + */ + json_int_t opt_cnt; }; @@ -129,18 +139,6 @@ meta_cb (void *cls, po); GNUNET_free (po->provider_url); GNUNET_free (po); - if (NULL == pd->po_head) - { - pd->cb (pd->cb_cls, - NULL, - NULL, - 0, - 0, - GNUNET_TIME_UNIT_ZERO_TS, - NULL); - ANASTASIS_policy_discovery_stop (pd); - return; - } return; } if (GNUNET_YES == @@ -172,7 +170,6 @@ meta_cb (void *cls, * @param id_data our identity data, derived using @a mask * @param mask the mask describing which optional attributes were removed * @param provider_url which provider to query - * @param state state machine state * @param cursor cursor telling us from where to query */ static void @@ -180,9 +177,9 @@ start_po (struct ANASTASIS_PolicyDiscovery *pd, const json_t *id_data, json_int_t mask, const char *provider_url, - const json_t *state, const json_t *cursor) { + const json_t *state = pd->state; struct ProviderOperation *po; uint32_t max_version = UINT32_MAX; struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt; @@ -214,6 +211,9 @@ start_po (struct ANASTASIS_PolicyDiscovery *pd, { /* cursor invalid */ GNUNET_break (0); + json_dumpf (obj, + stderr, + JSON_INDENT (2)); return; } if ( (cmask == mask) && @@ -227,11 +227,13 @@ start_po (struct ANASTASIS_PolicyDiscovery *pd, } if (GNUNET_OK != - ANASTASIS_reducer_lookup_salt_ (state, - provider_url, - &provider_salt)) + ANASTASIS_reducer_lookup_salt (state, + provider_url, + &provider_salt)) { - GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "No /config for `%s', skipping provider\n", + provider_url); return; } po = GNUNET_new (struct ProviderOperation); @@ -295,7 +297,7 @@ ANASTASIS_policy_discovery_start (const json_t *state, (! json_is_array (required_attributes)) ) { GNUNET_break (0); - json_dumpf (state, + json_dumpf (required_attributes, stderr, JSON_INDENT (2)); return NULL; @@ -327,6 +329,9 @@ ANASTASIS_policy_discovery_start (const json_t *state, NULL, NULL)) { GNUNET_break (0); + json_dumpf (required_attribute, + stderr, + JSON_INDENT (2)); return NULL; } present = (NULL != @@ -335,6 +340,9 @@ ANASTASIS_policy_discovery_start (const json_t *state, if ((! present) && (! optional)) { GNUNET_break (0); + json_dumpf (master_id, + stderr, + JSON_INDENT (2)); return NULL; } if (present && optional) @@ -347,6 +355,8 @@ ANASTASIS_policy_discovery_start (const json_t *state, GNUNET_NO); pd->cb = cb; pd->cb_cls = cb_cls; + pd->opt_cnt = opt_cnt; + pd->state = json_deep_copy (state); /* Compute 'id_data' for all possible masks, and then start downloads at all providers for 'id_data' */ @@ -364,18 +374,45 @@ ANASTASIS_policy_discovery_start (const json_t *state, id_data, mask, url, - state, cursor); } json_decref (id_data); } - if (NULL == pd->po_head) + return pd; +} + + +void +ANASTASIS_policy_discovery_more (struct ANASTASIS_PolicyDiscovery *pd, + const char *provider_url, + json_t *provider_state) +{ + json_t *master_id = json_object_get (pd->state, + "identity_attributes"); + json_t *providers = json_object_get (pd->state, + "authentication_providers"); + + GNUNET_assert (NULL != master_id); + GNUNET_assert (NULL != providers); + GNUNET_assert (0 == + json_object_set (providers, + provider_url, + provider_state)); + /* Compute 'id_data' for all possible masks, and then + start downloads at provider for 'id_data' */ + for (json_int_t mask = 0; mask < (1LL << pd->opt_cnt); mask++) { - GNUNET_break (0); - ANASTASIS_policy_discovery_stop (pd); - return NULL; + json_t *id_data = ANASTASIS_mask_id_data (pd->state, + master_id, + mask); + + start_po (pd, + id_data, + mask, + provider_url, + NULL); + json_decref (id_data); } - return pd; } @@ -394,6 +431,7 @@ ANASTASIS_policy_discovery_stop (struct ANASTASIS_PolicyDiscovery *pd) GNUNET_free (po); } GNUNET_CONTAINER_multihashmap_destroy (pd->dd_map); + json_decref (pd->state); GNUNET_free (pd); } diff --git a/src/reducer/anastasis_api_recovery_redux.c b/src/reducer/anastasis_api_recovery_redux.c index 5f087f3..2be963f 100644 --- a/src/reducer/anastasis_api_recovery_redux.c +++ b/src/reducer/anastasis_api_recovery_redux.c @@ -2076,9 +2076,9 @@ sync_providers (json_t *state, return NULL; } if (GNUNET_OK == - ANASTASIS_reducer_lookup_salt_ (state, - provider_url, - &salt)) + ANASTASIS_reducer_lookup_salt (state, + provider_url, + &salt)) continue; /* provider already ready */ se = GNUNET_new (struct SyncEntry); se->ms = ms; @@ -2107,6 +2107,78 @@ sync_providers (json_t *state, } +/** + * Try to obtain configuration information on all configured + * providers. Upon success, call @a cb with the updated provider + * status data. + * + * @param[in] state we are in + * @param arguments our arguments with the solution + * @param cb functiont o call with the new state + * @param cb_cls closure for @a cb + * @return handle to cancel challenge selection step + */ +static struct ANASTASIS_ReduxAction * +poll_providers (json_t *state, + const json_t *arguments, + ANASTASIS_ActionCallback cb, + void *cb_cls) +{ + json_t *ap; + const char *url; + json_t *obj; + struct MasterSync *ms; + + ap = json_object_get (state, + "authentication_providers"); + if (NULL == ap) + { + GNUNET_break (0); + ANASTASIS_redux_fail_ (cb, + cb_cls, + TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, + "'authentication_providers' missing"); + return NULL; + } + ms = GNUNET_new (struct MasterSync); + ms->cb = cb; + ms->cb_cls = cb_cls; + json_object_foreach (ap, url, obj) + { + struct ANASTASIS_CRYPTO_ProviderSaltP salt; + struct SyncEntry *se; + + if (GNUNET_OK == + ANASTASIS_reducer_lookup_salt (state, + url, + &salt)) + continue; + se = GNUNET_new (struct SyncEntry); + se->ms = ms; + GNUNET_CONTAINER_DLL_insert (ms->se_head, + ms->se_tail, + se); + se->ra = ANASTASIS_REDUX_add_provider_to_state_ (url, + state, + &sync_progress, + se); + } + if (NULL == ms->se_head) + { + /* everything already synced */ + clean_sync (ms); + ANASTASIS_redux_fail_ (cb, + cb_cls, + TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID, + "already in sync"); + return NULL; + } + ms->ra.cleanup = &clean_sync; + ms->ra.cleanup_cls = ms; + return &ms->ra; +} + + /** * The user pressed "back" during challenge solving. * Transition back to selecting another challenge. @@ -2592,6 +2664,11 @@ ANASTASIS_recovery_action_ (json_t *state, "add_provider", &add_provider }, + { + ANASTASIS_RECOVERY_STATE_SECRET_SELECTING, + "poll_providers", + &poll_providers + }, { ANASTASIS_RECOVERY_STATE_SECRET_SELECTING, "next", diff --git a/src/reducer/anastasis_api_redux.c b/src/reducer/anastasis_api_redux.c index a83b86b..d1d4b77 100644 --- a/src/reducer/anastasis_api_redux.c +++ b/src/reducer/anastasis_api_redux.c @@ -2015,9 +2015,9 @@ ANASTASIS_REDUX_load_continents_ () * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue -ANASTASIS_reducer_lookup_salt_ (const json_t *state, - const char *provider_url, - struct ANASTASIS_CRYPTO_ProviderSaltP *salt) +ANASTASIS_reducer_lookup_salt (const json_t *state, + const char *provider_url, + struct ANASTASIS_CRYPTO_ProviderSaltP *salt) { const json_t *aps; const json_t *cfg; diff --git a/src/reducer/anastasis_api_redux.h b/src/reducer/anastasis_api_redux.h index 81fbeed..cc59713 100644 --- a/src/reducer/anastasis_api_redux.h +++ b/src/reducer/anastasis_api_redux.h @@ -176,9 +176,9 @@ ANASTASIS_recovery_state_to_string_ (enum ANASTASIS_RecoveryState rs); * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue -ANASTASIS_reducer_lookup_salt_ (const json_t *state, - const char *provider_url, - struct ANASTASIS_CRYPTO_ProviderSaltP *salt); +ANASTASIS_reducer_lookup_salt (const json_t *state, + const char *provider_url, + struct ANASTASIS_CRYPTO_ProviderSaltP *salt); /** -- cgit v1.2.3