diff options
Diffstat (limited to 'src/reducer')
-rw-r--r-- | src/reducer/anastasis_api_backup_redux.c | 127 |
1 files changed, 119 insertions, 8 deletions
diff --git a/src/reducer/anastasis_api_backup_redux.c b/src/reducer/anastasis_api_backup_redux.c index 13b1dd6..6ca6de7 100644 --- a/src/reducer/anastasis_api_backup_redux.c +++ b/src/reducer/anastasis_api_backup_redux.c @@ -32,7 +32,7 @@ * anastasis-httpd.h. */ #define ANASTASIS_FREE_STORAGE GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_YEARS, 5) + GNUNET_TIME_UNIT_YEARS, 5) /** * CPU limiter: do not evaluate more than 16k @@ -1665,7 +1665,8 @@ done_authentication (json_t *state, pb.methods = json_object_get (state, "authentication_methods"); if ( (NULL == pb.methods) || - (! json_is_array (pb.methods)) ) + (! json_is_array (pb.methods)) || + (json_array_size (pb.methods) > UINT_MAX) ) { ANASTASIS_redux_fail_ (cb, cb_cls, @@ -1673,7 +1674,8 @@ done_authentication (json_t *state, "'authentication_methods' must be provided"); return NULL; } - pb.num_methods = json_array_size (pb.methods); + pb.num_methods + = (unsigned int) json_array_size (pb.methods); switch (pb.num_methods) { case 0: @@ -2953,6 +2955,62 @@ serialize_truth (struct UploadContext *uc) /** + * Test if the given @a provider_url is used by any of the + * authentication methods and thus the provider should be + * considered mandatory for storing the policy. + * + * @param state state to inspect + * @param provider_url provider to test + * @return false if the provider can be removed from policy + * upload considerations without causing a problem + */ +static bool +provider_required (const json_t *state, + const char *provider_url) +{ + json_t *policies + = json_object_get (state, + "policies"); + size_t pidx; + json_t *policy; + + json_array_foreach (policies, pidx, policy) + { + json_t *methods = json_object_get (policy, + "methods"); + size_t midx; + json_t *method; + + json_array_foreach (methods, midx, method) + { + const char *provider + = json_string_value (json_object_get (method, + "provider")); + + if (NULL == provider) + { + GNUNET_break (0); + continue; + } + if (0 == strcmp (provider, + provider_url)) + return true; + } + } + return false; +} + + +/** + * All truth uploads are done, begin with uploading the policy. + * + * @param[in,out] uc context for the operation + */ +static void +share_secret (struct UploadContext *uc); + + +/** * Function called with the results of a #ANASTASIS_secret_share(). * * @param cls closure with a `struct UploadContext *` @@ -3036,7 +3094,8 @@ secret_share_result_cb (void *cls, json_array_foreach (providers, off, provider) { const char *purl = json_string_value (json_object_get (provider, - "provider_url")); + "provider_url") + ); if (NULL == purl) { @@ -3077,6 +3136,45 @@ secret_share_result_cb (void *cls, { json_t *details; + if (! provider_required (uc->state, + sr->details.provider_failure.provider_url)) + { + /* try again without that provider */ + json_t *provider; + json_t *providers; + size_t idx; + + provider + = json_object_get ( + json_object_get (uc->state, + "authentication_providers"), + sr->details.provider_failure.provider_url); + GNUNET_break (0 == + json_object_set_new (provider, + "status", + json_string ("disabled"))); + providers + = json_object_get (uc->state, + "policy_providers"); + json_array_foreach (providers, idx, provider) + { + const char *url + = json_string_value (json_object_get (provider, + "provider_url")); + + if ( (NULL != url) && + (0 == strcmp (sr->details.provider_failure.provider_url, + url)) ) + { + GNUNET_break (0 == + json_array_remove (providers, + idx)); + break; + } + } + share_secret (uc); + return; + } details = GNUNET_JSON_PACK ( GNUNET_JSON_pack_uint64 ("http_status", sr->details.provider_failure.http_status), @@ -3194,7 +3292,18 @@ share_secret (struct UploadContext *uc) return; } - pds_len = json_array_size (providers); + if (json_array_size (providers) > UINT_MAX) + { + GNUNET_break_op (0); + ANASTASIS_redux_fail_ (uc->cb, + uc->cb_cls, + TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, + "provider array excessively long"); + upload_cancel_cb (uc); + return; + } + pds_len + = (unsigned int) json_array_size (providers); if (0 == pds_len) { ANASTASIS_redux_fail_ (uc->cb, @@ -3223,17 +3332,19 @@ share_secret (struct UploadContext *uc) unsigned int methods_len; if ( (! json_is_array (jmethods)) || - (0 == json_array_size (jmethods)) ) + (0 == json_array_size (jmethods)) || + (json_array_size (jmethods) > UINT_MAX) ) { GNUNET_break (0); ANASTASIS_redux_fail_ (uc->cb, uc->cb_cls, TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, - "'methods' must be an array"); + "'methods' must be an array of sane length"); upload_cancel_cb (uc); return; } - methods_len = json_array_size (jmethods); + methods_len + = (unsigned int) json_array_size (jmethods); { struct ANASTASIS_Policy *p; struct ANASTASIS_Truth *truths[methods_len]; |