summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/authorization/anastasis-authorization-sms.sh2
-rw-r--r--src/authorization/anastasis_authorization_plugin_sms.c2
-rw-r--r--src/authorization/libanastasiseufin/lae_credit.c2
-rw-r--r--src/backend/Makefile.am1
-rw-r--r--src/backend/anastasis-httpd_config.c113
-rw-r--r--src/include/anastasis.h1
-rw-r--r--src/lib/anastasis_recovery.c119
-rw-r--r--src/reducer/anastasis_api_backup_redux.c127
-rw-r--r--src/restclient/anastasis_api_config.c15
-rw-r--r--src/stasis/drop.sql10
10 files changed, 294 insertions, 98 deletions
diff --git a/src/authorization/anastasis-authorization-sms.sh b/src/authorization/anastasis-authorization-sms.sh
index 1e38661..c3b1055 100755
--- a/src/authorization/anastasis-authorization-sms.sh
+++ b/src/authorization/anastasis-authorization-sms.sh
@@ -20,8 +20,6 @@ STATUS=$(curl --request POST \
--data message_type=OTP \
--data "phone_number=$1" \
-w "%{http_code}" -s -o $TMPFILE)
-echo `cat $TMPFILE` >> /var/log/sms.log
-rm -f $TMPFILE
case $STATUS in
200|203|250|290|291|295)
exit 0;
diff --git a/src/authorization/anastasis_authorization_plugin_sms.c b/src/authorization/anastasis_authorization_plugin_sms.c
index 51457b6..695e5d8 100644
--- a/src/authorization/anastasis_authorization_plugin_sms.c
+++ b/src/authorization/anastasis_authorization_plugin_sms.c
@@ -375,7 +375,7 @@ sms_challenge (struct ANASTASIS_AUTHORIZATION_State *as,
GNUNET_assert (NULL != pipe_stdin);
GNUNET_DISK_pipe_close (p);
GNUNET_asprintf (&as->msg,
- "%s\nAnastasis\n: %s",
+ "%s\nAnastasis:\n%s",
ANASTASIS_pin2s (as->code),
ANASTASIS_CRYPTO_uuid2s (&as->truth_uuid));
{
diff --git a/src/authorization/libanastasiseufin/lae_credit.c b/src/authorization/libanastasiseufin/lae_credit.c
index d3fd781..dd6687b 100644
--- a/src/authorization/libanastasiseufin/lae_credit.c
+++ b/src/authorization/libanastasiseufin/lae_credit.c
@@ -82,7 +82,7 @@ parse_account_history (struct ANASTASIS_EUFIN_CreditHistoryHandle *hh,
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- for (unsigned int i = 0; i<json_array_size (history_array); i++)
+ for (size_t i = 0; i<json_array_size (history_array); i++)
{
struct ANASTASIS_EUFIN_CreditDetails td;
uint64_t row_id;
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 10edef5..c1b0931 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -37,7 +37,6 @@ anastasis_httpd_LDADD = \
-ltalerjson \
-ltalerutil \
-lgnunetcurl \
- -lgnunetrest \
-lgnunetjson \
-lgnunetutil \
-lmicrohttpd \
diff --git a/src/backend/anastasis-httpd_config.c b/src/backend/anastasis-httpd_config.c
index 677c5dc..315419e 100644
--- a/src/backend/anastasis-httpd_config.c
+++ b/src/backend/anastasis-httpd_config.c
@@ -1,6 +1,6 @@
/*
This file is part of Anastasis
- Copyright (C) 2020, 2021 Anastasis SARL
+ Copyright (C) 2020, 2021, 2024 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -78,48 +78,83 @@ MHD_RESULT
AH_handler_config (struct AH_RequestHandler *rh,
struct MHD_Connection *connection)
{
- json_t *method_arr = json_array ();
+ static struct MHD_Response *response;
+ static struct GNUNET_TIME_Absolute a;
- GNUNET_assert (NULL != method_arr);
+ if ( (GNUNET_TIME_absolute_is_past (a)) &&
+ (NULL != response) )
{
- json_t *method;
+ MHD_destroy_response (response);
+ response = NULL;
+ }
+ if (NULL == response)
+ {
+ json_t *method_arr = json_array ();
+ struct GNUNET_TIME_Timestamp km;
+ char dat[128];
+
+ GNUNET_assert (NULL != method_arr);
+ a = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_DAYS);
+ /* Round up to next full day to ensure the expiration
+ time does not become a fingerprint! */
+ a = GNUNET_TIME_absolute_round_down (a,
+ GNUNET_TIME_UNIT_DAYS);
+ a = GNUNET_TIME_absolute_add (a,
+ GNUNET_TIME_UNIT_DAYS);
+ /* => /config response stays at most 48h in caches! */
+ km = GNUNET_TIME_absolute_to_timestamp (a);
+ TALER_MHD_get_date_string (km.abs_time,
+ dat);
+ {
+ json_t *method;
+
+ method = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_string ("type",
+ "question"),
+ TALER_JSON_pack_amount ("cost",
+ &AH_question_cost));
+ GNUNET_assert (
+ 0 ==
+ json_array_append_new (method_arr,
+ method));
+ }
+ GNUNET_CONFIGURATION_iterate_sections (AH_cfg,
+ &add_methods,
+ method_arr);
- method = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("type",
- "question"),
- TALER_JSON_pack_amount ("cost",
- &AH_question_cost));
- GNUNET_assert (
- 0 ==
- json_array_append_new (method_arr,
- method));
+ response = TALER_MHD_MAKE_JSON_PACK (
+ GNUNET_JSON_pack_string ("name",
+ "anastasis"),
+ GNUNET_JSON_pack_string ("version",
+ "0:2:0"),
+ GNUNET_JSON_pack_string ("implementation",
+ "urn:net:taler:specs:anastasis:c-reference"),
+ GNUNET_JSON_pack_string ("business_name",
+ AH_business_name),
+ GNUNET_JSON_pack_array_steal ("methods",
+ method_arr),
+ GNUNET_JSON_pack_uint64 ("storage_limit_in_megabytes",
+ AH_upload_limit_mb),
+ TALER_JSON_pack_amount ("annual_fee",
+ &AH_annual_fee),
+ TALER_JSON_pack_amount ("truth_upload_fee",
+ &AH_truth_upload_fee),
+ TALER_JSON_pack_amount ("liability_limit",
+ &AH_insurance),
+ GNUNET_JSON_pack_data_auto ("provider_salt",
+ &AH_provider_salt));
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_EXPIRES,
+ dat));
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CACHE_CONTROL,
+ "public,max-age=21600")); /* 6h */
}
- GNUNET_CONFIGURATION_iterate_sections (AH_cfg,
- &add_methods,
- method_arr);
- return TALER_MHD_REPLY_JSON_PACK (
- connection,
- MHD_HTTP_OK,
- GNUNET_JSON_pack_string ("name",
- "anastasis"),
- GNUNET_JSON_pack_string ("version",
- "0:1:0"),
- GNUNET_JSON_pack_string ("implementation",
- "urn:net:taler:specs:anastasis:c-reference"),
- GNUNET_JSON_pack_string ("business_name",
- AH_business_name),
- GNUNET_JSON_pack_array_steal ("methods",
- method_arr),
- GNUNET_JSON_pack_uint64 ("storage_limit_in_megabytes",
- AH_upload_limit_mb),
- TALER_JSON_pack_amount ("annual_fee",
- &AH_annual_fee),
- TALER_JSON_pack_amount ("truth_upload_fee",
- &AH_truth_upload_fee),
- TALER_JSON_pack_amount ("liability_limit",
- &AH_insurance),
- GNUNET_JSON_pack_data_auto ("provider_salt",
- &AH_provider_salt));
+ return MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
}
diff --git a/src/include/anastasis.h b/src/include/anastasis.h
index fd1275c..ea49ee7 100644
--- a/src/include/anastasis.h
+++ b/src/include/anastasis.h
@@ -1071,7 +1071,6 @@ struct ANASTASIS_ShareResult
*/
enum ANASTASIS_UploadStatus ec;
-
} provider_failure;
} details;
diff --git a/src/lib/anastasis_recovery.c b/src/lib/anastasis_recovery.c
index f164c93..41f35a5 100644
--- a/src/lib/anastasis_recovery.c
+++ b/src/lib/anastasis_recovery.c
@@ -782,13 +782,11 @@ policy_lookup_cb (void *cls,
json_dumpf (recovery_document,
stderr,
0);
- json_decref (recovery_document);
r->csc (r->csc_cls,
ANASTASIS_RS_POLICY_MALFORMED_JSON,
NULL,
0);
- ANASTASIS_recovery_abort (r);
- return;
+ goto cleanup;
}
if (NULL != secret_name)
{
@@ -799,19 +797,37 @@ policy_lookup_cb (void *cls,
}
}
+ if ( (json_array_size (esc_methods) > UINT_MAX) ||
+ (json_array_size (dec_policies) > UINT_MAX) )
+ {
+ GNUNET_break_op (0);
+ r->csc (r->csc_cls,
+ ANASTASIS_RS_POLICY_DOWNLOAD_TOO_BIG,
+ NULL,
+ 0);
+ goto cleanup;
+ }
+
r->ri.version = dd->details.ok.version;
- r->ri.cs_len = json_array_size (esc_methods);
- r->ri.dps_len = json_array_size (dec_policies);
- r->ri.dps = GNUNET_new_array (r->ri.dps_len,
- struct ANASTASIS_DecryptionPolicy *);
- r->dps = GNUNET_new_array (r->ri.dps_len,
- struct DecryptionPolicy);
- r->solved_challenges = GNUNET_new_array (r->ri.cs_len,
- struct ANASTASIS_Challenge *);
- r->ri.cs = GNUNET_new_array (r->ri.cs_len,
- struct ANASTASIS_Challenge *);
- r->cs = GNUNET_new_array (r->ri.cs_len,
- struct ANASTASIS_Challenge);
+ r->ri.cs_len
+ = (unsigned int) json_array_size (esc_methods);
+ r->ri.dps_len
+ = (unsigned int) json_array_size (dec_policies);
+ r->ri.dps
+ = GNUNET_new_array (r->ri.dps_len,
+ struct ANASTASIS_DecryptionPolicy *);
+ r->dps
+ = GNUNET_new_array (r->ri.dps_len,
+ struct DecryptionPolicy);
+ r->solved_challenges
+ = GNUNET_new_array (r->ri.cs_len,
+ struct ANASTASIS_Challenge *);
+ r->ri.cs
+ = GNUNET_new_array (r->ri.cs_len,
+ struct ANASTASIS_Challenge *);
+ r->cs
+ = GNUNET_new_array (r->ri.cs_len,
+ struct ANASTASIS_Challenge);
for (unsigned int i = 0; i < r->ri.cs_len; i++)
{
struct ANASTASIS_Challenge *cs = &r->cs[i];
@@ -849,9 +865,7 @@ policy_lookup_cb (void *cls,
ANASTASIS_RS_POLICY_MALFORMED_JSON,
NULL,
0);
- ANASTASIS_recovery_abort (r);
- json_decref (recovery_document);
- return;
+ goto cleanup;
}
cs->url = GNUNET_strdup (url);
cs->type = GNUNET_strdup (escrow_type);
@@ -890,15 +904,23 @@ policy_lookup_cb (void *cls,
ANASTASIS_RS_POLICY_MALFORMED_JSON,
NULL,
0);
- ANASTASIS_recovery_abort (r);
- json_decref (recovery_document);
- return;
+ goto cleanup;
}
GNUNET_assert (NULL != dp->emk);
GNUNET_assert (dp->emk_size > 0);
- dp->pub_details.challenges_length = json_array_size (uuids);
+ if (json_array_size (uuids) > UINT_MAX)
+ {
+ GNUNET_break_op (0);
+ r->csc (r->csc_cls,
+ ANASTASIS_RS_POLICY_MALFORMED_JSON,
+ NULL,
+ 0);
+ goto cleanup;
+ }
+ dp->pub_details.challenges_length
+ = (unsigned int) json_array_size (uuids);
dp->pub_details.challenges
= GNUNET_new_array (dp->pub_details.challenges_length,
struct ANASTASIS_Challenge *);
@@ -921,9 +943,7 @@ policy_lookup_cb (void *cls,
ANASTASIS_RS_POLICY_MALFORMED_JSON,
NULL,
0);
- ANASTASIS_recovery_abort (r);
- json_decref (recovery_document);
- return;
+ goto cleanup;
}
for (unsigned int i = 0; i<r->ri.cs_len; i++)
{
@@ -942,15 +962,17 @@ policy_lookup_cb (void *cls,
ANASTASIS_RS_POLICY_MALFORMED_JSON,
NULL,
0);
- ANASTASIS_recovery_abort (r);
- json_decref (recovery_document);
- return;
+ goto cleanup;
}
}
}
r->pc (r->pc_cls,
&r->ri);
json_decref (recovery_document);
+ return;
+cleanup:
+ ANASTASIS_recovery_abort (r);
+ json_decref (recovery_document);
}
@@ -1126,16 +1148,23 @@ parse_cs_array (struct ANASTASIS_Recovery *r,
const json_t *cs_arr)
{
json_t *cs;
- unsigned int n_index;
+ size_t n_index;
if (! json_is_array (cs_arr))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- r->ri.cs_len = json_array_size (cs_arr);
- r->solved_challenges = GNUNET_new_array (r->ri.cs_len,
- struct ANASTASIS_Challenge *);
+ if (json_array_size (cs_arr) > UINT_MAX)
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ r->ri.cs_len
+ = (unsigned int) json_array_size (cs_arr);
+ r->solved_challenges
+ = GNUNET_new_array (r->ri.cs_len,
+ struct ANASTASIS_Challenge *);
r->ri.cs = GNUNET_new_array (r->ri.cs_len,
struct ANASTASIS_Challenge *);
r->cs = GNUNET_new_array (r->ri.cs_len,
@@ -1212,14 +1241,20 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
const json_t *dps_arr)
{
json_t *dps;
- unsigned int n_index;
+ size_t n_index;
if (! json_is_array (dps_arr))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- r->ri.dps_len = json_array_size (dps_arr);
+ if (json_array_size (dps_arr) > UINT_MAX)
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ r->ri.dps_len
+ = (unsigned int) json_array_size (dps_arr);
r->dps = GNUNET_new_array (r->ri.dps_len,
struct DecryptionPolicy);
r->ri.dps = GNUNET_new_array (r->ri.dps_len,
@@ -1259,14 +1294,20 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
}
GNUNET_assert (NULL != dp->emk);
GNUNET_assert (dp->emk_size > 0);
- dp->pub_details.challenges_length = json_array_size (challenges);
- dp->pub_details.challenges = GNUNET_new_array (
- dp->pub_details.challenges_length,
- struct ANASTASIS_Challenge *);
+ if (json_array_size (challenges) > UINT_MAX)
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ dp->pub_details.challenges_length
+ = (unsigned int) json_array_size (challenges);
+ dp->pub_details.challenges
+ = GNUNET_new_array (dp->pub_details.challenges_length,
+ struct ANASTASIS_Challenge *);
{
json_t *challenge;
- unsigned int c_index;
+ size_t c_index;
json_array_foreach (challenges, c_index, challenge)
{
struct ANASTASIS_CRYPTO_TruthUUIDP uuid;
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];
diff --git a/src/restclient/anastasis_api_config.c b/src/restclient/anastasis_api_config.c
index fff4774..aee0357 100644
--- a/src/restclient/anastasis_api_config.c
+++ b/src/restclient/anastasis_api_config.c
@@ -169,11 +169,18 @@ handle_config_finished (void *cls,
acfg.ec = TALER_EC_GENERIC_VERSION_MALFORMED;
break;
}
- acfg.details.ok.methods_length = json_array_size (methods);
+ acfg.details.ok.methods_length = (unsigned int) json_array_size (methods);
+ if (((size_t) acfg.details.ok.methods_length) !=
+ json_array_size (methods))
{
- struct ANASTASIS_AuthorizationMethodConfig mcfg[GNUNET_NZL (
- acfg.details.ok.
- methods_length)];
+ GNUNET_break_op (0);
+ acfg.http_status = 0;
+ acfg.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+ break;
+ }
+ {
+ struct ANASTASIS_AuthorizationMethodConfig mcfg[
+ GNUNET_NZL (acfg.details.ok.methods_length)];
for (unsigned int i = 0; i<acfg.details.ok.methods_length; i++)
{
diff --git a/src/stasis/drop.sql b/src/stasis/drop.sql
index 67aa4a1..357fa9d 100644
--- a/src/stasis/drop.sql
+++ b/src/stasis/drop.sql
@@ -17,8 +17,14 @@
-- Everything in one big transaction
BEGIN;
--- Unregister patch (0001.sql)
-SELECT _v.unregister_patch('stasis-0001');
+WITH xpatches AS (
+ SELECT patch_name
+ FROM _v.patches
+ WHERE starts_with(patch_name,'stasis-')
+)
+ SELECT _v.unregister_patch(xpatches.patch_name)
+ FROM xpatches;
+
DROP SCHEMA anastasis CASCADE;
-- And we're out of here...